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退出后,点击通知:
点击这里下载源码
相关文章推荐
- 【Android】信鸽推送通知栏点击之重复打开APP&重复从Laucher主入口启动问题
- 关于android推送服务-点击通知栏回不到当前应用程序的问题研究
- Android 关于极光推送退出APP时清空通知的问题
- 【Android开发那点破事】消息推送BroadcastReceiver,点击通知打开两次Activity问题
- Android 使用友盟分享SDK,分享到QQ成功后,遇到app被销毁后,回到此分享界面无法正常点击界面问题。--连QQ都忘记处理的activity状态恢复问题
- 编写Android app更新模块遇到的问题分析与总结
- 关于android popupwindow 点击窗外不能关闭问题
- Android项目使用appcompat_v7时遇到的问题
- Android Stock Browser Web App开发当中遇到的问题(持续更新)
- java的初始化研究:android开发中遇到的一个奇怪问题
- 2014-10-22遇到的问题----Android创建第一个项目出现appcompat_v7工程的解决办法
- Android Alert Dialog解决点击按钮对话框不关闭/的问题
- 【边做项目边学Android】小白会遇到的问题--Appcompat_V7问题
- spooler SubSystem App 遇到问题需要关闭
- Android通知栏点击无法启动Activity的问题
- Android各种类型Dialog点击空白处自动关闭问题
- 点击推送通知时APP方法调用的几种情况
- 举例说明关于android编程中遇到的java.lang.ClassCastException: android.app.Application问题的原因及解决办法
- android应用程序遇到程序关闭后重启的问题
- ios app推送通知详细教程 四 实战问题解决