Android集成Huawei PUSH(四)——客户端开发

一、华为Push功能描述

集成 Huawei PUSH 服务开发主要包括两部分:客户端开发和服务端开发。具体的流程可参照下图
(图片来源:Huawei PUSH 官方文档)


客户端开发的主要目的是为了向PUSH服务器获取设备的PUSH Token,获取Token之后开发者可以在开发者联盟PUSH控制台或者开发者自己的服务器上根据Token向这些设备发送推送消息。
开发者联盟PUSH控制台链接:https://developer.huawei.com/consumer/cn/console#/openCard/AppService/6

说明:
①华为手机申请Token的流程:(图片来源:Huawei PUSH 官方文档)


②非华为手机申请Token的流程:(图片来源:Huawei PUSH 官方文档)

-----------------------------------------------------------------------------------------

二、初始化Agent

具体步骤如下:

1.调用init,在application的onCreate方法中初始化HMS Agent套件。
说明:查找application文件的方法:在Manifest.xml中的application节点中的name属性即为application文件的路径


示例代码:

public class MyApplication extends Application {        @Override        public void onCreate() {                        super.onCreate();                HMSAgent.init(this);        }}       

2.调用connect
在应用启动后的首个Activity的OnCreate方法中调用connect接口,确保HMS SDK 和HMS APK的连接。

示例代码:

HMSAgent.connect(this, new ConnectHandler() {    @Override    public void onConnect(int rst) {        showLog("HMS connect end:" + rst);    }});   

3.申请Token
建议开发者在首个Activity的onCreate方法中调用getToken方法,同一个手机的同一个应用获取的Token不会变,但是建议每次启动更新一次PUSH token。调用getToken接口后,Token不是在本接口中直接返回的,而是通过广播的形式通知APP因此需要开发者实现自定义广播的onToken方法来接收Token。

示例代码:

private void getToken() {    showLog("get token: begin");    HMSAgent.Push.getToken(new GetTokenHandler() {        @Override        public void onResult(int rtnCode, TokenResult tokenResult) {            showLog("get token: end" + rtnCode);        }    }); }    

注意:获取Token的时候经常会返回错误码6003,原因是证书指纹校验错误,此时解决该问题的方法有两个:一是使用Keystore文件将项目打包成apk,二是在子项目的gradle文件中signingConfigs修改成如下信息:

signingConfigs {        release {            keyAlias 'keystore.keystore'            keyPassword 'trechina'            storeFile file('../keystore.keystore')            storePassword 'trechina'        }        debug {            keyAlias 'keystore.keystore'            keyPassword 'trechina'            storeFile file('../keystore.keystore')            storePassword 'trechina'        }    }

-----------------------------------------------------------------------------------------

三、实现自定义广播接收消息

开发者需要创建子类继承com.huawei.hms.support.api.push.PushReceiver,实现onToken,onPushMsg,onEvent这几个方法,用于接收Token返回,透传消息和通知栏点击事件处理。具体步骤如下:

注意: onEvent会在后续版本中逐渐废弃,请开发者谨慎使用,建议开发者创建两个子类继承PushReceiver类,分别实现onToken,onPushMsg和onEvent的处理。

1.自定义HuaweiPushReceiver类继承PushReceiver类,用于实现对于PUSH Token和透传消息的接收

示例代码:

public class HuaweiPushReceiver extends PushReceiver {    @Override    public void onToken(Context context, String token, Bundle extras) {    }    @Override    public boolean onPushMsg(Context context, byte[] msg, Bundle bundle) {    }     }    

onToken方法:返回Token信息
onPushMsg方法:返回透传信息

2.开发者自定义HuaweiPushRevicerEx类继承PushReceiver,实现接收通知栏或通知栏上按钮点击事件的onEvent回调
注意:后续版本逐渐废弃,请开发者谨慎使用

示例代码:

public class HuaweiPushReceiverEx extends PushReceiver {    @Override    public void onEvent(Context context, Event event, Bundle extras) {    }}   

onEvent方法:点击打开通知栏消息、点击通知栏上的按钮之后被调用

4.在application节点下增加AppUpdateActivity和PackageInstallActivity,用来是应用自升级接口所需要使用的页面

    

-----------------------------------------------------------------------------------------

四、设定是否接收PUSH通知栏消息

如果开发者不调用此方法,默认是接收通知栏消息。

示例代码:

private void setReceiveNotifyMsg(boolean enable){        showLog("enableReceiveNotifyMsg:begin");        HMSAgent.Push.enableReceiveNotifyMsg(enable, new EnableReceiveNotifyMsgHandler() {            @Override            public void onResult(int rst) {                showLog("enableReceiveNotifyMsg:end code=" + rst);            }        });    }    

-----------------------------------------------------------------------------------------

五、设定是否接收PUSH透传消息

如果开发者不调用此方法,默认是接收透传消息。

示例代码:

private void setReceiveNormalMsg(boolean enable){        showLog("enableReceiveNormalMsg:begin");        HMSAgent.Push.enableReceiveNormalMsg(enable, new EnableReceiveNormalMsgHandler() {            @Override            public void onResult(int rst) {                showLog("enableReceiveNormalMsg:end code=" + rst);            }        });    } 

客户端的其他方法,比如删除PUSH Token、展示角标等,可以参照:https://developer.huawei.com/consumer/cn/service/hms/catalog/huaweipush_agent.html?page=hmssdk_huaweipush_devguide_client_agent

-----------------------------------------------------------------------------------------

六、示例代码(透传消息)

MainActivity.java:

import static com.example.testpush.HuaweiPushRevicer.ACTION_TOKEN;import static com.example.testpush.HuaweiPushRevicer.ACTION_UPDATEUI;public class MainActivity extends AppCompatActivity implements HuaweiPushRevicer.IPushCallback {    private String token;    StringBuffer sbLog = new StringBuffer();        @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        HMSAgent.connect(this, new ConnectHandler() {            @Override            public void onConnect(int rst) {                showLog("HMS connect end:" + rst);            }        });        getToken();        HuaweiPushRevicer.registerPushCallback(this);        setReceiveNotifyMsg(true);        setReceiveNormalMsg(true);        Log.d("****Token****",token+"");        showLog(token);                Intent intent = new Intent();        intent.setClass(MainActivity.this, MainActivity.class);        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        intent.putExtra("ext1","helloExt1");        intent.putExtra("ext2","helloExt2");        String intentUri = intent.toUri(Intent.URI_INTENT_SCHEME);        Log.e("onCreate: ",intentUri );        Toast.makeText(this,getIntent().getStringExtra("ext1"),Toast.LENGTH_SHORT).show();    }        /**     * 获取token     */    private void getToken() {        showLog("get token: begin");        HMSAgent.Push.getToken(new GetTokenHandler() {            @Override            public void onResult(int rtnCode) {                showLog("get token: end" + rtnCode);            }        });    }        /**     * 设置接收通知消息 | Set up receive notification messages     * @param enable 是否开启 | enabled or not     */    private void setReceiveNotifyMsg(boolean enable){        showLog("enableReceiveNotifyMsg:begin");        HMSAgent.Push.enableReceiveNotifyMsg(enable, new EnableReceiveNotifyMsgHandler() {            @Override            public void onResult(int rst) {                showLog("enableReceiveNotifyMsg:end code=" + rst);            }        });    }        /**     * 设置是否接收普通透传消息 | Set whether to receive normal pass messages     * @param enable 是否开启 | enabled or not     */    private void setReceiveNormalMsg(boolean enable){        showLog("enableReceiveNormalMsg:begin");        HMSAgent.Push.enableReceiveNormalMsg(enable, new EnableReceiveNormalMsgHandler() {            @Override            public void onResult(int rst) {                showLog("enableReceiveNormalMsg:end code=" + rst);            }        });    }    protected void showLog(String logLine) {        DateFormat format = new java.text.SimpleDateFormat("MMddhhmmssSSS");        String time = format.format(new Date());        sbLog.append(time+":"+logLine);        sbLog.append('\n');        new Handler(Looper.getMainLooper()).post(new Runnable() {            @Override            public void run() {                View vText = findViewById(R.id.tv_log);                if (vText != null && vText instanceof TextView) {                    TextView tvLog = (TextView)vText;                    tvLog.setText(sbLog.toString());                }                View vScrool = findViewById(R.id.sv_log);                if (vScrool != null && vScrool instanceof ScrollView) {                    ScrollView svLog = (ScrollView)vScrool;                    svLog.fullScroll(View.FOCUS_DOWN);                }            }        });    }        @Override    protected void onDestroy() {        super.onDestroy();        HuaweiPushRevicer.unRegisterPushCallback(this);        ;    }    @Override    public void onReceive(Intent intent) {        if (intent != null) {            String action = intent.getAction();            Bundle b = intent.getExtras();            if (b != null && ACTION_TOKEN.equals(action)) {                token = b.getString(ACTION_TOKEN);                Log.d("****Token****",token+"");                showLog(token);                showLog(intent.getStringExtra("aa"));            } else if (b != null && ACTION_UPDATEUI.equals(action)) {                String log = b.getString("log");                showLog(log);                Log.d("****Token****",token+"");                showLog(token);            }        }    }}

HuaweiPushRevicer.java:

public class HuaweiPushRevicer extends PushReceiver {public static final String TAG = "HuaweiPushRevicer";public static final String ACTION_UPDATEUI = "action.updateUI";    public static final String ACTION_TOKEN = "action.updateToken";    private static List pushCallbacks = new ArrayList();    private static final Object CALLBACK_LOCK = new Object();    public interface IPushCallback {        void onReceive(Intent intent);    }    public static void registerPushCallback(IPushCallback callback) {        synchronized (CALLBACK_LOCK) {            pushCallbacks.add(callback);        }    }    public static void unRegisterPushCallback(IPushCallback callback) {        synchronized (CALLBACK_LOCK) {            pushCallbacks.remove(callback);        }    }    @Override    public void onToken(Context context, String tokenIn, Bundle extras) {    String belongId = extras.getString("belongId");        Intent intent = new Intent();        intent.setAction(ACTION_TOKEN);        intent.putExtra(ACTION_TOKEN, tokenIn);        callBack(intent);        intent = new Intent();        intent.setAction(ACTION_UPDATEUI);        intent.putExtra("log", "belongId is:" + belongId + " Token is:" + tokenIn);        callBack(intent);    }    @Override    public boolean onPushMsg(Context context, byte[] msg, Bundle bundle) {        try {        //CP可以自己解析消息内容,然后做相应的处理 | CP can parse message content on its own, and then do the appropriate processing            String content = new String(msg, "UTF-8");            Intent intent = new Intent();            intent.setAction(ACTION_UPDATEUI);            intent.putExtra("log", "Receive a push pass message with the message:" + content);            callBack(intent);        } catch (Exception e) {            Intent intent = new Intent();            intent.setAction(ACTION_UPDATEUI);            intent.putExtra("log", "Receive push pass message, exception:" + e.getMessage());            callBack(intent);        }        return false;    }    public void onEvent(Context context, Event event, Bundle extras) {           }    @Override    public void onPushState(Context context, boolean pushState) {        Intent intent = new Intent();        intent.setAction(ACTION_UPDATEUI);        intent.putExtra("log", "The Push connection status is:" + pushState);        callBack(intent);    }    private static void callBack(Intent intent) {        synchronized (CALLBACK_LOCK) {            for (IPushCallback callback : pushCallbacks) {                if (callback != null) {                    callback.onReceive(intent);                }            }        }    }}

-----------------------------------------------------------------------------------------

七、示例代码(通知栏——直接打开应用)

MainActivity.java:

import static com.example.testpush.HuaweiPushRevicer.ACTION_TOKEN;import static com.example.testpush.HuaweiPushRevicer.ACTION_UPDATEUI;public class MainActivity extends AppCompatActivity implements HuaweiPushRevicer.IPushCallback {    private String token;    StringBuffer sbLog = new StringBuffer();        @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        HMSAgent.connect(this, new ConnectHandler() {            @Override            public void onConnect(int rst) {                showLog("HMS connect end:" + rst);            }        });        getToken();        HuaweiPushRevicer.registerPushCallback(this);        setReceiveNotifyMsg(true);        setReceiveNormalMsg(true);        Log.d("****Token****",token+"");        showLog(token);    }        /**     * 获取token     */    private void getToken() {        showLog("get token: begin");        HMSAgent.Push.getToken(new GetTokenHandler() {            @Override            public void onResult(int rtnCode) {                showLog("get token: end" + rtnCode);            }        });    }        /**     * 设置接收通知消息 | Set up receive notification messages     * @param enable 是否开启 | enabled or not     */    private void setReceiveNotifyMsg(boolean enable){        showLog("enableReceiveNotifyMsg:begin");        HMSAgent.Push.enableReceiveNotifyMsg(enable, new EnableReceiveNotifyMsgHandler() {            @Override            public void onResult(int rst) {                showLog("enableReceiveNotifyMsg:end code=" + rst);            }        });    }        /**     * 设置是否接收普通透传消息 | Set whether to receive normal pass messages     * @param enable 是否开启 | enabled or not     */    private void setReceiveNormalMsg(boolean enable){        showLog("enableReceiveNormalMsg:begin");        HMSAgent.Push.enableReceiveNormalMsg(enable, new EnableReceiveNormalMsgHandler() {            @Override            public void onResult(int rst) {                showLog("enableReceiveNormalMsg:end code=" + rst);            }        });    }    protected void showLog(String logLine) {        DateFormat format = new java.text.SimpleDateFormat("MMddhhmmssSSS");        String time = format.format(new Date());        sbLog.append(time+":"+logLine);        sbLog.append('\n');        new Handler(Looper.getMainLooper()).post(new Runnable() {            @Override            public void run() {                View vText = findViewById(R.id.tv_log);                if (vText != null && vText instanceof TextView) {                    TextView tvLog = (TextView)vText;                    tvLog.setText(sbLog.toString());                }                View vScrool = findViewById(R.id.sv_log);                if (vScrool != null && vScrool instanceof ScrollView) {                    ScrollView svLog = (ScrollView)vScrool;                    svLog.fullScroll(View.FOCUS_DOWN);                }            }        });    }        @Override    protected void onDestroy() {        super.onDestroy();        HuaweiPushRevicer.unRegisterPushCallback(this);        ;    }    @Override    public void onReceive(Intent intent) {        if (intent != null) {            String action = intent.getAction();            Bundle b = intent.getExtras();            if (b != null && ACTION_TOKEN.equals(action)) {                token = b.getString(ACTION_TOKEN);                Log.d("****Token****",token+"");                showLog(token);                showLog(intent.getStringExtra("aa"));            } else if (b != null && ACTION_UPDATEUI.equals(action)) {                String log = b.getString("log");                showLog(log);                Log.d("****Token****",token+"");                showLog(token);            }        }    }}

HuaweiPushRevicer.java:

public class HuaweiPushReceiver extends PushReceiver {    //HuaweiPushRevicer类继承PushReceiver,实现PUSH Token和透传消息的接收public static final String TAG = "HuaweiPushReceiver";public static final String ACTION_UPDATEUI = "action.updateUI";    public static final String ACTION_TOKEN = "action.updateToken";    //定义用于保存接口对象的列表    private static List pushCallbacks = new ArrayList();    private static final Object CALLBACK_LOCK = new Object();    //定义IPushCallback接口用于回传Token信息    public interface IPushCallback {        void onReceive(Intent intent);    }    public static void registerPushCallback(IPushCallback callback) {        synchronized (CALLBACK_LOCK) {            pushCallbacks.add(callback);        }    }    public static void unRegisterPushCallback(IPushCallback callback) {        synchronized (CALLBACK_LOCK) {            pushCallbacks.remove(callback);        }    }    @Override    public void onToken(Context context, String tokenIn, Bundle extras) {        //onToken 调用getToken方法后,获取服务端返回的token结果,返回token以及belongId    String belongId = extras.getString("belongId");        Intent intent = new Intent();        intent.setAction(ACTION_TOKEN);        intent.putExtra(ACTION_TOKEN, tokenIn);        callBack(intent);  //返回Token信息        intent = new Intent();        intent.setAction(ACTION_UPDATEUI);        intent.putExtra("log", "belongId is:" + belongId + " Token is:" + tokenIn);        callBack(intent);  //返回日志信息    }        @Override    public boolean onPushMsg(Context context, byte[] msg, Bundle bundle) {        return true;    }    public void onEvent(Context context, Event event, Bundle extras) {           }    @Override    public void onPushState(Context context, boolean pushState) {        //调用getPushState方法后,获取push连接状态的查询结果        Intent intent = new Intent();        intent.setAction(ACTION_UPDATEUI);        intent.putExtra("log", "The Push connection status is:" + pushState);        callBack(intent);    }    private static void callBack(Intent intent) {        synchronized (CALLBACK_LOCK) {            for (IPushCallback callback : pushCallbacks) {                if (callback != null) {                    callback.onReceive(intent);  //执行接口对象的onReceive方法                }            }        }    }}

-----------------------------------------------------------------------------------------

八、示例代码(通知栏——自定义Intent)

自定义Intent为:intent://com.huawei.pushtest/notify_detail#Intent;scheme=customscheme;launchFlags=0x10000000;S.package=test;end

MainActivity.java:

import static com.example.estpush.HuaweiPushRevicer.ACTION_TOKEN;import static com.example.testpush.HuaweiPushRevicer.ACTION_UPDATEUI;public class MainActivity extends AppCompatActivity implements HuaweiPushRevicer.IPushCallback {    private String token;    StringBuffer sbLog = new StringBuffer();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        HMSAgent.connect(this, new ConnectHandler() {            @Override            public void onConnect(int rst) {                showLog("HMS connect end:" + rst);            }        });        getToken();        HuaweiPushRevicer.registerPushCallback(this);        setReceiveNotifyMsg(true);        setReceiveNormalMsg(true);if("test".equals(getIntent().getStringExtra("package"))){            //开发者自己写逻辑        }    }    /**     * 获取token     */    private void getToken() {        showLog("get token: begin");        HMSAgent.Push.getToken(new GetTokenHandler() {            @Override            public void onResult(int rtnCode) {                showLog("get token: end" + rtnCode);            }        });    }    /**     * 设置接收通知消息 | Set up receive notification messages     * @param enable 是否开启 | enabled or not     */    private void setReceiveNotifyMsg(boolean enable){        showLog("enableReceiveNotifyMsg:begin");        HMSAgent.Push.enableReceiveNotifyMsg(enable, new EnableReceiveNotifyMsgHandler() {            @Override            public void onResult(int rst) {                showLog("enableReceiveNotifyMsg:end code=" + rst);            }        });    }    /**     * 设置是否接收普通透传消息 | Set whether to receive normal pass messages     * @param enable 是否开启 | enabled or not     */    private void setReceiveNormalMsg(boolean enable){        showLog("enableReceiveNormalMsg:begin");        HMSAgent.Push.enableReceiveNormalMsg(enable, new EnableReceiveNormalMsgHandler() {            @Override            public void onResult(int rst) {                showLog("enableReceiveNormalMsg:end code=" + rst);            }        });    }    protected void showLog(String logLine) {        DateFormat format = new java.text.SimpleDateFormat("MMddhhmmssSSS");        String time = format.format(new Date());        sbLog.append(time+":"+logLine);        sbLog.append('\n');        new Handler(Looper.getMainLooper()).post(new Runnable() {            @Override            public void run() {                View vText = findViewById(R.id.tv_log);                if (vText != null && vText instanceof TextView) {                    TextView tvLog = (TextView)vText;                    tvLog.setText(sbLog.toString());                }                View vScrool = findViewById(R.id.sv_log);                if (vScrool != null && vScrool instanceof ScrollView) {                    ScrollView svLog = (ScrollView)vScrool;                    svLog.fullScroll(View.FOCUS_DOWN);                }            }        });    }    @Override    protected void onDestroy() {        super.onDestroy();        HuaweiPushRevicer.unRegisterPushCallback(this);        ;    }    @Override    public void onReceive(Intent intent) {        if (intent != null) {            String action = intent.getAction();            Bundle b = intent.getExtras();            if (b != null && ACTION_TOKEN.equals(action)) {                token = b.getString(ACTION_TOKEN);                Log.d("****Token****",token+"");                showLog(token);                showLog(intent.getStringExtra("aa"));            } else if (b != null && ACTION_UPDATEUI.equals(action)) {                String log = b.getString("log");                showLog(log);                Log.d("****Token****",token+"");                showLog(token);            }        }    }}

HuaweiPushRevicer.java:

public class HuaweiPushReceiver extends PushReceiver {    //HuaweiPushRevicer类继承PushReceiver,实现PUSH Token和透传消息的接收public static final String TAG = "HuaweiPushReceiver";public static final String ACTION_UPDATEUI = "action.updateUI";    public static final String ACTION_TOKEN = "action.updateToken";    //定义用于保存接口对象的列表    private static List pushCallbacks = new ArrayList();    private static final Object CALLBACK_LOCK = new Object();    //定义IPushCallback接口用于回传Token信息    public interface IPushCallback {        void onReceive(Intent intent);    }    public static void registerPushCallback(IPushCallback callback) {        synchronized (CALLBACK_LOCK) {            pushCallbacks.add(callback);        }    }    public static void unRegisterPushCallback(IPushCallback callback) {        synchronized (CALLBACK_LOCK) {            pushCallbacks.remove(callback);        }    }    @Override    public void onToken(Context context, String tokenIn, Bundle extras) {        //onToken 调用getToken方法后,获取服务端返回的token结果,返回token以及belongId    String belongId = extras.getString("belongId");        Intent intent = new Intent();        intent.setAction(ACTION_TOKEN);        intent.putExtra(ACTION_TOKEN, tokenIn);        callBack(intent);  //返回Token信息        intent = new Intent();        intent.setAction(ACTION_UPDATEUI);        intent.putExtra("log", "belongId is:" + belongId + " Token is:" + tokenIn);        callBack(intent);  //返回日志信息    }    @Override    public boolean onPushMsg(Context context, byte[] msg, Bundle bundle) {       return true;    }    public void onEvent(Context context, Event event, Bundle extras) {            }    @Override    public void onPushState(Context context, boolean pushState) {        //调用getPushState方法后,获取push连接状态的查询结果        Intent intent = new Intent();        intent.setAction(ACTION_UPDATEUI);        intent.putExtra("log", "The Push connection status is:" + pushState);        callBack(intent);    }    private static void callBack(Intent intent) {        synchronized (CALLBACK_LOCK) {            for (IPushCallback callback : pushCallbacks) {                if (callback != null) {                    callback.onReceive(intent);  //执行接口对象的onReceive方法                }            }        }    }

-----------------------------------------------------------------------------------------

附录

客户端开发过程中错误码及解决方法请参照:https://developer.huawei.com/consumer/cn/service/hms/catalog/huaweipush_agent.html?page=hmssdk_huaweipush_api_reference_errorcode

更多相关文章

  1. android中跨进程通讯的4种方式
  2. android 提升性能总结
  3. android 生命周期复习1
  4. android架构层次了解及涉及技术归纳
  5. android实用测试方法之Monkey与MonkeyRunner
  6. 四大组件之服务(Service)
  7. Java笔记:[反射篇] 利用反射,获取类中的私有内部类对象,并调用该对
  8. 修改Android(安卓)Media Scanner的扫描路径
  9. Android(安卓)HAL实例解析

随机推荐

  1. Android反编译工具
  2. android Activity 和 Service 之间 传参
  3. android 全面屏适配方案
  4. android 中的实现加水印
  5. 编写第一个Android程序
  6. Matisse Android(安卓)图片选择器
  7. Ubuntu 14.04 连接Android 手机(三星note
  8. Android添加半透明操作提示的方法
  9. Android学习--使用url访问网络资源
  10. android 9.0 获取U盘路径