入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

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

创建时间:2017-01-12 投稿人: 浏览次数:1950

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

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

这里写图片描述

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

根据是否登录来做判断,为什么不根据进程是否存活来判断呢?因为在网上,很多都是根据进程是否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

声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
  • 上一篇:没有了
  • 下一篇:没有了
未上传头像