全部产品
云市场

Android接入手册

更新时间:2019-12-09 10:30:04

1. SDK依赖配置

环境准备:

通过gradle使用推送相关SDK需要配置仓库信息,在EMAS平台上进行构建和模块管理需要接入emas gradle插件。

SDK仓库和对接EMAS平台插件接入请参考以下文档的2.2-2.3章节:https://help.aliyun.com/document_detail/87884.html

gradle依赖:

  1. compile('com.taobao.android:accs_sdk_taobao:3.3.6.12-open') {
  2. exclude group: 'com.taobao.android', module: 'networksdk'
  3. transitive true
  4. }
  5. compile 'com.taobao.android:accs-xiaomi:1.0.9' //可选
  6. compile 'com.taobao.android:accs-huawei:1.1.3' //可选
  7. compile 'com.taobao.android:accs-oppo:1.0.3' //可选
  8. compile('com.taobao.android:accs-meizu:1.0.6') { //可选
  9. transitive false
  10. }
  11. compile 'com.taobao.android:meizu-push:3.8.1@aar' //可选

2. 接入准备

2.1 环境配置

需要向EMAS平台获取appkey、appsecret、推送域名等信息。可从平台上下载的脚手架工程中配置文件:aliyun-emas-services.json获取相关配置信息。

  1. {
  2. "private_cloud_config":{
  3. "AppKey": "10000021",
  4. "AppSecret": "f7bd9a1adabacebfc1edf933ff1c020d",
  5. ...
  6. "ACCS":{
  7. "Domain": "accs.emas-poc.com" //推送域名,这里是poc环境的推送域名
  8. },
  9. "Network":{
  10. "IPStrategy": {} //如无域名,只能通过ip建连,则将ACCS.Domain设置为poc环境域铭,并在此处指定其对应的ip和端口。示例:"IPStrategy": {"accs.emas-poc.com":"ip:port"}
  11. },
  12. ...
  13. }
  14. }

接入厂商通道的需要自行到各个品牌的推送接入平台申请对应的key、secret

2.2 Manifest配置

权限声明

  1. <uses-permission android:name="android.permission.INTERNET" />
  2. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  3. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  4. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  5. <uses-permission android:name="android.permission.WAKE_LOCK" />
  6. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  7. <uses-permission android:name="android.permission.GET_TASKS" />
  8. <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

必要Service声明(如已接入accs通道服务,则仅需配置里的服务)

  1. <!-- accs start -->
  2. <service
  3. android:name="com.taobao.accs.ChannelService"
  4. android:exported="true"
  5. android:process=":channel">
  6. <intent-filter>
  7. <action android:name="com.taobao.accs.intent.action.SERVICE" />
  8. </intent-filter>
  9. </service>
  10. <service
  11. android:name="com.taobao.accs.ChannelService$KernelService"
  12. android:exported="false"
  13. android:process=":channel" />
  14. <service
  15. android:name="com.taobao.accs.data.MsgDistributeService"
  16. android:exported="true">
  17. <intent-filter>
  18. <action android:name="com.taobao.accs.intent.action.RECEIVE" />
  19. </intent-filter>
  20. </service>
  21. <receiver
  22. android:name="com.taobao.accs.EventReceiver"
  23. android:process=":channel">
  24. <intent-filter>
  25. <action android:name="android.intent.action.BOOT_COMPLETED" />
  26. </intent-filter>
  27. <intent-filter>
  28. <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
  29. </intent-filter>
  30. <intent-filter>
  31. <action android:name="android.intent.action.PACKAGE_REMOVED" />
  32. <data android:scheme="package" />
  33. </intent-filter>
  34. <intent-filter>
  35. <action android:name="android.intent.action.USER_PRESENT" />
  36. </intent-filter>
  37. </receiver>
  38. <receiver
  39. android:name="com.taobao.accs.ServiceReceiver"
  40. android:process=":channel">
  41. <intent-filter>
  42. <action android:name="com.taobao.accs.intent.action.COMMAND" />
  43. </intent-filter>
  44. <intent-filter>
  45. <action android:name="com.taobao.accs.intent.action.START_FROM_AGOO" />
  46. </intent-filter>
  47. </receiver>
  48. <service
  49. android:name="com.taobao.accs.internal.AccsJobService"
  50. android:permission="android.permission.BIND_JOB_SERVICE"
  51. android:process=":channel" />
  52. <!-- accs end -->
  53. <!-- agoo start -->
  54. <service
  55. android:name="org.android.agoo.accs.AgooService"
  56. android:exported="true"
  57. android:process=":channel">
  58. <intent-filter>
  59. <action android:name="com.taobao.accs.intent.action.RECEIVE" />
  60. </intent-filter>
  61. </service>
  62. <!-- 接受agoo本地的控制事件 -->
  63. <receiver
  64. android:name="com.taobao.agoo.AgooCommondReceiver"
  65. android:exported="true"
  66. android:process=":channel">
  67. <intent-filter>
  68. <action android:name="{$packageName}.intent.action.COMMAND" />
  69. </intent-filter>
  70. <intent-filter>
  71. <action android:name="android.intent.action.PACKAGE_REMOVED" />
  72. <data android:scheme="package" />
  73. </intent-filter>
  74. </receiver>
  75. <!-- accs的2.2.2以及以后基于intentService,用于消息转发,提高消息送达率 -->
  76. <service
  77. android:name="com.taobao.agoo.TaobaoMessageIntentReceiverService"
  78. android:exported="true"
  79. android:process=":channel">
  80. <intent-filter>
  81. <action android:name="org.android.agoo.client.MessageReceiverService" />
  82. </intent-filter>
  83. </service>
  84. <!-- agoo end -->

可选厂商通道相关服务声明

  1. <!-- 可选厂商通道相关 -->
  2. <!-- 魅族 start -->
  3. <!-- push应用定义消息receiver声明 -->
  4. <receiver android:name=".DemoMeizuPushMsgReceiver">
  5. <intent-filter>
  6. <!-- 接收push消息 -->
  7. <action android:name="com.meizu.flyme.push.intent.MESSAGE" />
  8. <!-- 接收register消息 -->
  9. <action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />
  10. <!-- 接收unregister消息 -->
  11. <action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK" />
  12. <!-- 兼容低版本Flyme3推送服务配置 -->
  13. <action android:name="com.meizu.c2dm.intent.REGISTRATION" />
  14. <action android:name="com.meizu.c2dm.intent.RECEIVE" />
  15. <category android:name="${PackgeName}" />
  16. </intent-filter>
  17. </receiver>
  18. <!-- 魅族 end -->
  19. <!-- 华为 start -->
  20. <meta-data
  21. android:name="com.huawei.hms.client.appid"
  22. android:value="appid=xxxxx" />
  23. <!-- 华为 end -->

3. 接入API

3.1 构造配置

必须调用, 构造一个初始化配置项,可参考从平台下载的脚手架工程中的配置文件aliyun-emas-services.json,详细见前文[环境配置]章节

  1. AccsClientConfig.Builder clientBuilder = new AccsClientConfig.Builder()
  2. .setAppKey(String appKey) //必选, 所属appkey
  3. .setTag(AccsClientConfig.DEFAULT_CONFIGTAG) //必选, 多实例下tag, 其它sdk默认会使用该实例, 此时该值必须是`AccsClientConfig.DEFAULT_CONFIGTAG`
  4. .setAppSecret(String appsecret) //必选, 所属秘钥
  5. .setKeepAlive(boolean keepalive) //必选, 是否保活应用内连接, 建议值true
  6. .setDisableChannel(boolean disableChannel); //必选,建议值true
  7. .setInappHost(String host) //推送域名
  8. .setInappPubKey(int pubKey) //连接公钥,sdk需要设置为SpdyProtocol.PUBKEY_SEQ_OPEN
  9. .build();
  10. ACCSClient.init(Context context, clientBuilder);

3.2 设备注册

agoo注册

设备信息注册,绑定结果会在IRegister中异步返回,切记要放application里面调用, 以确保在主进程和CHANNEL进程都能执行到

  1. /**
  2. * agoo设备注册接口
  3. * @param context
  4. * @param accsConfigTag 指定accs实例tag, 此时应该使用上述的AccsClientConfig.DEFAULT_CONFIGTAG
  5. * @param appKey 上文申请的appkey
  6. * @param appSecret 上文申请的秘钥,使用无线保镖时无需填写
  7. * @param ttid 渠道id, 可不填
  8. * @param callback 注册结果回调
  9. */
  10. TaobaoRegister.register(Context context, String accsConfigTag, String appKey, String appSecret, String ttid, IRegister callback) throws AccsException
  11. class IRegister {
  12. //agoo注册成功回调
  13. public abstract void onSuccess(String deviceToken);
  14. //agoo注册失败回调
  15. public abstract void onFailure(String errCode, String errDesc);
  16. }

可选厂商通道注册

  1. //厂商通道初始化, 在各家push官网申请拿到, 同时服务token务必填入EMAS推送平台
  2. String phoneBrand = Build.BRAND;
  3. //简易判断机型, 可能不标准, 仅供参考
  4. if ("huawei".equalsIgnoreCase(phoneBrand) || "honor".equalsIgnoreCase(phoneBrand)) {
  5. HuaWeiRegister.register(mApplication);//华为通道(可选)
  6. } else if ("xiaomi".equalsIgnoreCase(phoneBrand)) {
  7. MiPushRegistar.register(mApplication, XIAOMI_APPID, XIAOMI_APPKEY);//小米通道(可选)
  8. } else if ("oppo".equalsIgnoreCase(phoneBrand)) {
  9. OppoRegister.register(mApplication, OPPO_APPKEY, OPPO_APPSECRET);//OPPO通道(可选)
  10. } else if ("meizu".equalsIgnoreCase(phoneBrand)) {
  11. MeizuRegister.register(mApplication, MEIZU_APPID, MEIZU_APPKEY);//MEIZU通道(可选)
  12. }

3.3 开启/关闭agoo

非必须调用, 默认情况下TaobaoRegister.register接口执行之后agoo就是开启的, 但是如果想运行时就关闭agoo推送, 那么调用TaobaoRegister.unbindAgoo接口. 如果想重新开启agoo推送, 调用TaobaoRegister.bindAgoo接口

3.4 设置/移除别名

非必须调用, 仅需要按用户维度推送的APP需要调用

  1. 当程序自身的用户进行登陆后,可以使用以下方法绑定用户,绑定结果会在ICallback中异步返回
  2. TaobaoRegister.setAlias(Context context, String alias, ICallback bindAlias)
  3. //当用户注销时,使用以下方法解绑用户,解绑结果会在会在ICallback中异步返回
  4. TaobaoRegister.removeAlias(Context context, ICallback bindAlias)

3.5 消息接收

消息解析示例:

  1. String messageId = intent.getStringExtra(AgooConstants.MESSAGE_ID);
  2. String message = intent.getStringExtra(AgooConstants.MESSAGE_BODY);

4. 厂商通道配置

如果接入厂商通道,则需要做系统弹窗跳转activity配置。

业务方指定的该Activity需要继承自com.taobao.agoo.BaseNotifyClickActivity, 同时实现父类的onMessage方法, 对该方法的intent参数进一步解析即可

4.1 Manifest声明

  1. <activity
  2. android:name=".ThirdNotifyClickedActivity"
  3. android:exported="true" />

4.2 代码示例

  1. public class ThirdNotifyClickedActivity extends BaseNotifyClickActivity {
  2. private static final String TAG = "ThirdNotifyClickedActivity";
  3. private final static String PRE_NOTIFY = "测试通知点击界面 内容: ";
  4. @BindView(R.id.text)
  5. public TextView mTextView;
  6. @Override
  7. protected void onCreate(Bundle savedInstanceState) {
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.activity_notify_clicked);
  10. ButterKnife.bind(this);
  11. mTextView.setText(PRE_NOTIFY);
  12. ALog.d(TAG, "onCreate");
  13. }
  14. @Override
  15. public void onMessage(final Intent intent) {
  16. runOnUiThread(new Runnable() {
  17. @Override
  18. public void run() {
  19. String body = intent.getStringExtra(AgooConstants.MESSAGE_BODY);//拿到厂商通道托管弹窗消息内容
  20. mTextView.setText(PRE_NOTIFY + body);
  21. }
  22. });
  23. }
  24. }

5. Demo示例

  1. public static IRegister agooRegister = new IRegister() {
  2. @Override
  3. public void onSuccess(String deviceToken) {
  4. ALog.i(TAG, "register onSuccess", "deviceToken", deviceToken);
  5. }
  6. @Override
  7. public void onFailure(String errorCode, String errorMsg) {
  8. ALog.e(TAG, "register onFailure", "errorCode", errorCode, "errorMsg", errorMsg);
  9. }
  10. };
  11. private IAppReceiver mAppReceiver = new IAppReceiver() {
  12. private String TAG = "mAppReceiver";
  13. @Override
  14. public void onBindApp(int errorCode) {
  15. ALog.i(TAG, "onBindApp", "errorCode", errorCode);
  16. try {
  17. ACCSClient.getAccsClient(AccsClientConfig.DEFAULT_CONFIGTAG).bindUser("123324234");
  18. } catch (AccsException e) {
  19. e.printStackTrace();
  20. }
  21. }
  22. @Override
  23. public void onUnbindApp(int errorCode) {
  24. ALog.i(TAG, "onUnbindApp", "errorCode", errorCode);
  25. }
  26. @Override
  27. public void onBindUser(String userId, int errorCode) {
  28. ALog.i(TAG, "onBindUser", "errorCode", errorCode);
  29. }
  30. @Override
  31. public void onUnbindUser(int errorCode) {
  32. ALog.i(TAG, "onUnbindUser", "errorCode", errorCode);
  33. }
  34. @Override
  35. public void onSendData(String dataId, int errorCode) {
  36. ALog.i(TAG, "onSendData");
  37. }
  38. @Override
  39. public void onData(String userId, String dataId, byte[] data) {
  40. ALog.i(TAG, "onData");
  41. }
  42. @Override
  43. public String getService(String serviceId) {
  44. String service = SERVICES.get(serviceId);
  45. return service;
  46. }
  47. @Override
  48. public Map<String, String> getAllServices() {
  49. return SERVICES;
  50. }
  51. };
  52. private void initAccs() {
  53. ACCSManager.setAppkey(mApplication.getApplicationContext(), mAppkey, env);//兼容老接口 如果有任意地方使用老接口,必须setAppkey
  54. NetworkSdkSetting.init(mApplication.getApplicationContext());
  55. //关闭AMDC请求
  56. HttpDispatcher.getInstance().setEnable(false);
  57. ACCSClient.setEnvironment(mApplication.getApplicationContext(), env);
  58. AwcnConfig.setAccsSessionCreateForbiddenInBg(false);
  59. final AccsClientConfig clientConfig = new AccsClientConfig.Builder()
  60. .setAppKey(appkey)
  61. .setAppSecret(appsecret)
  62. .setInappHost(emasHost)
  63. .setInappPubKey(pubkey)
  64. .setChannelHost(emasHost)
  65. .setChannelPubKey(pubkey)
  66. .setTag(AccsClientConfig.DEFAULT_CONFIGTAG)
  67. .setConfigEnv(env)
  68. .build();
  69. new Thread() { //建议异步进行初始化
  70. @Override
  71. public void run() {
  72. try {
  73. ACCSClient.init(mApplication, clientConfig);
  74. ACCSClient.getAccsClient(AccsClientConfig.DEFAULT_CONFIGTAG).bindApp(mChannelID, mAppReceiver);
  75. initAgooPush();
  76. } catch (AccsException e) {
  77. ALog.w(TAG, "initDefaultAccsConfig", e);
  78. }
  79. }
  80. }.start();
  81. }
  82. private void initAgooPush() {
  83. try {
  84. TaobaoRegister.setAgooMsgReceiveService(mReceivePushService);
  85. TaobaoRegister.register(mApplication, AccsClientConfig.DEFAULT_CONFIGTAG, mAppkey, mAppSecret, "",
  86. new IRegister() {
  87. @Override
  88. public void onSuccess(String deviceToken) {
  89. ALog.d(TAG, "agoo register success");
  90. AgooActivity.accsState = "online";
  91. AgooActivity.accsToken = deviceToken;
  92. }
  93. @Override
  94. public void onFailure(String s, String s1) {
  95. ALog.w(TAG, "agoo register fail" + s + s1);
  96. AgooActivity.accsState = "error:" + s;
  97. }
  98. });
  99. }
  100. //DemoAgooService.java消息接收
  101. public class DemoAgooService extends TaobaoBaseIntentService {
  102. .....
  103. @Override
  104. protected void onMessage(Context context, Intent intent) {
  105. String messageId = intent.getStringExtra(AgooConstants.MESSAGE_ID);
  106. String message = intent.getStringExtra(AgooConstants.MESSAGE_BODY);
  107. ALog.i(TAG, "onMessage", "messageId", messageId, "message", message);
  108. //解析agoo消息, 通知栏显示, 仅供参考
  109. NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
  110. .....
  111. manager.notify(notifyID, builder.build());
  112. }
  113. }

6. 错误码

6.1 客户端错误码

错误码 描述 备注
200 成功
-1 未知网络异常
-2 参数非法或为空
-3 服务端异常
-4 消息过大
-5 上行数据域名为空
-6 鉴权参数异常或为空
-7 鉴权异常
-8 未知错误
-9 请求超时 查看tag awcn error日志看连接有没有成功建立
-10 连接中断
-11 从网络库拿不到网络session 1、查看tag awcn error级别日志看连接有没有成功建立
2、网络库/mtop开启了降级
3、找不到tnet.so或者tnet.so和tnetjni版本不匹配
-12 ping超时
-13 无网络
-14 APPKEY为空
-15 app secret为空
-16 bindapp传入的callback为空
-17 ACCS被禁用

6.2 客户端网络连接错误码

错误码 描述 备注
-1108 so加载失败 tnet so没有打进包里或者tnet jni与so的版本不匹配
-38** http2协议错误
-2002 客户端主动关闭连接 一般是请求超时导致
-2003 建连超时
-2004 请求超时 请求超时
-2005 spdy stream被reset
-2032 服务端关闭连接
-2611 Connection refused 一般手机网络有问题或者流量被禁用
-2613 No route to host 一般手机网络有问题或者流量被禁用
-3* ssl错误

6.3 服务端错误码

错误码 描述 备注
100 dm异常 联系技术支持排查
101 sal异常 联系技术支持排查
102 appkey非法 or tail访问失败 没有联系技术支持配appkey
103 packagename 非法
104 serviceId 非法 没有联系技术支持配serviceId
105 设备离线
106 服务异常 检查业务后台是否正常,正常则联系服务端排查
300 app没有绑定 没有执行bindApp或者bindApp失败 ,查看bindapp返回错误码
314 appkey没注册 检查应用创建