厂商 SDK 集成指南

厂商 SDK 集成指南

前言

  • 本文档介绍 Android Studio 开发环境下厂商推送 SDK 的 Maven 集成步骤

  • 集成厂商 SDK 前,必须先 集成个推 SDK

  • 辅助推送:个推推送针对厂商设备管控较严的情况特意接入厂商推送作为辅助通道以提高在厂商设备上的到达率。个推推送优先选择个推通道进行消息下发,只有在个推通道断连时选择辅助通道下发消息。厂商推送在下发纯透传消息时并不保证会拉起被杀死进程,所以辅助通道在进程被杀死情况下无法保证透传消息一定到达。

  • 本文默认您已经完成了个推推送 SDK 的集成以及掌握了基本的 Android 基础知识

  • 本文假设您的工程项目结构为

    Getui_SDK_Demo_AS_manufacture/
      |- app/ (项目主模块)
      |    |- libs/ (第三方库)
      |    |- src/ (代码目录)
      |    |- build.gradle (模块级 gradle 文件)
      |- gradle/
      |- build.gradle (顶层 gradle 文件)
      |- settings.gradle
      | ......
    

1. 添加辅助 SDK 及相关配置

1.1 添加 Maven 库地址

在以项目名为命名的顶层 build.gradle 文件的 allprojects.repositories 中,添加个推 maven 库地址 https://mvn.getui.com/nexus/content/repositories/releases/ 如下所示:

allprojects {
    repositories {
        mavenCentral()
        //添加 Maven URL 地址
        maven {
            url "https://mvn.getui.com/nexus/content/repositories/releases/"
        }
    }
}

1.2 配置相关依赖

app/build.gradle 文件中的 dependencies 块中引用厂商 SDK 依赖库 ,此处的{version}为对应的版本号,详见厂商更新日志。ups为个推与手机厂商合作通道,目前支持坚果,索尼,海信手机。如下所示:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    // 根据所需厂商选择集成
    implementation 'com.getui.opt:hwp:{version}'   // 华为
    implementation 'com.getui.opt:xmp:{version}'   // 小米
    implementation 'com.assist-v3:oppo:{version}'  // oppo
    implementation 'com.assist-v3:vivo:{version}'  // vivo
    implementation 'com.getui.opt:mzp:{version}'   // 魅族
    implementation 'com.getui.opt:ups:{version}'   // ups,ups目前支持坚果,索尼,海信手机
}

1.3 配置应用参数

app/build.gradle 文件中的 android.defaultConfig 下添加 manifestPlaceholders,配置厂商相关的应用参数,如下 manifestPlaceholders 中的内容所示,ups无需配置对应的厂商ID,个推已经默认作出处理:

android {
    defaultConfig {
        manifestPlaceholders = [
                // 华为 相关应用参数
                HUAWEI_APP_ID  : "",

                // 小米相关应用参数
                XIAOMI_APP_ID  : "",
                XIAOMI_APP_KEY : "",

                // OPPO 相关应用参数   
                OPPO_APP_KEY   : "",
                OPPO_APP_SECRET: "",

                // VIVO 相关应用参数   
                VIVO_APP_ID    : "",
                VIVO_APP_KEY   : "",

                // 魅族相关应用参数  
                MEIZU_APP_ID   : "",
                MEIZU_APP_KEY  : ""
        ]
    }
}

2. 华为配置

集成华为通道还需以下步骤。若无需集成华为厂商推送,可直接跳过此节

1. 添加应用的 AppGallery Connect 配置文件

  1. 登录 AppGallery Connect,选择“我的项目”,找到应用所在的产品,点击应用名称。
  2. 选择“项目设置 > 常规”,在“应用”栏下的“agconnect-services.json”下载配置文件。
  3. 将 agconnect-services.json 文件拷贝到应用级根目录下。如下:

    Getui_SDK_Demo_AS_manufacture/
      |- app/ (项目主模块)
      |  ......
      |    |- agconnect-services.json 
      |- gradle/
      |- build.gradle (顶层 gradle 文件)
      |- settings.gradle
      | ......
    

注意:华为离线推送验证需要客户端使用签名包,否则会校验失败。

2. 配置相应依赖

  1. 在以项目名为命名的顶层 build.gradle 文件的 buildscript.repositoriesallprojects.repositories 中,添加 HMS SDK 的 maven 地址。在 buildscript.dependencies 添加 classpath 'com.huawei.agconnect:agcp:${version}' 如下所示:

    buildscript {
        repositories {
            mavenCentral()
            google()
            maven {url 'https://developer.huawei.com/repo/'}
        }
        dependencies {
            ......
            classpath 'com.huawei.agconnect:agcp:1.4.1.300'
        }
    }
    
    allprojects {
        repositories {
            ......
            maven {url 'https://developer.huawei.com/repo/'}
        }
    }
    
  2. 在模块级别 app/build.gradle 中文件头配置 apply plugin: 'com.huawei.agconnect' 以及在 dependencies 块配置 HMS Push 依赖 implementation 'com.huawei.hms:push:${version}',如下:

    apply plugin: 'com.android.application'
    apply plugin: 'com.huawei.agconnect'
    android { 
        ......
    }
    dependencies { 
        ......
        implementation 'com.huawei.hms:push:5.3.0.301'
    }
    
  3. 配置签名信息:将应用签名文件拷贝到工程 app 目录下,在 app/build.gradle 文件中配置签名。如下(具体请根据您当前项目的配置修改):

    signingConfigs {
         config {
             keyAlias 'pushdemo'
             keyPassword '123456789'
             storeFile file('pushdemo.jks')
             storePassword '123456789'
         }
     }
     buildTypes {
         debug {
             signingConfig signingConfigs.config
         }
         release {
             signingConfig signingConfigs.config
             minifyEnabled false
             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
         }
     }
    

3. 集成验证

初始化个推 SDK,打开 logcat 查看信息,Verbose 级日志,tag 过滤内容“Assist_”,Filter 选择“No Filters”。

成功打印 token 信息则表示集成成功:
config_succ

4. 通知开关开启

4.1 检测用户设备是否开启通知权限,示例代码如下:

public boolean areNotificationsEnabled(Context context) {
            NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            if (Build.VERSION.SDK_INT >= 24) {
                return mNotificationManager.areNotificationsEnabled();
            } else if (Build.VERSION.SDK_INT >= 19) {
                AppOpsManager appOps =
                        (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
                ApplicationInfo appInfo = context.getApplicationInfo();
                String pkg = context.getApplicationContext().getPackageName();
                int uid = appInfo.uid;
                try {
                    Class<?> appOpsClass = Class.forName(AppOpsManager.class.getName());
                    Method checkOpNoThrowMethod = appOpsClass.getMethod("checkOpNoThrow", Integer.TYPE,
                            Integer.TYPE, String.class);
                    Field opPostNotificationValue = appOpsClass.getDeclaredField("OP_POST_NOTIFICATION");
                    int value = (int) opPostNotificationValue.get(Integer.class);
                    return ((int) checkOpNoThrowMethod.invoke(appOps, value, uid, pkg)
                            == AppOpsManager.MODE_ALLOWED);
                } catch (ClassNotFoundException | NoSuchMethodException | NoSuchFieldException
                        | InvocationTargetException | IllegalAccessException | RuntimeException e) {
                    return true;
                }
            } else {
                return true;
            }
        }

返回true,表示用户设备正常开启通知权限,推送通知在设备上可以正常到达、展示;
返回false,表示用户设备未开启通知权限,通知权限被关闭后,重要服务通知均无法正常触达用户,进而影响日活、留存和转化数据。

4.2 通知关闭引导开通功能,示例代码如下:

private void openNotification(Context context) {
        try {
            Intent intent = new Intent();
            if (Build.VERSION.SDK_INT >= 26) {
                intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
                intent.putExtra("android.provider.extra.APP_PACKAGE", context.getPackageName());
                intent.putExtra("android.provider.extra.CHANNEL_ID", context.getApplicationInfo().uid);
                intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
            } else if (Build.VERSION.SDK_INT >= 21) {
                intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
                intent.putExtra("app_package", context.getPackageName());
                intent.putExtra("app_uid", context.getApplicationInfo().uid);
                intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
            } else {
                intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
                Uri var2 = Uri.fromParts("package", context.getPackageName(), (String)null);
                intent.setData(var2);
                intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
            }
            startActivity(intent);
        } catch (Throwable var3) {
            var3.printStackTrace();
        }
    }

调用上述方法,将跳转到系统开启通知功能页面,引导用户开启通知权限

5. 打开应用自定义页面

鉴于各厂商SDK打开应用自定义页面有多种方式,且有些方式互不兼容,为了保持统一并且方便开发者,个推提供一种标准且唯一的打开应用自定义页面方式,通过服务端API指定intent参数,同时此方式兼容旧版本SDK,可以正常打开自定义页面,不会影响未更新用户使用。
注意:原有intent方式,请慎重使用,即:"intent:#Intent;component=com.getui.demo/com.getui.demo.DemoActivity;S.key1=value1;end";
原有intent方式使用厂商渠道时,某些机型会无法打开,例如当vivo厂商sdk版本从 com.assist-v3:vivo:3.0.4 开始 或者 com.assist:vivo:1.0.8 开始,使用老版本格式intent (在部分 vivo 机型, 比如 android 11 ) 可能出现无法打开应用内自定义界面

跨应用启动Activity必须使用显式intent方式,通过intent可以携带额外的数据给客户端应用。主要通过如下几步来完成:

5.1 生成Intent参数:

    //在Android 开发工具中,参考如下代码生成 Intent
    Intent intent = new Intent(this, DemoActivity.class);
    //Scheme协议(gtpushscheme://com.getui.push/detail?)开发者可以自定义
    intent.setData(Uri.parse("gtpushscheme://com.getui.push/detail?"));

    //如果设置了 package,则表示目标应用必须是 package 所对应的应用
    intent.setPackage(getPackageName());
    //intent 中添加自定义键值对,value 为 String 型
    intent.putExtra("name", "getui");
    //intent 中添加自定义键值对,value 为 Integer 型
    intent.putExtra("age", 18);

    // 应用必须带上该Flag,如果不添加该选项有可能会显示重复的消息,强烈推荐使用Intent.FLAG_ACTIVITY_CLEAR_TOP
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    String intentUri = intent.toUri(Intent.URI_INTENT_SCHEME);

    //得到intent url 值
    //示例:intent://com.getui.push/detail?#Intent;scheme=gtpushscheme;launchFlags=0x4000000;package=com.getui.demo;component=com.getui.demo/com.getui.demo.DemoActivity;i.age=18;S.name=getui;end

    // 打印出的intentUri值就是设置到推送消息中intent字段的值
    Log.d("intentUri", intentUri);

注意:
1、com.getui.demo是您的包名即applicationId,com.getui.demo.DemoActivity是您要打开的 activity 全路径

2、由于部分厂商只支持 String 类型的参数,设置其它类型参数,App 端接收以后,会强转为 String 类型,所以建议参数统一设置为 String 类型。参数可以分开设置,也可以合并为一个 json 格式数据。

3、S 大写是 string 类型,s小写是short类型,B 大写是 boolean 类型,b 小写是 byte 类型,其它均小写即可;

4、如果您手动拼装intent,有特殊字符的需要encode设置的参数,如有特殊字符:比如 Scheme 链接含有#符号,建议 UrlEncode 编码处理,参数在经过Android 系统接收后,会自动进行解码处理(经测试,intent 参数里面有 % 符号,客户端接收参数会乱码;intent 参数里面有 # 和 ; 符号,会影响跳转,UrlEncode 编码处理后正常。);

5、如果遇到点击第二条通知,页面不能正常跳转的情况,建议设置 launchFlags为0x04000000 测试,这个一般是 activity 启动模式的问题,参数会在 activity 的 onCreate 或 onNewIntent 方法回调。

5.2 在AndroidManifest.xml文件注册被启动的Activity:

比如被启动的自定义页面 DemoActivity,其中host、path、scheme 一定要与上面的 Intent 生成参数匹配。
注意:该属性必须设置android:exported="true";activity 名称用户自己定义.

    <activity android:name=".DemoActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.VIEW"/>
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
                <data
                    <!-- 下面内容由您自定义 -->
                    android:host="com.getui.push"
                    android:path="/detail"
                    android:scheme="gtpushscheme" />
        </intent-filter>
    </activity>

5.3 在上一步中您自定义Activity中接收数据:

// 此处DemoActivity是您需要打开的应用内的页面Activity
public class DemoActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo);
        //获取自定义透传参数值
        Intent intent = getIntent();
        if (null != intent) {
            String name = intent.getStringExtra("name");
            int age = intent.getIntExtra("age", 0);
            Log.d("DemoActivity", "name = " + name + ",age = " + age);
        }
    }
}

开发者中心 SDK 下载

文档中心搜索

在线
咨询

微信扫一扫

随时联系技术支持

在线
咨询