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

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

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退出后,点击通知:
这里写图片描述

点击这里下载源码

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值