国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > Android > 正文

Android消息推送:手把手教你集成小米推送(附demo)

2019-12-12 04:18:39
字體:
供稿:網(wǎng)友

前言

在Android開發(fā)中,消息推送功能的使用非常常見。

推送消息截圖

為了降低開發(fā)成本,使用第三方推送是現(xiàn)今較為流行的解決方案。

今天,我將手把手教大家如何在你的應(yīng)用里集成小米推送

目錄

目錄

1. 官方Demo解析

首先,我們先對(duì)小米官方的推送Demo進(jìn)行解析。

請(qǐng)先到官網(wǎng)下載官方Demo和SDK說明文檔

1.1 Demo概況

Demo目錄

目錄說明:

DemoApplication類

繼承自Application類,其作用主要是:設(shè)置App的ID & Key、注冊(cè)推送服務(wù)

DemoMessageReceiver類

繼承自BroadcastReceiver,用于接收推送消息并對(duì)這些消息進(jìn)行處理

MainActivity

實(shí)現(xiàn)界面按鈕處理 & 設(shè)置本地推送方案

TimeIntervalDialog

設(shè)置推送的時(shí)間間段

接下來,我將對(duì)每個(gè)類進(jìn)行詳細(xì)分析

1.2 詳細(xì)分析

1.2.1 DemoApplication類

繼承自Application類,其作用主要是:

  • 設(shè)置App的ID & Key
  • 注冊(cè)推送服務(wù)

接下來我們通過代碼來看下這兩個(gè)功能如何實(shí)現(xiàn):

DemoApplication.Java

package com.xiaomi.mipushdemo;import android.app.ActivityManager;import android.app.ActivityManager.RunningAppProcessInfo;import android.app.Application;import android.content.Context;import android.os.Handler;import android.os.Message;import android.os.Process;import android.text.TextUtils;import android.util.Log;import android.widget.Toast;import com.xiaomi.channel.commonutils.logger.LoggerInterface;import com.xiaomi.mipush.sdk.Logger;import com.xiaomi.mipush.sdk.MiPushClient;import java.util.List;public class DemoApplication extends Application {  // 使用自己APP的ID(官網(wǎng)注冊(cè)的)  private static final String APP_ID = "1000270";  // 使用自己APP的KEY(官網(wǎng)注冊(cè)的)  private static final String APP_KEY = "670100056270";  // 此TAG在adb logcat中檢索自己所需要的信息, 只需在命令行終端輸入 adb logcat | grep  // com.xiaomi.mipushdemo  public static final String TAG = "com.xiaomi.mipushdemo";  private static DemoHandler sHandler = null;  private static MainActivity sMainActivity = null;  //為了提高推送服務(wù)的注冊(cè)率,官方Demo建議在Application的onCreate中初始化推送服務(wù)  //你也可以根據(jù)需要,在其他地方初始化推送服務(wù)  @Override  public void onCreate() {    super.onCreate();    //判斷用戶是否已經(jīng)打開App,詳細(xì)見下面方法定義    if (shouldInit()) {    //注冊(cè)推送服務(wù)    //注冊(cè)成功后會(huì)向DemoMessageReceiver發(fā)送廣播    // 可以從DemoMessageReceiver的onCommandResult方法中MiPushCommandMessage對(duì)象參數(shù)中獲取注冊(cè)信息      MiPushClient.registerPush(this, APP_ID, APP_KEY);     //參數(shù)說明    //context:Android平臺(tái)上app的上下文,建議傳入當(dāng)前app的application context    //appID:在開發(fā)者網(wǎng)站上注冊(cè)時(shí)生成的,MiPush推送服務(wù)頒發(fā)給app的唯一認(rèn)證標(biāo)識(shí)    //appKey:在開發(fā)者網(wǎng)站上注冊(cè)時(shí)生成的,與appID相對(duì)應(yīng),用于驗(yàn)證appID是否合法    }    //下面是與測(cè)試相關(guān)的日志設(shè)置    LoggerInterface newLogger = new LoggerInterface() {      @Override      public void setTag(String tag) {        // ignore      }      @Override      public void log(String content, Throwable t) {        Log.d(TAG, content, t);      }      @Override      public void log(String content) {        Log.d(TAG, content);      }    };    Logger.setLogger(this, newLogger);    if (sHandler == null) {      sHandler = new DemoHandler(getApplicationContext());    }  }//通過判斷手機(jī)里的所有進(jìn)程是否有這個(gè)App的進(jìn)程//從而判斷該App是否有打開  private boolean shouldInit() {//通過ActivityManager我們可以獲得系統(tǒng)里正在運(yùn)行的activities//包括進(jìn)程(Process)等、應(yīng)用程序/包、服務(wù)(Service)、任務(wù)(Task)信息。    ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));    List<RunningAppProcessInfo> processInfos = am.getRunningAppProcesses();    String mainProcessName = getPackageName();    //獲取本App的唯一標(biāo)識(shí)    int myPid = Process.myPid();    //利用一個(gè)增強(qiáng)for循環(huán)取出手機(jī)里的所有進(jìn)程    for (RunningAppProcessInfo info : processInfos) {      //通過比較進(jìn)程的唯一標(biāo)識(shí)和包名判斷進(jìn)程里是否存在該App      if (info.pid == myPid && mainProcessName.equals(info.processName)) {        return true;      }    }    return false;  }  public static DemoHandler getHandler() {    return sHandler;  }  public static void setMainActivity(MainActivity activity) {    sMainActivity = activity;  }//通過設(shè)置Handler來設(shè)置提示文案  public static class DemoHandler extends Handler {    private Context context;    public DemoHandler(Context context) {      this.context = context;    }    @Override    public void handleMessage(Message msg) {      String s = (String) msg.obj;      if (sMainActivity != null) {        sMainActivity.refreshLogInfo();      }      if (!TextUtils.isEmpty(s)) {        Toast.makeText(context, s, Toast.LENGTH_LONG).show();      }    }  }}

總結(jié):

步驟1:先判斷應(yīng)用App是否已開啟 - 通過判斷系統(tǒng)里的進(jìn)程

通過靜態(tài)方法

public static void registerPush(Context context, String appID, String appKey)

進(jìn)行推送服務(wù)注冊(cè),詳細(xì)參數(shù)如下:

為了提高注冊(cè)率,最好在Application的onCreate中初始化推送服務(wù) 

你也可以根據(jù)需要,在其他地方初始化推送服務(wù)

1.2.2 DemoMessageReceiver類

繼承自PushMessageReceiver(抽象類,繼承自BroadcastReceiver),其作用主要是:

  • 接收推送消息
  • 對(duì)推送消息進(jìn)行處理

DemoMessageReceiver.java

package com.xiaomi.mipushdemo;import android.annotation.SuppressLint;import android.content.Context;import android.os.Message;import android.text.TextUtils;import android.util.Log;import com.xiaomi.mipush.sdk.ErrorCode;import com.xiaomi.mipush.sdk.MiPushClient;import com.xiaomi.mipush.sdk.MiPushCommandMessage;import com.xiaomi.mipush.sdk.MiPushMessage;import com.xiaomi.mipush.sdk.PushMessageReceiver;import java.text.SimpleDateFormat;import java.util.Date;import java.util.List;/** * 1、PushMessageReceiver 是個(gè)抽象類,該類繼承了 BroadcastReceiver。 * 2、需要將自定義的 DemoMessageReceiver 注冊(cè)在 AndroidManifest.xmlpublic class DemoMessageReceiver extends PushMessageReceiver {  private String mRegId;  private String mTopic;  private String mAlias;  private String mAccount;  private String mStartTime;  private String mEndTime;  //透?jìng)飨⒌竭_(dá)客戶端時(shí)調(diào)用  //作用:可通過參數(shù)message從而獲得透?jìng)飨ⅲ唧w請(qǐng)看官方SDK文檔  @Override  public void onReceivePassThroughMessage(Context context, MiPushMessage message) {    Log.v(DemoApplication.TAG,        "onReceivePassThroughMessage is called. " + message.toString());    String log = context.getString(R.string.recv_passthrough_message, message.getContent());    MainActivity.logList.add(0, getSimpleDate() + " " + log);    if (!TextUtils.isEmpty(message.getTopic())) {      mTopic = message.getTopic();    } else if (!TextUtils.isEmpty(message.getAlias())) {      mAlias = message.getAlias();    }    Message msg = Message.obtain();    msg.obj = log;    DemoApplication.getHandler().sendMessage(msg);  }//通知消息到達(dá)客戶端時(shí)調(diào)用   //注:應(yīng)用在前臺(tái)時(shí)不彈出通知的通知消息到達(dá)客戶端時(shí)也會(huì)回調(diào)函數(shù)  //作用:通過參數(shù)message從而獲得通知消息,具體請(qǐng)看官方SDK文檔  @Override  public void onNotificationMessageArrived(Context context, MiPushMessage message) {    Log.v(DemoApplication.TAG,        "onNotificationMessageArrived is called. " + message.toString());    String log = context.getString(R.string.arrive_notification_message, message.getContent());    MainActivity.logList.add(0, getSimpleDate() + " " + log);    if (!TextUtils.isEmpty(message.getTopic())) {      mTopic = message.getTopic();    } else if (!TextUtils.isEmpty(message.getAlias())) {      mAlias = message.getAlias();    }    Message msg = Message.obtain();    msg.obj = log;    DemoApplication.getHandler().sendMessage(msg);  }  //用戶手動(dòng)點(diǎn)擊通知欄消息時(shí)調(diào)用   //注:應(yīng)用在前臺(tái)時(shí)不彈出通知的通知消息到達(dá)客戶端時(shí)也會(huì)回調(diào)函數(shù)  //作用:1. 通過參數(shù)message從而獲得通知消息,具體請(qǐng)看官方SDK文檔  //2. 設(shè)置用戶點(diǎn)擊消息后打開應(yīng)用 or 網(wǎng)頁(yè) or 其他頁(yè)面  @Override  public void onNotificationMessageClicked(Context context, MiPushMessage message) {    Log.v(DemoApplication.TAG,        "onNotificationMessageClicked is called. " + message.toString());    String log = context.getString(R.string.click_notification_message, message.getContent());    MainActivity.logList.add(0, getSimpleDate() + " " + log);    if (!TextUtils.isEmpty(message.getTopic())) {      mTopic = message.getTopic();    } else if (!TextUtils.isEmpty(message.getAlias())) {      mAlias = message.getAlias();    }    Message msg = Message.obtain();    if (message.isNotified()) {      msg.obj = log;    }    DemoApplication.getHandler().sendMessage(msg);  }  //用來接收客戶端向服務(wù)器發(fā)送命令后的響應(yīng)結(jié)果。  @Override  public void onCommandResult(Context context, MiPushCommandMessage message) {    Log.v(DemoApplication.TAG,        "onCommandResult is called. " + message.toString());    String command = message.getCommand();    List<String> arguments = message.getCommandArguments();    String cmdArg1 = ((arguments != null && arguments.size() > 0) ? arguments.get(0) : null);    String cmdArg2 = ((arguments != null && arguments.size() > 1) ? arguments.get(1) : null);    String log;    if (MiPushClient.COMMAND_REGISTER.equals(command)) {      if (message.getResultCode() == ErrorCode.SUCCESS) {        mRegId = cmdArg1;        log = context.getString(R.string.register_success);      } else {        log = context.getString(R.string.register_fail);      }    } else if (MiPushClient.COMMAND_SET_ALIAS.equals(command)) {      if (message.getResultCode() == ErrorCode.SUCCESS) {        mAlias = cmdArg1;        log = context.getString(R.string.set_alias_success, mAlias);      } else {        log = context.getString(R.string.set_alias_fail, message.getReason());      }    } else if (MiPushClient.COMMAND_UNSET_ALIAS.equals(command)) {      if (message.getResultCode() == ErrorCode.SUCCESS) {        mAlias = cmdArg1;        log = context.getString(R.string.unset_alias_success, mAlias);      } else {        log = context.getString(R.string.unset_alias_fail, message.getReason());      }    } else if (MiPushClient.COMMAND_SET_ACCOUNT.equals(command)) {      if (message.getResultCode() == ErrorCode.SUCCESS) {        mAccount = cmdArg1;        log = context.getString(R.string.set_account_success, mAccount);      } else {        log = context.getString(R.string.set_account_fail, message.getReason());      }    } else if (MiPushClient.COMMAND_UNSET_ACCOUNT.equals(command)) {      if (message.getResultCode() == ErrorCode.SUCCESS) {        mAccount = cmdArg1;        log = context.getString(R.string.unset_account_success, mAccount);      } else {        log = context.getString(R.string.unset_account_fail, message.getReason());      }    } else if (MiPushClient.COMMAND_SUBSCRIBE_TOPIC.equals(command)) {      if (message.getResultCode() == ErrorCode.SUCCESS) {        mTopic = cmdArg1;        log = context.getString(R.string.subscribe_topic_success, mTopic);      } else {        log = context.getString(R.string.subscribe_topic_fail, message.getReason());      }    } else if (MiPushClient.COMMAND_UNSUBSCRIBE_TOPIC.equals(command)) {      if (message.getResultCode() == ErrorCode.SUCCESS) {        mTopic = cmdArg1;        log = context.getString(R.string.unsubscribe_topic_success, mTopic);      } else {        log = context.getString(R.string.unsubscribe_topic_fail, message.getReason());      }    } else if (MiPushClient.COMMAND_SET_ACCEPT_TIME.equals(command)) {      if (message.getResultCode() == ErrorCode.SUCCESS) {        mStartTime = cmdArg1;        mEndTime = cmdArg2;        log = context.getString(R.string.set_accept_time_success, mStartTime, mEndTime);      } else {        log = context.getString(R.string.set_accept_time_fail, message.getReason());      }    } else {      log = message.getReason();    }    MainActivity.logList.add(0, getSimpleDate() + "  " + log);    Message msg = Message.obtain();    msg.obj = log;    DemoApplication.getHandler().sendMessage(msg);  }  //用于接收客戶端向服務(wù)器發(fā)送注冊(cè)命令后的響應(yīng)結(jié)果。  @Override  public void onReceiveRegisterResult(Context context, MiPushCommandMessage message) {    Log.v(DemoApplication.TAG,        "onReceiveRegisterResult is called. " + message.toString());    String command = message.getCommand();    List<String> arguments = message.getCommandArguments();    String cmdArg1 = ((arguments != null && arguments.size() > 0) ? arguments.get(0) : null);    String log;    if (MiPushClient.COMMAND_REGISTER.equals(command)) {      if (message.getResultCode() == ErrorCode.SUCCESS) {        mRegId = cmdArg1;        //打印日志:注冊(cè)成功        log = context.getString(R.string.register_success);      } else {           //打印日志:注冊(cè)失敗        log = context.getString(R.string.register_fail);      }    } else {      log = message.getReason();    }    Message msg = Message.obtain();    msg.obj = log;    DemoApplication.getHandler().sendMessage(msg);  }  @SuppressLint("SimpleDateFormat")  private static String getSimpleDate() {    return new SimpleDateFormat("MM-dd hh:mm:ss").format(new Date());  }}

總結(jié)

根據(jù)需要復(fù)寫PushMessageReceiver里對(duì)消息的相關(guān)處理方法,以下是相關(guān)方法的詳情:

相關(guān)方法詳情

關(guān)于onCommandResult(Context context,MiPushCommandMessage message)

a. 作用:當(dāng)客戶端向服務(wù)器發(fā)送注冊(cè)push、設(shè)置alias、取消注冊(cè)alias、訂閱topic、取消訂閱topic等等命令后,從服務(wù)器返回結(jié)果。

b. 參數(shù)說明:

參數(shù)說明

1.2.3 MainActivity

用于給用戶設(shè)置標(biāo)識(shí),如別名、標(biāo)簽、賬號(hào)等等

MainActivity.java

public class MainActivity extends Activity {  public static List<String> logList = new CopyOnWriteArrayList<String>();  private TextView mLogView = null;  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    DemoApplication.setMainActivity(this);    mLogView = (TextView) findViewById(R.id.log);    // 設(shè)置別名    findViewById(R.id.set_alias).setOnClickListener(new OnClickListener() {      @Override      public void onClick(View v) {        final EditText editText = new EditText(MainActivity.this);        new AlertDialog.Builder(MainActivity.this)            .setTitle(R.string.set_alias)            .setView(editText)            .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {              @Override              public void onClick(DialogInterface dialog, int which) {                String alias = editText.getText().toString();//調(diào)用靜態(tài)方法進(jìn)行設(shè)置                MiPushClient.setAlias(MainActivity.this, alias, null);              }            })            .setNegativeButton(R.string.cancel, null)            .show();      }    });    // 撤銷別名    findViewById(R.id.unset_alias).setOnClickListener(new OnClickListener() {      @Override      public void onClick(View v) {        final EditText editText = new EditText(MainActivity.this);        new AlertDialog.Builder(MainActivity.this)            .setTitle(R.string.unset_alias)            .setView(editText)            .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {              @Override              public void onClick(DialogInterface dialog, int which) {                String alias = editText.getText().toString();//調(diào)用靜態(tài)方法進(jìn)行設(shè)置                 MiPushClient.unsetAlias(MainActivity.this, alias, null);              }            })            .setNegativeButton(R.string.cancel, null)            .show();      }    });    // 設(shè)置帳號(hào)    findViewById(R.id.set_account).setOnClickListener(new OnClickListener() {      @Override      public void onClick(View v) {        final EditText editText = new EditText(MainActivity.this);        new AlertDialog.Builder(MainActivity.this)            .setTitle(R.string.set_account)            .setView(editText)            .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {              @Override              public void onClick(DialogInterface dialog, int which) {                String account = editText.getText().toString();//調(diào)用靜態(tài)方法進(jìn)行設(shè)置                 MiPushClient.setUserAccount(MainActivity.this, account, null);              }            })            .setNegativeButton(R.string.cancel, null)            .show();      }    });    // 撤銷帳號(hào)    findViewById(R.id.unset_account).setOnClickListener(new OnClickListener() {      @Override      public void onClick(View v) {        final EditText editText = new EditText(MainActivity.this);        new AlertDialog.Builder(MainActivity.this)            .setTitle(R.string.unset_account)            .setView(editText)            .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {              @Override              public void onClick(DialogInterface dialog, int which) {                String account = editText.getText().toString();//調(diào)用靜態(tài)方法進(jìn)行設(shè)置                 MiPushClient.unsetUserAccount(MainActivity.this, account, null);              }            })            .setNegativeButton(R.string.cancel, null)            .show();      }    });    // 設(shè)置標(biāo)簽    findViewById(R.id.subscribe_topic).setOnClickListener(new OnClickListener() {      @Override      public void onClick(View v) {        final EditText editText = new EditText(MainActivity.this);        new AlertDialog.Builder(MainActivity.this)            .setTitle(R.string.subscribe_topic)            .setView(editText)            .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {              @Override              public void onClick(DialogInterface dialog, int which) {                String topic = editText.getText().toString();//調(diào)用靜態(tài)方法進(jìn)行設(shè)置                 MiPushClient.subscribe(MainActivity.this, topic, null);              }            })            .setNegativeButton(R.string.cancel, null)            .show();      }    });    // 撤銷標(biāo)簽    findViewById(R.id.unsubscribe_topic).setOnClickListener(new OnClickListener() {      @Override      public void onClick(View v) {        final EditText editText = new EditText(MainActivity.this);        new AlertDialog.Builder(MainActivity.this)            .setTitle(R.string.unsubscribe_topic)            .setView(editText)            .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {              @Override              public void onClick(DialogInterface dialog, int which) {                String topic = editText.getText().toString();//調(diào)用靜態(tài)方法進(jìn)行設(shè)置                 MiPushClient.unsubscribe(MainActivity.this, topic, null);              }            })            .setNegativeButton(R.string.cancel, null)            .show();      }    });    // 設(shè)置接收消息時(shí)間    findViewById(R.id.set_accept_time).setOnClickListener(new OnClickListener() {      @Override      public void onClick(View v) {        new TimeIntervalDialog(MainActivity.this, new TimeIntervalInterface() {          @Override          public void apply(int startHour, int startMin, int endHour,                   int endMin) {            //調(diào)用靜態(tài)方法進(jìn)行設(shè)置             MiPushClient.setAcceptTime(MainActivity.this, startHour, startMin, endHour, endMin, null);          }          @Override          public void cancel() {            //ignore          }        })            .show();      }    });    // 暫停推送    findViewById(R.id.pause_push).setOnClickListener(new OnClickListener() {      @Override      public void onClick(View v) {        MiPushClient.pausePush(MainActivity.this, null);      }    });    findViewById(R.id.resume_push).setOnClickListener(new OnClickListener() {      @Override      public void onClick(View v) {      //調(diào)用靜態(tài)方法進(jìn)行設(shè)置         MiPushClient.resumePush(MainActivity.this, null);      }    });  }  @Override  protected void onResume() {    super.onResume();    refreshLogInfo();  }  @Override  protected void onDestroy() {    super.onDestroy();    DemoApplication.setMainActivity(null);  }  public void refreshLogInfo() {    String AllLog = "";    for (String log : logList) {      AllLog = AllLog + log + "/n/n";    }    mLogView.setText(AllLog);  }}

總結(jié):

根據(jù)需求對(duì)不同用戶設(shè)置不同的推送標(biāo)識(shí),如別名、標(biāo)簽等等。

a. 別名(Alias)

1、開發(fā)者可以為指定用戶設(shè)置別名,然后給這個(gè)別名推送消息, 

效果等同于給RegId推送消息,Alias是除Regid(自動(dòng)生成的)和UserAccount之外的第三個(gè)用戶標(biāo)識(shí)

2、開發(fā)者可以取消指定用戶的某個(gè)別名,服務(wù)器就不會(huì)給這個(gè)別名推送消息了。

//設(shè)置別名MiPushClient.setAlias(Context context, String alias, String category);//撤銷別名MiPushClient.unsetAlias(Context context, String alias, String category);//參數(shù)說明//context:Android平臺(tái)上app的上下文,建議傳入當(dāng)前app的application context//alias:為指定用戶設(shè)置別名 / 為指定用戶取消別名//category:擴(kuò)展參數(shù),暫時(shí)沒有用途,直接填null//獲取該客戶端所有的別名public static List<String> getAllAlias(final Context context)

b. 用戶賬號(hào)(UserAccoun)

  • 開發(fā)者可以為指定用戶設(shè)置userAccount
  • 開發(fā)者可以取消指定用戶的某個(gè)userAccount,服務(wù)器就不會(huì)給這個(gè)userAccount推送消息了
//設(shè)置MiPushClient.setUserAccount(final Context context, final String userAccount, Stringcategory)//撤銷MiPushClient.unsetUserAccount(final Context context, final String userAccount, Stringcategory)//參數(shù)說明//context:Android平臺(tái)上app的上下文,建議傳入當(dāng)前app的application context//userAccount:為指定用戶設(shè)置userAccount / 為指定用戶取消userAccount//category:擴(kuò)展參數(shù),暫時(shí)沒有用途,直接填null//獲取該客戶端所有設(shè)置的賬號(hào)public static List<String> getAllUserAccount(final Context context)

c. 標(biāo)簽(Topic)

  • 開發(fā)者可以結(jié)合自己的業(yè)務(wù)特征,給用戶打上不同的標(biāo)簽。
  • 消息推送時(shí),開發(fā)者可以結(jié)合每條消息的內(nèi)容和目標(biāo)用戶,為每條消息選擇對(duì)應(yīng)的標(biāo)簽,為開發(fā)者可以根據(jù)訂閱的主題實(shí)現(xiàn)分組群發(fā),從而進(jìn)行消息的精準(zhǔn)推送
//設(shè)置標(biāo)簽MiPushClient.subscribe(Context context, String topic, String category);//撤銷標(biāo)簽MiPushClient.unsubscribe(Context context, String topic, String category);//參數(shù)說明//context:Android平臺(tái)上app的上下文,建議傳入當(dāng)前app的application context//topic:為指定用戶設(shè)置設(shè)置訂閱的主題 / 為指定用戶取消訂閱的主題//category:擴(kuò)展參數(shù),暫時(shí)沒有用途,直接填null//獲取該客戶端所有的標(biāo)簽public static List<String> getAllTopic(final Context context);

TimeIntervalDialog

作用:用于設(shè)置推送的時(shí)間-開始時(shí)間+暫停時(shí)間

package com.xiaomi.mipushdemo;import android.app.Dialog;import android.content.Context;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TimePicker;import android.widget.TimePicker.OnTimeChangedListener;//繼承OnTimeChangedListener接口public class TimeIntervalDialog extends Dialog implements OnTimeChangedListener {  private TimeIntervalInterface mTimeIntervalInterface;  private Context mContext;  private TimePicker mStartTimePicker, mEndTimePicker;  private int mStartHour, mStartMinute, mEndHour, mEndMinute;  private Button.OnClickListener clickListener = new Button.OnClickListener() {    @Override    public void onClick(View v) {      switch (v.getId()) {        case R.id.apply:          dismiss();          //設(shè)置時(shí)間參數(shù)          mTimeIntervalInterface.apply(mStartHour, mStartMinute, mEndHour, mEndMinute);          break;        case R.id.cancel:          dismiss();          mTimeIntervalInterface.cancel();          break;        default:          break;      }    }  };  public TimeIntervalDialog(Context context, TimeIntervalInterface timeIntervalInterface,               int startHour, int startMinute, int endHour, int endMinute) {    super(context);    mContext = context;    this.mTimeIntervalInterface = timeIntervalInterface;    this.mStartHour = startHour;    this.mStartMinute = startMinute;    this.mEndHour = endHour;    this.mEndMinute = endMinute;  }  public TimeIntervalDialog(Context context, TimeIntervalInterface timeIntervalInterface) {    this(context, timeIntervalInterface, 0, 0, 23, 59);  }  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.set_time_dialog);    setCancelable(true);    setTitle(mContext.getString(R.string.set_accept_time));    mStartTimePicker = (TimePicker) findViewById(R.id.startTimePicker);    mStartTimePicker.setIs24HourView(true);    mStartTimePicker.setCurrentHour(mStartHour);    mStartTimePicker.setCurrentMinute(mStartMinute);    mStartTimePicker.setOnTimeChangedListener(this);    mEndTimePicker = (TimePicker) findViewById(R.id.endTimePicker);    mEndTimePicker.setIs24HourView(true);    mEndTimePicker.setCurrentHour(mEndHour);    mEndTimePicker.setCurrentMinute(mEndMinute);    mEndTimePicker.setOnTimeChangedListener(this);    Button applyBtn = (Button) findViewById(R.id.apply);    applyBtn.setOnClickListener(clickListener);    Button cancelBtn = (Button) findViewById(R.id.cancel);    cancelBtn.setOnClickListener(clickListener);  }  @Override  public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {    if (view == mStartTimePicker) {      mStartHour = hourOfDay;      mStartMinute = minute;    } else if (view == mEndTimePicker) {      mEndHour = hourOfDay;      mEndMinute = minute;    }  }  interface TimeIntervalInterface {    void apply(int startHour, int startMin, int endHour, int endMin);    void cancel();  }}

總結(jié)

  • 使用一個(gè)繼承了Dialog類的TimeIntervalDialog類進(jìn)行推送時(shí)間的配置
  • 可進(jìn)行的配置:設(shè)置推送時(shí)間(開始 & 結(jié)束)、暫停推送時(shí)間、恢復(fù)推送時(shí)間
//設(shè)置推送時(shí)間(開始 & 結(jié)束)MiPushClient.setAcceptTime(Context context, int startHour, int startMin, int endHour,int endMin, String category)//設(shè)置暫停推送時(shí)間、恢復(fù)推送時(shí)間pausePush(Context context, String category)`和`resumePush(Context context, String category)//參數(shù)說明//context:Android平臺(tái)上app的上下文,建議傳入當(dāng)前app的application context//startHour:接收時(shí)段開始時(shí)間的小時(shí)//startMin :接收時(shí)段開始時(shí)間的分鐘//endHour:接收時(shí)段結(jié)束時(shí)間的小時(shí)//endMin:接收時(shí)段結(jié)束時(shí)間的分鐘//category:擴(kuò)展參數(shù),暫時(shí)沒有用途,直接填null

AndroidManifest文件的配置

//小米推送支持最低的Android版本是2.2<uses-sdk android:minSdkVersion="8"/>//設(shè)置一系列權(quán)限  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  <uses-permission android:name="android.permission.INTERNET" />  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />  <uses-permission android:name="android.permission.READ_PHONE_STATE" />  <uses-permission android:name="android.permission.GET_TASKS" />  <uses-permission android:name="android.permission.VIBRATE" />//這里com.xiaomi.mipushdemo改成自身app的包名  <permission android:name="com.xiaomi.mipushdemo.permission.MIPUSH_RECEIVE" android:protectionLevel="signature" />//這里com.xiaomi.mipushdemo改成自身app的包名  <uses-permission android:name="com.xiaomi.mipushdemo.permission.MIPUSH_RECEIVE" />//注冊(cè)廣播BroadcastReceiver & Service//都是靜態(tài)注冊(cè),因?yàn)橐L(zhǎng)期處在后臺(tái)運(yùn)行//注:共是3個(gè)廣播接收器和4個(gè)服務(wù),其中包括繼承了PushMessageReceiver的DemoMessageReceiver    //4個(gè)后臺(tái)服務(wù)    <service     android:enabled="true"     android:process=":pushservice"     android:name="com.xiaomi.push.service.XMPushService"/>    //此service必須在3.0.1版本以后(包括3.0.1版本)加入    <service     android:name="com.xiaomi.push.service.XMJobService"     android:enabled="true"     android:exported="false"     android:permission="android.permission.BIND_JOB_SERVICE"     android:process=":pushservice" />    //此service必須在2.2.5版本以后(包括2.2.5版本)加入    <service     android:enabled="true"     android:exported="true"     android:name="com.xiaomi.mipush.sdk.PushMessageHandler" />     <service android:enabled="true"     android:name="com.xiaomi.mipush.sdk.MessageHandleService" />     //3個(gè)廣播    <receiver     android:exported="true"     android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver" >     <intent-filter>      <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />      <category android:name="android.intent.category.DEFAULT" />     </intent-filter>    </receiver>    <receiver     android:exported="false"     android:process=":pushservice"     android:name="com.xiaomi.push.service.receivers.PingReceiver" >     <intent-filter>      <action android:name="com.xiaomi.push.PING_TIMER" />     </intent-filter>    </receiver>//繼承了PushMessageReceiver的DemoMessageReceiver的廣播注冊(cè)    <receiver      android:name="com.xiaomi.mipushdemo.DemoMessageReceiver"      android:exported="true">      <intent-filter>        <action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE" />      </intent-filter>      <intent-filter>        <action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED" />      </intent-filter>      <intent-filter>        <action android:name="com.xiaomi.mipush.ERROR" />      </intent-filter>    </receiver>

2. 集成小米推送步驟匯總

  • 步驟1:在小米推送平臺(tái)進(jìn)行相關(guān)注冊(cè)開發(fā)者賬號(hào),并進(jìn)行應(yīng)用的注冊(cè):應(yīng)用包名,AppID和AppKey
  • 步驟2:將小米推送的SDK包加入庫(kù)
  • 步驟3:在應(yīng)用內(nèi)初始化小米推送服務(wù)
  • 步驟4:繼承PushMessageReceiver,并復(fù)寫相關(guān)推送消息的方法
  • 步驟5:在AndroidManifest文件里面配置好權(quán)限、注冊(cè)Service和BroadcastReceiver
  • 在Android6.0里面的權(quán)限需要?jiǎng)討B(tài)獲取
  • 步驟6:根據(jù)需要設(shè)置一系列的推送設(shè)置,如用戶別名、標(biāo)簽等等

接下來,我們來按照上面的步驟,一步步來實(shí)現(xiàn)一個(gè)簡(jiǎn)易的小米推送Demo

3. 實(shí)例解析

步驟1:在小米推送平臺(tái)進(jìn)行相關(guān)注冊(cè)開發(fā)者賬號(hào),并進(jìn)行應(yīng)用的注冊(cè):應(yīng)用包名,AppID和AppKey

注意,填入的包名要跟你的應(yīng)用App的包名是一致的

創(chuàng)建應(yīng)用

AppID和Key

步驟2:將小米推送的SDK包加入到你應(yīng)用的庫(kù)里

點(diǎn)擊此處進(jìn)行下載

小米推送SDK

步驟3:在應(yīng)用內(nèi)初始化小米推送服務(wù)

為了提高推送服務(wù)的注冊(cè)率,我選擇在Application的onCreate中初始化推送服務(wù) *BaseActivity.java*

package scut.carson_ho.demo_mipush;import android.app.ActivityManager;import android.app.Application;import android.content.Context;import android.os.Process;import com.xiaomi.mipush.sdk.MiPushClient;import java.util.List;/** * Created by Carson_Ho on 16/10/26. */  //主要要繼承Applicationpublic class BaseActivity extends Application {  // 使用自己APP的ID(官網(wǎng)注冊(cè)的)  private static final String APP_ID = "2882303761517520369";  // 使用自己APP的Key(官網(wǎng)注冊(cè)的)  private static final String APP_KEY = "5401752085369";  //為了提高推送服務(wù)的注冊(cè)率,我建議在Application的onCreate中初始化推送服務(wù)  //你也可以根據(jù)需要,在其他地方初始化推送服務(wù)  @Override  public void onCreate() {    super.onCreate();    if (shouldInit()) {      //注冊(cè)推送服務(wù)      //注冊(cè)成功后會(huì)向DemoMessageReceiver發(fā)送廣播      // 可以從DemoMessageReceiver的onCommandResult方法中MiPushCommandMessage對(duì)象參數(shù)中獲取注冊(cè)信息      MiPushClient.registerPush(this, APP_ID, APP_KEY);    }  }  //通過判斷手機(jī)里的所有進(jìn)程是否有這個(gè)App的進(jìn)程  //從而判斷該App是否有打開  private boolean shouldInit() {  //通過ActivityManager我們可以獲得系統(tǒng)里正在運(yùn)行的activities  //包括進(jìn)程(Process)等、應(yīng)用程序/包、服務(wù)(Service)、任務(wù)(Task)信息。    ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));    List<ActivityManager.RunningAppProcessInfo> processInfos = am.getRunningAppProcesses();    String mainProcessName = getPackageName();    //獲取本App的唯一標(biāo)識(shí)    int myPid = Process.myPid();    //利用一個(gè)增強(qiáng)for循環(huán)取出手機(jī)里的所有進(jìn)程    for (ActivityManager.RunningAppProcessInfo info : processInfos) {      //通過比較進(jìn)程的唯一標(biāo)識(shí)和包名判斷進(jìn)程里是否存在該App      if (info.pid == myPid && mainProcessName.equals(info.processName)) {        return true;      }    }    return false;  }}

注意要在Android.manifest.xml里的application里加入

android:name=".BaseActivity"

這樣在應(yīng)用初始化時(shí)是第一個(gè)加載BaseActivity.java類文件的

如下圖:

示意圖

步驟4:設(shè)置子類繼承PushMessageReceiver,并復(fù)寫相關(guān)推送消息的方法

Mipush_Broadcast.java

package scut.carson_ho.demo_mipush;import android.content.Context;import com.xiaomi.mipush.sdk.ErrorCode;import com.xiaomi.mipush.sdk.MiPushClient;import com.xiaomi.mipush.sdk.MiPushCommandMessage;import com.xiaomi.mipush.sdk.MiPushMessage;import com.xiaomi.mipush.sdk.PushMessageReceiver;/** * Created by Carson_Ho on 16/10/26. */public class Mipush_Broadcast extends PushMessageReceiver {  //透?jìng)飨⒌竭_(dá)客戶端時(shí)調(diào)用  //作用:可通過參數(shù)message從而獲得透?jìng)飨ⅲ唧w請(qǐng)看官方SDK文檔  @Override  public void onReceivePassThroughMessage(Context context, MiPushMessage message) {    //打印消息方便測(cè)試    System.out.println("透?jìng)飨⒌竭_(dá)了");    System.out.println("透?jìng)飨⑹?+message.toString());  }//通知消息到達(dá)客戶端時(shí)調(diào)用  //注:應(yīng)用在前臺(tái)時(shí)不彈出通知的通知消息到達(dá)客戶端時(shí)也會(huì)回調(diào)函數(shù)  //作用:通過參數(shù)message從而獲得通知消息,具體請(qǐng)看官方SDK文檔  @Override  public void onNotificationMessageArrived(Context context, MiPushMessage message) {    //打印消息方便測(cè)試    System.out.println("通知消息到達(dá)了");    System.out.println("通知消息是"+message.toString());  }  //用戶手動(dòng)點(diǎn)擊通知欄消息時(shí)調(diào)用  //注:應(yīng)用在前臺(tái)時(shí)不彈出通知的通知消息到達(dá)客戶端時(shí)也會(huì)回調(diào)函數(shù)  //作用:1. 通過參數(shù)message從而獲得通知消息,具體請(qǐng)看官方SDK文檔  //2. 設(shè)置用戶點(diǎn)擊消息后打開應(yīng)用 or 網(wǎng)頁(yè) or 其他頁(yè)面  @Override  public void onNotificationMessageClicked(Context context, MiPushMessage message) {    //打印消息方便測(cè)試    System.out.println("用戶點(diǎn)擊了通知消息");    System.out.println("通知消息是" + message.toString());    System.out.println("點(diǎn)擊后,會(huì)進(jìn)入應(yīng)用" );  }  //用來接收客戶端向服務(wù)器發(fā)送命令后的響應(yīng)結(jié)果。  @Override  public void onCommandResult(Context context, MiPushCommandMessage message) {    String command = message.getCommand();    System.out.println(command );    if (MiPushClient.COMMAND_REGISTER.equals(command)) {      if (message.getResultCode() == ErrorCode.SUCCESS) {        //打印信息便于測(cè)試注冊(cè)成功與否        System.out.println("注冊(cè)成功");      } else {        System.out.println("注冊(cè)失敗");      }    }  }  //用于接收客戶端向服務(wù)器發(fā)送注冊(cè)命令后的響應(yīng)結(jié)果。  @Override  public void onReceiveRegisterResult(Context context, MiPushCommandMessage message) {    String command = message.getCommand();    System.out.println(command );    if (MiPushClient.COMMAND_REGISTER.equals(command)) {      if (message.getResultCode() == ErrorCode.SUCCESS) {        //打印日志:注冊(cè)成功        System.out.println("注冊(cè)成功");      } else {        //打印日志:注冊(cè)失敗        System.out.println("注冊(cè)失敗");      }    } else {      System.out.println("其他情況"+message.getReason());    }  }}

步驟5:在AndroidManifest文件里面配置好權(quán)限、注冊(cè)Service和BroadcastReceiver

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"  package="scut.carson_ho.demo_mipush">  //相關(guān)權(quán)限  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  <uses-permission android:name="android.permission.INTERNET" />  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />  <uses-permission android:name="android.permission.READ_PHONE_STATE" />  <uses-permission android:name="android.permission.GET_TASKS" />  <uses-permission android:name="android.permission.VIBRATE" />  //注意這里.permission.MIPUSH_RECEIVE是自身app的包名  <permission android:name="scut.carson_ho.demo_mipush.permission.MIPUSH_RECEIVE" android:protectionLevel="signature" />  //注意這里.permission.MIPUSH_RECEIVE是自身app的包名  <uses-permission android:name="scut.carson_ho.demo_mipush.permission.MIPUSH_RECEIVE" />//注意要初始化BaseActivity.java類  <application    android:name=".BaseActivity"    android:allowBackup="true"    android:icon="@mipmap/ic_launcher"    android:label="@string/app_name"    android:supportsRtl="true"    android:theme="@style/AppTheme">    <activity android:name=".MainActivity">      <intent-filter>        <action android:name="android.intent.action.MAIN" />        <category android:name="android.intent.category.LAUNCHER" />      </intent-filter>    </activity>  //注冊(cè)廣播BroadcastReceiver和Service  //都是靜態(tài)注冊(cè),因?yàn)橐L(zhǎng)期處在后臺(tái)運(yùn)行  //注:共是3個(gè)廣播接收器和4個(gè)服務(wù),其中包括繼承了PushMessageReceiver的DemoMessageReceiver  //4個(gè)后臺(tái)服務(wù)  <service    android:enabled="true"    android:process=":pushservice"    android:name="com.xiaomi.push.service.XMPushService"/>  //此service必須在3.0.1版本以后(包括3.0.1版本)加入  <service    android:name="com.xiaomi.push.service.XMJobService"    android:enabled="true"    android:exported="false"    android:permission="android.permission.BIND_JOB_SERVICE"    android:process=":pushservice" />  //此service必須在2.2.5版本以后(包括2.2.5版本)加入  <service    android:enabled="true"    android:exported="true"    android:name="com.xiaomi.mipush.sdk.PushMessageHandler" />  <service android:enabled="true"    android:name="com.xiaomi.mipush.sdk.MessageHandleService" />  //3個(gè)廣播  <receiver    android:exported="true"    android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver" >    <intent-filter>      <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />      <category android:name="android.intent.category.DEFAULT" />    </intent-filter>  </receiver>  <receiver    android:exported="false"    android:process=":pushservice"    android:name="com.xiaomi.push.service.receivers.PingReceiver" >    <intent-filter>      <action android:name="com.xiaomi.push.PING_TIMER" />    </intent-filter>  </receiver>  //繼承了PushMessageReceiver的DemoMessageReceiver的廣播注冊(cè)  <receiver    android:name=".Mipush_Broadcast"    android:exported="true">    <intent-filter>      <action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE" />    </intent-filter>    <intent-filter>      <action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED" />    </intent-filter>    <intent-filter>      <action android:name="com.xiaomi.mipush.ERROR" />    </intent-filter>  </receiver>  </application></manifest>

步驟6:根據(jù)需要設(shè)置一系列的推送設(shè)置,如用戶別名、標(biāo)簽等等

  • 此處是簡(jiǎn)單Demo,所以不作過多的設(shè)置
  • 更多設(shè)置請(qǐng)回看上方官方Demo解析

運(yùn)行結(jié)果

測(cè)試成功結(jié)果

好了,客戶端的代碼寫好后,可以去小米官網(wǎng)測(cè)試一下消息推送了

步驟1:在小米官網(wǎng)的消息推送里選擇你創(chuàng)建的應(yīng)用,然后點(diǎn)擊“推送工具”

點(diǎn)擊推送工具

步驟2:設(shè)置推送消息的相關(guān)信息

可進(jìn)行的配置非常全面,基本上能滿足推送的需求

設(shè)置推送消息 

設(shè)置推送消息

推送的結(jié)果

消息到達(dá)客戶端

測(cè)試結(jié)果
測(cè)試結(jié)果:收到的信息

點(diǎn)擊通知欄消息后

4. Demo下載地址  demo

5. 關(guān)于對(duì)小米推送的思考(問題)

上述說的小米推送看似簡(jiǎn)單:初始化推送服務(wù) + 相關(guān)推送設(shè)置。但是,好的代碼不僅能在正常情況下工作,還應(yīng)該充分考慮失敗情況。那么,有什么樣的失敗情況需要我們考慮呢?

  • 背景:在這個(gè)初始化推送服務(wù)的過程中,是需要聯(lián)系小米推送的服務(wù)器來申請(qǐng)reg id(即推送token)。
  • 沖突:初始化過程可能失敗:網(wǎng)絡(luò)問題(沒網(wǎng)or網(wǎng)絡(luò)信號(hào)弱)、服務(wù)器問題導(dǎo)致初始化失敗。那么,當(dāng)失敗以后,該什么時(shí)候再次進(jìn)行初始化呢?
  • 解決方案:在初始化失敗的情況下提供重試機(jī)制,直到初始化成功(可以通過檢測(cè)是否已經(jīng)拿到推送token來確定),問題解決的邏輯如下:

解決邏輯

總結(jié)

全面考慮到所有異常問題并恰當(dāng)?shù)剡M(jìn)行處理才能真正體現(xiàn)程序猿的功力,希望大家做擼代碼的時(shí)候不要只做代碼的搬運(yùn)工,純粹寫代碼并不會(huì)讓你成長(zhǎng),關(guān)鍵在于思考。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 辽中县| 天镇县| 金沙县| 拜城县| 罗江县| 称多县| 昆山市| 英吉沙县| 桃园市| 前郭尔| 嘉定区| 龙岩市| 五寨县| 黔西| 荔浦县| 甘谷县| 元氏县| 宁明县| 崇礼县| 江北区| 大方县| 福海县| 吉木乃县| 奉化市| 镇康县| 承德市| 赤城县| 瓦房店市| 利津县| 项城市| 湘潭县| 沐川县| 石首市| 乌拉特后旗| 南部县| 汉川市| 钦州市| 绵阳市| 博兴县| 施秉县| 田东县|