Android 关于Notification 点击启动流程分析

来源:互联网 发布:数控火焰切割手动编程 编辑:程序博客网 时间:2024/06/04 19:56

最近在项目中做了一个关于推送消息,点击进入指定页面的一个功能,相信大家都遇到过这种情形。

比如在集成(极光/友盟/小米/华为)推送的时候,当收到消息的时候如何处理点击逻辑呢?看图:

这里写图片描述

上面是我简单画的一个分析流程以及注意事项,以后留用。

根据是否登录来做判断,为什么不根据进程是否存活来判断呢?因为在网上,很多都是根据进程是否alive来判断应用是否退出,但是进程死了,又如何能接收推送消息呢?因为接收推送消息需要一个常驻service。

所以我在项目中用是否登录来判断应用是否退出。

情况1:当应用没有退出时。

应当设置MainActivity启动模式为SingleTask,当MainActivity在堆栈中时,移除所有它上面的,将MainActivity至于栈顶,当Activity没启动,则在栈顶创建。 如此是为了保证MainActivity的唯一性。防止回退紊乱。在onNewIntent()方法中执行接收数据传递的方法。还需要执行setIntent(intent)方法来防止数据不会被刷新。

情况2:当应用退出时,

则应启动应用,在闪屏界面,登录界面,主界面一次传值。在onCreate()方法中去执行接收数据传递的方法。

onNewIntent的使用:

onNewIntent()使用场景,是当多次启动一个Activity时,只想保留一个Activity实例,需要用到onNewIntent()方法。故而只有SingleTask和SingleTop模式下,才可以用onNewIntent();第一次启动Activity时会走onCreate()->onStart()->onResume();并不会走onNewIntent(),多次启动同一Activity,会走onNewIntent()->onRestart()->onStart()->onResume().

当调用到onNewIntent(intent)的时候,需要在onNewIntent() 中使用setIntent(intent),否则,后续的getIntent()都是之前的Intent。赋值并不会被刷新。

以项目集成极光推送为例。

需要一个常驻service来接收推送的消息。

  <!-- Required SDK 核心功能-->        <!-- 可配置android:process参数将PushService放在其他进程中 -->        <service            android:name="cn.jpush.android.service.PushService"            android:enabled="true"            android:exported="false">            <intent-filter>                <action android:name="cn.jpush.android.intent.REGISTER" />                <action android:name="cn.jpush.android.intent.REPORT" />                <action android:name="cn.jpush.android.intent.PushService" />                <action android:name="cn.jpush.android.intent.PUSH_TIME" />            </intent-filter>        </service>

需要一个Receiver来处理接收到的消息

        <!-- Required SDK核心功能-->        <receiver            android:name="cn.jpush.android.service.PushReceiver"            android:enabled="true">            <intent-filter android:priority="1000">                <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" />                <category android:name="com.aixuetang.future" />            </intent-filter>            <intent-filter>                <action android:name="android.intent.action.USER_PRESENT" />                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />            </intent-filter>            <!-- Optional -->            <intent-filter>                <action android:name="android.intent.action.PACKAGE_ADDED" />                <action android:name="android.intent.action.PACKAGE_REMOVED" />                <data android:scheme="package" />            </intent-filter>        </receiver>
public class MyReceiver extends BroadcastReceiver {    private static final String TAG = "MyReceiver";    private NotificationManager nm;    @Override    public void onReceive(Context context, Intent intent) {        if (null == nm) {            nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);        }        Bundle bundle = intent.getExtras();        Logger.d(TAG, "onReceive - " + intent.getAction() + ", extras: " + AndroidUtil.printBundle(bundle));        if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {            Logger.d(TAG, "JPush用户注册成功");        } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {            Logger.d(TAG, "接受到推送下来的自定义消息");        } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {            Logger.d(TAG, "接受到推送下来的通知");            receivingNotification(context,bundle);        } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {            Logger.d(TAG, "用户点击打开了通知");           openNotification(context,bundle);        } else {            Logger.d(TAG, "Unhandled intent - " + intent.getAction());        }    }   private void receivingNotification(Context context, Bundle bundle){        String title = bundle.getString(JPushInterface.EXTRA_NOTIFICATION_TITLE);        Logger.d(TAG, " title : " + title);        String message = bundle.getString(JPushInterface.EXTRA_ALERT);        Logger.d(TAG, "message : " + message);        String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);        Logger.d(TAG, "extras : " + extras);    }   private void openNotification(Context context, Bundle bundle){        String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);        String myValue = "";        try {            JSONObject extrasJson = new JSONObject(extras);            myValue = extrasJson.optString("myKey");        } catch (Exception e) {            Logger.w(TAG, "Unexpected: extras is not a valid json", e);            return;        }        if (TYPE_THIS.equals(myValue)) {            Intent mIntent = new Intent(context, ThisActivity.class);            mIntent.putExtras(bundle);            mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);            context.startActivity(mIntent);        } else if (TYPE_ANOTHER.equals(myValue)){            Intent mIntent = new Intent(context, AnotherActivity.class);            mIntent.putExtras(bundle);            mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);            context.startActivity(mIntent);        }    }}

这里你可以启用自己的Notification,并处理点击事件

 public void notify(PushCommandModel model,String message, Intent intent) {        String title=model.data.title;        String text=model.data.msg;        if(intent == null) {            intent = new Intent(StuApplication.getsAppContext(), MessageReceiver.class);            intent.putExtra("MSG_TYPE",message);        }        PendingIntent pendingIntent = PendingIntent.getBroadcast(StuApplication.getsAppContext(), 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);        Notification notification = new NotificationCompat.Builder(StuApplication.getsAppContext())                .setContentTitle(title)                .setContentText(text)                .setSmallIcon(R.mipmap.ic_launcher)                .setContentIntent(pendingIntent)                .build();        notification.flags |= Notification.FLAG_AUTO_CANCEL;        notification.defaults |= Notification.DEFAULT_SOUND;        mNotificationManager.notify(sNotificationId++, notification);        LogUtils.e("sNotificationId---->"+sNotificationId);    }

处理点击用getBroadcast(),在MessageReceiver接收并处理,不处理点击用getActivity()。notify的id保证唯一,可以用当前系统时间。

在MessageReceiver中处理消息。

/** * Created by Administrator on 2017/1/6. */public class MessageReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        try {            String message = intent.getStringExtra("MSG_TYPE");            if (MainActivity.isLogin) {                Log.i("isLogin", MainActivity.isLogin+"");                Intent mainIntent = new Intent(context, MainActivity.class);                mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                mainIntent.putExtra(Constants.EXTRA_BUNDLE, message);                context.startActivity(mainIntent);            } else {                Log.i("isLogin", MainActivity.isLogin+"");                Intent launchIntent = context.getPackageManager().                        getLaunchIntentForPackage("com.aixuetang.future");                launchIntent.setFlags(                        Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);                launchIntent.putExtra(Constants.EXTRA_BUNDLE, message);                context.startActivity(launchIntent);            }        } catch (Exception e) {        }    }}

这里需要判断当前应用是否登录,判断方式不提,登录进入MainActivity,否则启动应用,当然各种参数需要传递
launchIntent.putExtra(Constants.EXTRA_BUNDLE, message);

在MainActivity中处理消息,跳转到指定页面

    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // TODO: add setContentView(...) invocation        ButterKnife.bind(this);        receiveMessage();    }    @Override    protected void onNewIntent(Intent intent) {        super.onNewIntent(intent);        setIntent(intent);        LogUtils.e("receiveMessage--onNewIntent-->");        receiveMessage();    }    private void receiveMessage(){       String message=getIntent().getStringExtra(Constants.EXTRA_BUNDLE);        LogUtils.e("receiveMessage---->"+message);        if(!TextUtils.isEmpty(message)){            LogUtils.e("receiveMessage--->");            PushDispatchUtils.dispatch(MainActivity.this,message);        }    }

在PushDispatchUtils中对消息进行集中处理,解析消息,分类型的处理消息。

这里写图片描述

对于未启动的情况,除了传值,别无其他,这里就不在讲述。

总结,需要常驻的service接收消息—->推到广播中接收—->弹出通知栏—->点击在广播中处理通知消息—->判断是否登录—–>>>>

推荐一款好用的通知栏库,代码也很简单。

https://github.com/wenmingvs/NotifyUtil

0 0
原创粉丝点击