Android 集成华为推送 push

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lhk147852369/article/details/82979928

由于项目需要我们不得不对华为push进行研究。

按照国际惯例先百度一波,发现各个大牛都是对于华为push的填坑,很明显,这个推送的问题还是有很多的。

这里引用:Android集成华为推送踩坑问题总结

  1. 使用老版push还是新版push
  2. PushReceiver中的onEvent()回调触发问题
  3. APP接收到推送后,点击消息,总是会先打开启动页
  4. 如何自定义动作intent

如何解决请跳转链接查看详细内容。


关于华为推送的注意点:

支持NC功能的手机:部分EMUI4.0和4.1的手机,以及EMUI5.0及之后的华为手机。 

是否接受通知栏消息:当是中国大陆地区的华为手机,必须满足EMUI版本不低于EMUI5.1
当是海外地区的华为手机或者非华为品牌手机,则必须满足华为移动服务的版本不低于2.5.0

针对以上:

//判断EMUI 大于 等于 12  相当于5.1
int emuiApiLevel = 0;            
        try {            
            Class cls = Class.forName("android.os.SystemProperties");            
            Method method = cls.getDeclaredMethod("get", new Class[]{String.class});            
            emuiApiLevel = Integer.parseInt((String) method.invoke(cls, new Object[]{"ro.build.hw_emui_api_level"}));            
        } catch (Exception e) {            
            e.printStackTrace();            
        }        

//判断服务版本 大于等于 250  
PackageInfo pi = null;            
        PackageManager pm = context.getPackageManager();            
        int hwid = 0;            
        try {            
            pi = pm.getPackageInfo("com.huawei.hwid", 0);            
            if (pi != null) {            
                result = pi.versionCode;            
            }            
        } catch (PackageManager.NameNotFoundException e) {            
            e.printStackTrace();            
        }        

一、注册华为开发者联盟账号 右上角进入管理中心

申请push服务 创建应用。

注意:

SHA256证书指纹1  此证书需要打包你的apk (放在根目录 方便)然后在Terminal 中输入

keytool -v -list -keystore  名称.jks 

输入密码后 即可查看

二、为了每次不用我们打包后安装

File -> project Structure -> app -> Signing 添加我们创建的jks

-> Build Types -> debug ->Signing Config 选择刚才创建的jks 就好。

有时候我们会忽略这一点 以至于 每次都会 6003  告诉我们 签名有问题

大家注意一下就好。

三、开发集成

下载Sdk

HMS Agent套件  HMSAgent_2.6.1.302.zip

解压后点击 GetHMSAgent_cn.bat

按照提示 输入相关内容 没有 直接Enter 就好

然后找到copysrc文件夹 将java 文件夹中的所有内容 拷贝到你的项目里

目录请看下图  com下  dak 是我项目的包名

然后放入 华为的Agent 套件  

注意: 目录一定要相对应

然后把AppManifestConfig.xml 中内容 放入到AndroidManifest.xml 中。

有一个标红点 需要放入一个Receiver 

我们把华为官方的simple中 HuaweiPushRevicer 拿过来就好了。

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<IPushCallback> pushCallbacks = new ArrayList<IPushCallback>();
    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) {
        Log.e("onToken:", tokenIn);

        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) {

        Log.e("onPushMsg:", "接收消息");
        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) {
        Log.e("onEvent:", "事件");
        Intent intent = new Intent();
        intent.setAction(ACTION_UPDATEUI);

        int notifyId = 0;
        if (Event.NOTIFICATION_OPENED.equals(event) || Event.NOTIFICATION_CLICK_BTN.equals(event)) {
            notifyId = extras.getInt(BOUND_KEY.pushNotifyId, 0);
            if (0 != notifyId) {
                NotificationManager manager = (NotificationManager) context
                        .getSystemService(Context.NOTIFICATION_SERVICE);
                manager.cancel(notifyId);
            }
        }

        String message = extras.getString(BOUND_KEY.pushMsgKey);
        intent.putExtra("log", "Received event,notifyId:" + notifyId + " msg:" + message);
        callBack(intent);
        super.onEvent(context, event, extras);
    }

    @Override
    public void onPushState(Context context, boolean pushState) {
        Log.e("onPushState:", "接收状态");
        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);
                }
            }
        }
    }
}

注意不要混乱。

在project build.gradle 中添加  maven {url 'http://developer.huawei.com/repo/'}

在module build.gradle 中添加 如下

// 此处版本号仅为示例,请手动修改成实际集成的HMSSDK版本号

String HMSSDKVer ='2.6.1.301'

compile 'com.huawei.android.hms:iap:'+HMSSDKVer

compile 'com.huawei.android.hms:game:'+HMSSDKVer

compile 'com.huawei.android.hms:sns:'+HMSSDKVer

compile 'com.huawei.android.hms:hwid:'+HMSSDKVer

compile 'com.huawei.android.hms:push:'+HMSSDKVer

compile 'com.huawei.android.hms:opendevice:'+HMSSDKVer 

需要哪个添加哪个就好。 Sync Now 一下

查看Agent 套件 是否还继续报错。

如果报错 看下是否少添加了内容

值得一提:

resConfigs "en", "zh-rCN","其他应用需要支持的语言"

确认项目需求是否需要 。

四、代码内容

在Application 的 onCreate 中 初始化套件  

HMSAgent.init(this);

在第一个Activity 中连接  我在Main中

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity:";

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


        connectHMSAgent();


        Button button = findViewById(R.id.btn_push);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this,PushActivity.class));
            }
        });
    }

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

}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.dak.administrator.hwpushsimple.MainActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="跳转push"
        android:id="@+id/btn_push"
        />

</LinearLayout>

以下是 官方simple 中测试 Activity  我只拿了 push 部份 可以用来测试

public class PushActivity extends AppCompatActivity implements HuaweiPushRevicer.IPushCallback, View.OnClickListener {

    private String token;

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

        Button btn = (Button) findViewById(R.id.btn_push);
        if (btn != null) {
            btn.setTextColor(Color.RED);
            btn.setEnabled(false);
        }

        findViewById(R.id.btn_gettoken).setOnClickListener(this);
        findViewById(R.id.btn_deletetoken).setOnClickListener(this);
        findViewById(R.id.btn_getpushstatus).setOnClickListener(this);
        findViewById(R.id.btn_setnormal).setOnClickListener(this);
        findViewById(R.id.btn_setnofify).setOnClickListener(this);
        findViewById(R.id.btn_agreement).setOnClickListener(this);

        registerBroadcast();
    }

    /**
     * 获取token | get push token
     */
    private void getToken() {
        showLog("get token: begin");
        HMSAgent.Push.getToken(new GetTokenHandler() {
            @Override
            public void onResult(int rtnCode) {
                showLog("get token: end code=" + rtnCode);
            }
        });

    }

    /**
     * 删除token | delete push token
     */
    private void deleteToken(){
        showLog("deleteToken:begin");
        HMSAgent.Push.deleteToken(token, new DeleteTokenHandler() {
            @Override
            public void onResult(int rst) {
                showLog("deleteToken:end code=" + rst);
            }
        });
    }

    /**
     * 获取push状态 | Get Push State
     */
    private void getPushStatus() {
        showLog("getPushState:begin");
        HMSAgent.Push.getPushState(new GetPushStateHandler() {
            @Override
            public void onResult(int rst) {
                showLog("getPushState: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);
            }
        });
    }

    /**
     * 设置接收通知消息 | Set up receive notification messages
     * 注意:当是中国大陆地区的华为手机,必须满足EMUI版本不低于EMUI5.1
     * 当是海外地区的华为手机或者非华为品牌手机,则必须满足华为移动服务的版本不低于2.5.0。
     * @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);
            }
        });
    }

    /**
     * 显示push协议 | Show Push protocol
     */
    private void showAgreement(){
        showLog("queryAgreement:begin");
        HMSAgent.Push.queryAgreement(new QueryAgreementHandler() {
            @Override
            public void onResult(int rst) {
                showLog("queryAgreement:end code=" + rst);
            }
        });
    }

    /**
     * Called when a view has been clicked.
     *
     * @param v The view that was clicked.
     */
    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.btn_push) {
            // 本页面切换到本页面的按钮事件不处理 | "This page switches to itself" button event does not need to be handled
            return;
        } else {
            // 如果不是tab切换按钮则处理业务按钮事件 | Handle Business button events without the TAB toggle button
            switch (id) {
                case R.id.btn_gettoken:
                    getToken();
                    break;
                case R.id.btn_deletetoken:
                    deleteToken();
                    break;
                case R.id.btn_getpushstatus:
                    getPushStatus();
                    break;
                case R.id.btn_setnormal:
                    setReceiveNormalMsg(true);
                    break;
                case R.id.btn_setnofify:
                    setReceiveNotifyMsg(true);
                    break;
                case R.id.btn_agreement:
                    showAgreement();
                    break;
                default:
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        HuaweiPushRevicer.unRegisterPushCallback(this);;
    }

    /**
     * 以下代码为sample自身逻辑,和业务能力不相关
     * 作用仅仅为了在sample界面上显示push相关信息
     */
    private void registerBroadcast() {
        HuaweiPushRevicer.registerPushCallback(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);
            } else if (b != null && ACTION_UPDATEUI.equals(action)) {
                String log = b.getString("log");
                showLog(log);
            }
        }
    }

    StringBuffer sbLog = new StringBuffer();
    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);
                }
            }
        });
    }
    //如何判断EMUI版本>=4.1
    private boolean isSwitchEnable(){
        int emuiApiLevel = 0;
        try {
            Class cls = Class.forName("android.os.SystemProperties");
            Method method = cls.getDeclaredMethod("get", new Class[]{String.class});
            emuiApiLevel = Integer.parseInt((String) method.invoke(cls, new Object[]{"ro.build.hw_emui_api_level"}));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return emuiApiLevel > 5.0;
    }
}

push.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFF">

    <include
        android:id="@+id/layout_commom"
        layout="@layout/layout_head"/>

    <LinearLayout
        android:id="@+id/layout_first"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/layout_commom"
        android:orientation="horizontal">
        <Button
            android:id="@+id/btn_gettoken"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="获取token"/>
        <Button
            android:id="@+id/btn_deletetoken"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="删除token"/>

    </LinearLayout>

    <LinearLayout
        android:id="@+id/layout_second"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/layout_first"
        android:orientation="horizontal">
        <Button
            android:id="@+id/btn_setnormal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="切换普通消息开关"/>
        <Button
            android:id="@+id/btn_setnofify"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="切换通知消息开关"/>

    </LinearLayout>

    <LinearLayout
        android:id="@+id/layout_third"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/layout_second"
        android:orientation="horizontal">
        <Button
            android:id="@+id/btn_agreement"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="协议"/>
        <Button
            android:id="@+id/btn_getpushstatus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="获取push状态"/>
    </LinearLayout>

    <ScrollView
        android:id="@+id/sv_log"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/layout_third">
        <TextView
            android:id="@+id/tv_log"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:textColor="#000000"
            android:paddingBottom="30dip"
            android:text="日志显示区:" />
    </ScrollView>

</RelativeLayout>

head.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:background="#FFFFFF"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/btn_game"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/button_color"
            android:minWidth="60dp"
            android:text="游戏"/>
        <Button
            android:id="@+id/btn_iap"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/button_color"
            android:minWidth="60dp"
            android:text="支付"/>
        <Button
            android:id="@+id/btn_id"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/button_color"
            android:minWidth="60dp"
            android:text="帐号"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/btn_sns"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/button_color"
            android:minWidth="60dp"
            android:text="社交"/>
        <Button
            android:id="@+id/btn_push"
            android:includeFontPadding="false"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/button_color"
            android:minWidth="60dp"
            android:text="push"/>
        <Button
            android:id="@+id/btn_opendevice"
            android:includeFontPadding="false"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/button_color"
            android:minWidth="60dp"
            android:text="开放设备id"/>
    </LinearLayout>

</LinearLayout>

ok 大功告成。

由于我在获取token的时候没有返回值。

提单后告知 我小米手机 下载的最新华为移动服务 不支持。 也就没测试了。 很难受。 

不过 以上方法 经过我多方验证,把或许会犯错的点已经 考虑了很多。

希望大家可以使用到。

推荐一个连接:

华为推送 超级多问题 都在这里 。

微访谈: push 总结

官方Sample下载地址

猜你喜欢

转载自blog.csdn.net/lhk147852369/article/details/82979928