android集成友盟推送单刁,點擊通知灸异,先啟動應用,然后再跳指定 界面羔飞;應用前臺肺樟,接收推送,應用內彈框

版權聲明:本文為博主原創(chuàng)文章逻淌,轉載請附上原文出處鏈接和本聲明么伯。
本文鏈接:http://www.reibang.com/p/a3744cae1b52


友情提示:在看本文前,最好對友盟推送的集成文檔看個差不多卡儒,不然可能有些概念不是太清楚田柔。
友盟集成文檔:https://developer.umeng.com/docs/66632/detail/98581
本文demo下載地址:https://github.com/274800562/umengtest.git
----------------分割線--------------------
應用分為在線狀態(tài)和離線狀態(tài),以應用進程是否存在為判斷依據(jù)骨望。

通知分為在線通知和離線通知硬爆,同樣以應用進程是否存在時為判斷依據(jù)。進程存在時接收到的通知即在線通知擎鸠,離線時接收到的通知為離線通知缀磕。

一 、需求描述:

1.應用離線時,收到通知袜蚕,點擊通知糟把,啟動應用,啟動SplashActivity->MainActivity,然后根據(jù)需要跳轉相應界面牲剃。

2.應用在線:
1)應用在前臺時遣疯,收到通知,應用內彈框颠黎,點擊跳轉響應界面另锋;
2)應用在后臺時,收到通知狭归,存儲通知數(shù)據(jù)夭坪,待應用切回到前臺時再彈框,點擊跳轉響應界面过椎。

二室梅、需求實現(xiàn)
首先,我們設定有SplashActivity疚宇、MainActivity亡鼠、DetailActivity、ListActvity四個類敷待,我們通過UMessage對象的extra字段配置數(shù)據(jù):type,id,title等间涵,type=1時,跳轉DetailActivity榜揖;type=2時勾哩,跳轉ListActvity。

3B1AAB823985FD8669D0F853FE0CF9B6.jpg

1.友盟推送可以集成廠商通道举哟,以接收離線通知思劳。通過繼承UmengNotifyClickActivity類,重寫onMessage(),點擊時回調此方法妨猩。

public class UmengClickActivityextends UmengNotifyClickActivity {
        private static StringTAG = UmengClickActivity.class.getName();
        @Override
        public void onMessage(Intent intent0) {
            super.onMessage(intent0);  //此方法必須調用潜叛,否則無法統(tǒng)計打開數(shù)
            String body = intent0.getStringExtra(AgooConstants.MESSAGE_BODY);
            Log.e(TAG, "body:" + body);
            Gson gson = new Gson();
            UmengClickBean bean = gson.fromJson(body, UmengClickBean.class);
            //ExtraBean包含三個字段:type,id,title,根據(jù)type跳轉相應界面
            ExtraBean extraBean = bean.getExtra();
            if (null != bean) {
                Intent intent = new Intent(this, SplashActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//必須
                intent.putExtra("bean", extraBean);
                intent.putExtra("tag", 1);//標志位,點擊跳過去的壶硅,區(qū)別于正常邏輯跳轉
                startActivity(intent);
                finish();
             }
        }
}

接著威兜,啟動SplashActivity->MainActivity。

public class SplashActivity extends AppCompatActivity {
    public static final String TAG = "SplashActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        int tag = getIntent().getIntExtra("tag", 0);
        //1.其他操作 省略

        //2.跳主界面
        Intent intent = new Intent(this,MainActivity.class);
        //tag==1時說明是點擊離線通知過來的庐椒,需要攜帶數(shù)據(jù)跳轉
        if (tag == 1) {
            ExtraBean extraBean= (ExtraBean) getIntent().getSerializableExtra("bean");
            intent.putExtra("bean", extraBean);
            intent.putExtra("tag", tag);
        }
        startActivity(intent);
    }
}
public class MainActivity extends AppCompatActivity {
    public static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        int tag = getIntent().getIntExtra("tag", 0);
        if (tag == 1) {//點擊通知跳轉過來的牡属,有攜帶數(shù)據(jù),需要執(zhí)行跳轉邏輯扼睬,根據(jù)type跳對應界面
            ExtraBean extraBean = (ExtraBean) getIntent().getSerializableExtra("bean");
            int type = extraBean.getType();
            Log.e(TAG, "umeng  type:" + type);
            Intent intent = null;
            if (type == 1) {
                intent = new Intent(this, DetailActivity.class);
            } else {
                intent = new Intent(this, ListActivity.class);
            }
            intent.putExtra("bean", extraBean);
            startActivity(intent);
        }
    }
}

DetailActivity逮栅、ListActivity代碼相同:

public class DetailActivity extends AppCompatActivity {
    public static final String TAG = "DetailActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        ExtraBean extraBean= (ExtraBean) getIntent().getSerializableExtra("bean");
        String id = String.valueOf(extraBean.getId());
        String title = extraBean.getTitle();

        TextView textView = findViewById(R.id.textview);
        textView.setText("id:"+id+"\n"+"title:"+title);
    }
}

按上面的代碼執(zhí)行是沒有什么問題的悴势,但是有一種情況時,收到離線通知措伐,不去點擊特纤,啟動app,再去點擊侥加。這時候依然會去執(zhí)行UmengClickActivity里的onMessage()方法捧存。按照上邊的邏輯會啟動SplashActivity,而不是根據(jù)type值啟動對應的Activity担败。
我的實現(xiàn)思路是昔穴,在onMessage()方法內部添加判斷,根據(jù)結果執(zhí)行不同邏輯提前。

public class UmengClickActivity extends UmengNotifyClickActivity {
    private static String TAG = UmengClickActivity.class.getName();

    @Override
    public void onMessage(Intent intent0) {
        super.onMessage(intent0);  //此方法必須調用吗货,否則無法統(tǒng)計打開數(shù)

        String body = intent0.getStringExtra(AgooConstants.MESSAGE_BODY);
        Log.e(TAG, "body:" + body);

        Gson gson = new Gson();
        //將接收到的body信息裝換成UmengClickBean
        UmengClickBean bean = gson.fromJson(body, UmengClickBean.class);
        //ExtraBean包含三個字段:type,id,title,根據(jù)type跳轉相應界面
        ExtraBean extraBean = bean.getExtra();
        if (null != bean) {
            int type = extraBean.getType();
            Intent intent = null;
            /**
             * 判斷棧中是否有MainActivity,有則意味著程序已啟動狈网,否則沒有
             */
            if (isExistMainActivity(MainActivity.class)) {
                if (type == 1) {
                    intent = new Intent(this, DetailActivity.class);
                } else {
                    intent = new Intent(this, ListActivity.class);
                }
            } else {
                intent = new Intent(this, SplashActivity.class);
                intent.putExtra("tag", 1);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            }
            intent.putExtra("bean", extraBean);
            startActivity(intent);
            finish();
        }
    }

    @TargetApi(Build.VERSION_CODES.Q)
    private boolean isExistMainActivity(Class<?> activity) {
        Intent intent = new Intent(this, activity);
        ComponentName cmpName = intent.resolveActivity(getPackageManager());
        boolean flag = false;
        if (cmpName != null) { // 說明系統(tǒng)中存在這個activity    
            ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
            List<ActivityManager.RunningTaskInfo> taskInfoList = 
                    am.getRunningTasks(10);
            //這里獲取的是APP棧的數(shù)量宙搬,一般也就兩個
            ActivityManager.RunningTaskInfo runningTaskInfo = taskInfoList.get(0);
            // 只是拿當前運行的棧
            int numActivities = taskInfoList.get(0).numActivities;
            for (ActivityManager.RunningTaskInfo taskInfo : taskInfoList) {
                if (taskInfo.baseActivity.equals(cmpName)) {// 說明它已經(jīng)啟動了
                    flag = true;
                    break;//跳出循環(huán),優(yōu)化效率
                }
            }
        }
        return flag;
    }
}

2.應用在前臺時拓哺,接收推送勇垛,彈框;在后臺時存數(shù)據(jù)士鸥,待應用切到前臺時再彈框闲孤。
在前臺時,在umeng 封裝類里的setMessageHandler()方法內部烤礁,重寫某個方法讼积,我們是重寫dealWithNotificationMessage()。
UmengHelper.java

public class UmPushHelper {
    public static final String TAG = "UmPushHelper";
    static UmPushHelper umPushHelper;
    Context context = MyApplacation.getMyApplication();
    private PushAgent mPushAgent;

    public static UmPushHelper getInstance() {
        if (null == umPushHelper) {
            umPushHelper = new UmPushHelper();
        }
        return umPushHelper;
    }

    /**
     * 友盟初始化
     * <p>
     * 友盟初始化及相關配置
     * 注冊
     * 通道配置
     */
    public void init() {
//
        UMConfigure.init(context, "Appkey", "Umeng",
                UMConfigure.DEVICE_TYPE_PHONE, "Umeng Message Secret");
        UMConfigure.setLogEnabled(true);//日志輸出鸽凶,上線關閉
        mPushAgent = PushAgent.getInstance(context);
        mPushAgent.register(new IUmengRegisterCallback() {
            @Override
            public void onSuccess(String deviceToken) {
                //注冊成功會返回deviceToken deviceToken是推送消息的唯一標志
                Log.i(TAG, "注冊成功:deviceToken:-------->  " + deviceToken);
            }
            @Override
            public void onFailure(String s, String s1) {
                Log.e(TAG, "注冊失敱疑啊:-------->  " + "s:" + s + ",s1:" + s1);
            }
        });
        //小米通道
        MiPushRegistar.register(context, "xiaomiId", "xiaomiKey");
        //華為通道
        HuaWeiRegister.register(MyApplacation.getMyApplication());
        //魅族通道
        MeizuRegister.register(context, "appId", "appKey");
        mPushAgent.onAppStart();
        //最多展示條數(shù)
        mPushAgent.setDisplayNotificationNumber(10);
        //通知或消息接收
        setMessageHandler();
        //通知點擊
        setNotificationClickHandler();
    }
    /**
     * MessageHandler有很多回調方法建峭,根據(jù)自己需要選擇
     */
    private void setMessageHandler() {
        UmengMessageHandler messageHandler = new UmengMessageHandler() {
            @Override
            public void dealWithNotificationMessage(Context context, UMessage uMessage) {
                super.dealWithNotificationMessage(context, uMessage);
                Log.e(TAG, "um notification msg.extra" + uMessage.extra);
                try {
                    JSONObject object = new JSONObject(uMessage.extra);

                    int type = object.getInt("type");
                    Long id = object.getLong("id");
                    String title = object.getString("title");

                    ExtraBean bean = new ExtraBean();
                    bean.setId(id);
                    bean.setType(type);
                    bean.setTitle(title);
                    /**
                     * 應用不在前臺時玻侥,不彈框,并把推送的數(shù)據(jù)存起來
                     *
                     * 在前臺時直接彈框
                     */

                    if (MyApplacation.getMyApplication().getActivityCount() == 0) {
                        ExtraBeanDao dao = MyApplacation.getMyApplication().getDaoSession().getExtraBeanDao();
                        dao.insertOrReplace(bean);
                        return;
                    }
                    Intent intent = new Intent(context, NotificationDialogActivity.class);
                    intent.putExtra("bean", bean);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(intent);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        };
        PushAgent.getInstance(context).setMessageHandler(messageHandler);
    }
    private void setNotificationClickHandler() {
        /**
         * 自定義行為的回調處理亿蒸,參考文檔:高級功能-通知的展示及提醒-自定義通知打開動作
         * UmengNotificationClickHandler是在BroadcastReceiver中被調用凑兰,故
         * 如果需啟動Activity,需添加Intent.FLAG_ACTIVITY_NEW_TASK
         * */
        UmengNotificationClickHandler notificationClickHandler = new UmengNotificationClickHandler() {

            @Override
            public void launchApp(Context context, UMessage msg) {
                Log.e("umenguuu", "helper launchApp extra:" + msg.extra.toString());
                super.launchApp(context, msg);
            }

            @Override
            public void openUrl(Context context, UMessage msg) {
                Log.e("umenguuu", "helper openUrl extra:" + msg.extra.toString());
                super.openUrl(context, msg);
            }

            @Override
            public void openActivity(Context context, UMessage msg) {
                //獲取extra字段值
                Log.e("umenguuu", "helper openActivity extra:" + msg.extra.toString());
                try {
                    JSONObject object = new JSONObject(msg.extra);
                    int type = object.getInt("type");
                    long id = object.getLong("id");
                    String title = object.getString("title");
                    ExtraBean extraBean = new ExtraBean();
                    extraBean.setId(id);
                    extraBean.setType(type);
                    extraBean.setTitle(title);
                    Intent intent;
                    Log.e("umenguuu", "helper type:" + type);

                    /**
                     * type=1 跳詳情界面
                     * type=2 跳列表界面
                     */
                    if (type == 1) {
                        intent = new Intent(context, DetailActivity.class);
                    } else {
                        intent = new Intent(context, ListActivity.class);
                    }
                    intent.putExtra("bean", extraBean);

                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(intent);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void dealWithCustomAction(Context context, UMessage msg) {
                Log.e("umenguuu", "helper dealWithCustomAction extra:" + msg.extra.toString());
            }
        };
        //使用自定義的NotificationHandler   PushAgent.getInstance(context).setNotificationClickHandler(notificationClickHandler);
    }
}

應用在前臺還是在后臺的判斷是在MyApplication.java內部, mActivityCount==0時边锁,意味著應用在后臺姑食。

public class MyApplacation extends Application {
    public static final String TAG = "MyApplication";
    private static MyApplacation app;
    private DaoSession daoSession;
    private int mActivityCount = 0;
    public static MyApplacation getMyApplication() {
        return app;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        app = this;//
        UmPushHelper.getInstance().init();//初始化友盟推送
        initDb();//初始化數(shù)據(jù)庫
        /**
         * 通過mActivityCount判斷當前應用在前臺還是在后臺
         */
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                Log.d(TAG, "onActivityCreated");
            }

            @Override
            public void onActivityStarted(Activity activity) {
                Log.d(TAG, "onActivityStarted");
                mActivityCount++;
            }

            @Override
            public void onActivityResumed(Activity activity) {
                Log.d(TAG, "onActivityResumed");
                /**
                 * 后臺切前臺的時候,判斷是否有未彈框的通知消息茅坛,如果有遍歷彈框
                 *
                 * 說明:此處設計的是彈框疊加音半,如果只彈一個框则拷,luanchMode="SingleTop"
                 * 并在NotificationDialogActivity內的onNewIntent()方法內處理邏輯
                 *
                 */
                List<ExtraBean> list = getDaoSession().getExtraBeanDao().queryBuilder().list();
                if (null != list && list.size() > 0) {
                    for (ExtraBean bean : list) {
                        Intent intent = new Intent(activity, NotificationDialogActivity.class);
                        intent.putExtra("bean", bean);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//必須
                        activity.startActivity(intent);
                    }
                    getDaoSession().getExtraBeanDao().deleteAll();
                }
            }

            @Override
            public void onActivityPaused(Activity activity) {
                Log.d(TAG, "onActivityPaused");
            }

            @Override
            public void onActivityStopped(Activity activity) {
                Log.d(TAG, "onActivityStopped");
                mActivityCount--;
                if (mActivityCount == 0) {//此時切后臺
                }
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
                Log.d(TAG, "onActivitySaveInstanceState");
            }

            @Override
            public void onActivityDestroyed(Activity activity) {
                Log.d(TAG, "onActivityDestroyed");
            }
        });
    }

    public int getActivityCount(){
        return mActivityCount;
    }

    public void initDb() {
        MyOpenHelper helper = new MyOpenHelper(this, "test.db", null);
        //對數(shù)據(jù)庫庫加密
//        Database db = helper.getEncryptedWritableDb(UUID);
        //不加密,uyi
        SQLiteDatabase db = helper.getWritableDatabase();
        DaoMaster daoMaster = new DaoMaster(db);
        daoSession = daoMaster.newSession();
    }
    public DaoSession getDaoSession() {
        return daoSession;
    }
}

彈框:用一個透明activity實現(xiàn)假彈框,疊加彈框默認lanuchMode即可曹鸠,只彈一個lanuchMode="singleTop",并重寫onNewIntent()方法煌茬。

public class NotificationDialogActivity extends AppCompatActivity {
    private ExtraBean extraBean;
    private TextView textView;

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


        textView = findViewById(R.id.textview);
        TextView tvCancel = findViewById(R.id.tv_cancel);
        TextView tvConfirm = findViewById(R.id.tv_confirm);


        extraBean = (ExtraBean) getIntent().getSerializableExtra("bean");

        textView.setText(extraBean.getTitle());
        final int type = extraBean.getType();

       tvConfirm.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               Intent intent=null;
               if (type == 1) {
                   intent = new Intent(NotificationDialogActivity.this, DetailActivity.class);
               } else {
                   intent = new Intent(NotificationDialogActivity.this, ListActivity.class);
               }
               intent.putExtra("bean", extraBean);
               startActivity(intent);
               finish();
           }
       });
       tvCancel.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               finish();
           }
       });

    }
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        extraBean = (ExtraBean) intent.getSerializableExtra("bean");
        textView.setText(extraBean.getTitle());
    }
}

其他類在demo里,demo下載地址:https://github.com/274800562/umengtest.git
如果您覺得此文章對您有幫助彻桃,請多多支持坛善。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市邻眷,隨后出現(xiàn)的幾起案子眠屎,更是在濱河造成了極大的恐慌,老刑警劉巖肆饶,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件改衩,死亡現(xiàn)場離奇詭異,居然都是意外死亡抖拴,警方通過查閱死者的電腦和手機燎字,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來阿宅,“玉大人候衍,你說我怎么就攤上這事∪鞣牛” “怎么了蛉鹿?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長往湿。 經(jīng)常有香客問我妖异,道長,這世上最難降的妖魔是什么领追? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任他膳,我火速辦了婚禮,結果婚禮上绒窑,老公的妹妹穿的比我還像新娘棕孙。我一直安慰自己,他們只是感情好些膨,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布蟀俊。 她就那樣靜靜地躺著,像睡著了一般订雾。 火紅的嫁衣襯著肌膚如雪肢预。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天洼哎,我揣著相機與錄音烫映,去河邊找鬼沼本。 笑死,一個胖子當著我的面吹牛锭沟,可吹牛的內容都是我干的擅威。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼冈钦,長吁一口氣:“原來是場噩夢啊……” “哼郊丛!你這毒婦竟也來了?” 一聲冷哼從身側響起瞧筛,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤厉熟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后较幌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體揍瑟,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年乍炉,在試婚紗的時候發(fā)現(xiàn)自己被綠了绢片。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡岛琼,死狀恐怖底循,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情槐瑞,我是刑警寧澤熙涤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站困檩,受9級特大地震影響祠挫,放射性物質發(fā)生泄漏。R本人自食惡果不足惜悼沿,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一等舔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧糟趾,春花似錦慌植、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鳖藕。三九已至魔慷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間著恩,已是汗流浹背院尔。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工蜻展, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人邀摆。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓纵顾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親栋盹。 傳聞我的和親對象是個殘疾皇子施逾,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361