您的位置:首页 > 移动开发

Android推送遇到的问题--app关闭后,点击通知后点击通知后app未初始化的问题

2017-05-17 19:30 495 查看

最近接了激光推送,完成后测试这边提出了这么一个问题:

app退出后,通知还在通知栏,这个时候点击通知后,手机会从桌面跳转到对应的订单页面,接着app直接闪退.

原因分析:

因为app中跳转掉订单页面,获取订单信息需要用户信息,但是这个时候App是直接进入订单页面的,没有经过欢迎页面的初始化,因此是拿不到用户信息的,自然会闪退掉!

解决方案:

1. 在app退出的时候制造一个假象,只是跳转到桌面,并没有真正的关闭.

解释下:很多app做的都是双击两次返回键退出,但是我们可以做一个假象,就是直接跳转到桌面,像京东.淘宝就是这样做的.你会发现你进入桌面后,再次进入淘宝或者京东的时候,并没有进入启动页,而是直接进入了主页



@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
long secondTime = System.currentTimeMillis();
if (secondTime - firstTime > 800) {// 如果两次按键时间间隔大于800毫秒,则不退出
CustomToast.createToast().showToast(MainActivity.this,
"再按一次  退出程序");
firstTime = secondTime;// 更新firstTime
return true;
} else {
//                    BaseApplication.getInstance().exit();//真正的退出
moveTaskToBack(false);
}
}
}
return super.dispatchKeyEvent(event);
}


说明:这种方法有治标不治本,如果从任务栏直接把app退出或者红米等一些低配的机器虽然你自己没有直接关闭,但是稍微打开几个app,我的app就可能被回收了,这个时候我们再点击通知进入app,仍然会因为缺少用户信息闪退的.

2.设置两个广播接受者,一个用来接收推送和展示推送,另一个用来处理通知点击后的操作

a.极光推送和个推都是通过BroadcastReceiver来接收推送的,那么我们在这个类中设置显示通知,点击通知后的延时意图设置为发一个广播而不是一个开启一个页面.在另外一个BroadcastReceiver中,接收到广播后进行一些判断,打开页面.

b.判断:首先我们判断这个app整个进程是不是还存活着,

如果存活,我们就直接打开我们要打开的订单页面,并且通过Intent将相关的数据传递过去

如果不存活,那就先打开启动页(WelcomeActivity),并将相关的数据通过Intent传递过去,进入启动页再将主界面(MainActivity)后,再进入订单页面

下边贴出代码(我们发一条广播代替推送):

1.NotificationShowReceiver

/**
* 接收和展示推送
* Created by Haipeng on 2017/5/11.
*/
public class NotificationShowReceiver extends BroadcastReceiver {
private static final String TAG = "NotShowReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "ShowNotificationReceiver onReceive");

String message = intent.getStringExtra("message");
Log.e(TAG, "[JPushReceiver] onReceive - " + intent.getAction() + ", extras: " + message);

showNotification(context, message);
}
private String id;
private Notification myNotify;
private NotificationManager manager;

//    send msg to MainActivity
private void showNotification(Context context, String message) {

//         message = "{\"type\":\"Test\",\"title\":\"测试\",\"content\":\"您有新的订单,点击查看\",\"id\":\"888888\",\"url\":\"\"}";

//设置点击通知栏的动作为启动另外一个广播
Intent broadcastIntent = new Intent(context, NotificationClickReceiver.class);
broadcastIntent.putExtra("message",message);
broadcastIntent.setAction("com.jike.testpushnotification.push.notificationclickreceiver");
PendingIntent pendingIntent = PendingIntent.
getBroadcast(context, 0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);

if (!TextUtils.isEmpty(message)) {
Log.e(TAG, message);
PushData pushData = new Gson().fromJson(message, PushData.class);
id = pushData.getId();
manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
myNotify = new Notification();
myNotify.icon = R.mipmap.ic_launcher;
myNotify.tickerText = pushData.getContent();
myNotify.when = System.currentTimeMillis();
myNotify.defaults = Notification.DEFAULT_SOUND;
myNotify.defaults |= Notification.DEFAULT_VIBRATE;
//myNotify.flags = Notification.FLAG_NO_CLEAR;// 不能够自动清除
myNotify.flags = Notification.FLAG_AUTO_CANCEL;
RemoteViews rv = new RemoteViews(context.getPackageName(),
R.layout.my_notification);
rv.setTextViewText(R.id.text_content, pushData.getContent());
rv.setTextViewText(R.id.text_content1, pushData.getTitle());
myNotify.contentView = rv;
myNotify.contentIntent = pendingIntent;
manager.notify(10123, myNotify);
}}
}


2.NotificationClickReceiver

/**
* 接收点击通知的事件和设置点击后做什么事情
* Created by Haipeng on 2017/5/11.
*/
public class NotificationClickReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra("message");

//判断app进程是否存活
if (SystemUtil.isAppAlive(context, "com.jike.testpushnotification")) {
//如果存活的话,就直接启动DetailActivity,但要考虑一种情况,就是app的进程虽然仍然在
//但Task栈已经空了,比如用户点击Back键退出应用,但进程还没有被系统回收,如果直接启动
//DetailActivity,再按Back键就不会返回MainActivity了。所以在启动
//DetailActivity前,要先启动MainActivity。
Log.i("NotClickReceiver", "the app process is alive");

Intent desIntnet = new Intent(context, OrderActivity.class);

if (!TextUtils.isEmpty(message)) {
desIntnet.putExtra("message", message);
}
desIntnet.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (SystemUtil.isActivityRunning(context, MainActivity.class)) {
context.startActivity(desIntnet);
} else {
Intent mainIntent = new Intent(context, MainActivity.class);
//将MainAtivity的launchMode设置成SingleTask, 或者在下面flag中加上Intent.FLAG_CLEAR_TOP,
//如果Task栈中有MainActivity的实例,就会把它移到栈顶,把在它之上的Activity都清理出栈,
//如果Task栈不存在MainActivity实例,则在栈顶创建
mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Intent[] intents = {mainIntent, desIntnet};

context.startActivities(intents);
}

} else {
//如果app进程已经被杀死,先重新启动app,将DetailActivity的启动参数传入Intent中,参数经过
//SplashActivity传入MainActivity,此时app的初始化已经完成,在MainActivity中就可以根据传入             //参数跳转到DetailActivity中去了
Log.i("NotClickReceiver", "the app process is dead");
Intent launchIntent = context.getPackageManager().
getLaunchIntentForPackage("com.jike.testpushnotification");
launchIntent.setFlags(
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
launchIntent.putExtra("message", message);

//            NotificationClickReceiver.
//            launchIntent.putExtra(Constants.EXTRA_BUNDLE, args);
context.startActivity(launchIntent);
}
}
}


3.WelcomeActivity

/**
* desc:启动页
* Edited by Haipeng.
*/
public class WelcomeActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);

new Thread(new Runnable() {
@Override
public void run() {
SystemClock.sleep(2000);
goMainPage();
}
}).start();
}

private void goMainPage() {
BaseApplication.isLogin=true;
String message = getIntent().getStringExtra("message");
Intent intent = new Intent(this, MainActivity.class);
if (!TextUtils.isEmpty(message)) {//将相关数据传过去
intent.putExtra("message", message);
}
startActivity(intent);
finish();
}
}


2.MainActivity

/**
* desc: 主界面  我们发一条广播代替推送
* Edited by Haipeng.
*/
public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}

private void init() {
String message = getIntent().getStringExtra("message");
if (!TextUtils.isEmpty(message)) {
Intent intent = new Intent(this, OrderActivity.class);
intent.putExtra("message", message);
startActivity(intent);
}
findViewById(R.id.bt_push).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent();
intent.setAction("com.jike.testpushnotification.push.notificationshowreceiver");
String message = "{\"type\":\"Test\",\"title\":\"测试\",\"content\":\"您有新的订单,点击查看\",\"id\":\"888888\",\"url\":\"\"}";
intent.putExtra("message",message);
sendBroadcast(intent);
}
});
}
}


3.OrderActivity

/**
* 测试订单页面   如果没有登录进入这个页面就会抛出一个异常
*/
public class OrderActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_order);
if (!BaseApplication.isLogin){
throw new IllegalStateException("未登录");
}
TextView tv_push_data= (TextView) findViewById(R.id.tv_push_data);
String message = getIntent().getStringExtra("message");
if (!TextUtils.isEmpty(message)) {
tv_push_data.setText(message);
}
}
}


看下效果图:

首先是app没有退出的时候:



接着是app退出后,点击通知:



点击这里下载源码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐