Skip to content
Yuye edited this page Jun 7, 2023 · 2 revisions

一、SDK基本信息

接入方式 描述 SDK大小 SDK版本 更新日志 SDK及Demo下载
aar 极简接入 168K v2.1.2 点击查看 点击下载

二、AndroidStudio接入

1、SDK依赖配置

1.1、复制Demo中dianzhuan-xxx.aar到您项目libs下
1.2、app模块build.gradle配置
android {
    defaultConfig {
        ndk {
            abiFilters 'arm64-v8a','armeabi-v7a'//根据需求保留CPU架构:arm64-v8a、armeabi-v7a、x86、x86_64
        }
    }
}

dependencies {
    //点赚SDK
    implementation(name: 'dianzhuan-2.1.2', ext: 'aar')//如果dependencies的fileTree中有'*.aar'则不需要此配置
}

2、AndroidX环境

  • 如果您的环境为AndroidX需在gradle.properties中添加如下配置:
android.useAndroidX=true
android.enableJetifier=true

3、权限申明

    <!--SDK必须权限-->
    <!--基础的联网需求-->
    <uses-permission android:name="android.permission.INTERNET" />
    <!--唯一设备标识-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <!--Android7.0及以上系统安装apk所需-->
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    <!--查询本机所有已安装的应用/游戏-->
    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
        tools:ignore="QueryAllPackagesPermission" />
    <!--引导用户卸载旧版本(其它渠道安装的游戏)-->
    <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />

    <!--以下权限为可选权限-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

4、混淆

-keep class com.android.point.core.** {*;}
到此SDK已集成完毕!有关SDK功能和使用常见问题IMEIOAID自定义下载自定义UIFragment场景等需求,可阅读下方文档

三、SDK功能和使用

1、SDK初始化
  • 在打开点赚组件之前初始化即可,内部初始化符合隐私合规,请放心初始化
    /**
     * @param context 上下文,建议传入Application类型上下文
     * @param appId app_id,在点赚商户后台申请
     * @param appKey app_key,在商户后台申请
     * @param debug 是否开启日志输出模式,true:开启,false:关闭
     */
    Ls.getWrapper().initSdk(application,appId,appKey, true);
2、有积分和无积分
  • 1、有积分:SDK调用需要传入非0的用户ID,点赚会将试玩的订单信息推送至开发者服务器(如果已再点赚后台配置回调)
  • 2、无积分:SDK调用无需传入用户ID字段,点赚也不会将试玩的订单信息推送至开发者服务器
3、首页
  • 默认样式的点赚首页
    Ls.getWrapper().routeIndex(context);//无积分
    Ls.getWrapper().routeIndex(context,userid);//有积分
  • 自定义样式的点赚首页
    StyleConfig build = new StyleConfig.Builder()
            //是否显示标题栏,默认显示
            .showTitle(true)
            //状态栏样式,0:白色字体,1:黑色字体,默认白色字体
            .setStatusBarStyle(1)
            //状态栏背景颜色,默认黑色
            .setStatusBarColor(ContextCompat.getColor(context, R.color.white))
            .build();
    Ls.getWrapper().routeIndex(context,build);//无积分
    Ls.getWrapper().routeIndex(context,build,userid);//有积分
4、应用详情页
    Ls.getWrapper().routeDetails(context, "广告id");//无积分
    Ls.getWrapper().routeDetails(context, "广告id",userid);//有积分
5、搜索页
    Ls.getWrapper().routeSearch(context);//无积分
    Ls.getWrapper().routeSearch(context,userid);//有积分
6、检查SDK集成状态
  • 初始化时debug传入true调用下列接口后在控制台过滤"LS_API"查看日志输出
    Ls.getWrapper().checkedStatus(context);

四、更新日志

五、统一设备标识

1、IMEI

1.1、SDK内部获取
  • SDK内部在检查已申明android.permission.READ_PHONE_STATE权限后自行获取IMEI
1.2、开发者传入IMEI
  • 支持开发者自行传入IMEI(SDK优先使用传入的IMEI),需在使用SDK各组件之前设置
    Ls.getWrapper().setDeviceId("imei");

2、OAID

  • 自Android10系统开始,IMEI不再支持非系统应用获取,故此设备唯一标识符的替代方案为:MSA OAID
  • 点赚SDK内部OAID获取优先权重:开发者传入OAID>第三方MSA SDK获取>系统API获取。有关系统API支持机型详见:设备及系统支持情况
2.1、开发者传入OAID(可选)
  • 点赚SDK将优先使用此OAID作为OAID标识符,(OAID非异常时:比如为null或00000000-0000-0000-0000-000000000000)内部不再尝试获取OAID
    Ls.getWrapper().setOaid("88888888");
2.2、第三方MSA OAID(可选)
  • 使用第三方OAID SDK获取请按下列步骤依赖第三方SDK到您的项目,点赚内部将在检测到正确集成第三方SDK后优先使用第三放SDK获取OAID
2.2.1、复制oaid_sdk_1.0.25.aar到您的libs目录中
2.2.2、自行准备或复制demo中assets下的supplierconfig.json文件到您的项目中assets目录下
2.2.3、build.gradle引用
dependencies {
    implementation(name: 'oaid_sdk_1.0.25', ext: 'aar')//如果dependencies的fileTree中有'*.aar'则不需要此配置
}
2.2.4、混淆
  • 引用第三方OAID SDK并且项目开启混淆必须添加下列混淆
-dontwarn com.bun.**
-dontwarn sun.misc.**
-keep class com.bun.**{*;}
2.2.5、第三方SDK设备支持情况及下载请参阅官方MSA OAID说明
2.3、系统API获取(默认)
  • 点赚SDK支持在不依赖第三方SDK的条件下自行获取OAID,无需接入者额外处理
  • 设备及系统支持情况:
厂商或品牌 系统或框架
华为(Huawei、Honor) HMS Core 2.6.2+ 、Google Play Service 4.0+
小米(XiaoMi、Redmi、BlackShark) MIUI 10.2+、Google Play Service 4.0+
维沃(VIVO、IQOO) Funtouch OS 9+、OriginOS 1.0+、Google Play Service 4.0+
欧珀(OPPO、Realme) ColorOS 7.0+、Google Play Service 4.0+
三星(Samsung) Android 10+、Google Play Service 4.0+
联想(Lenovo) ZUI 11.4+、Google Play Service 4.0+
华硕(ASUS) Android 10+、Google Play Service 4.0+
魅族(Meizu) Android 10+、Google Play Service 4.0+
一加(OnePlus) Android 10+、Google Play Service 4.0+
努比亚(Nubia) Android 10+、Google Play Service 4.0+
酷派(Coolpad) CoolOS、Google Play Service 4.0+
酷赛(Coosea ) Android 10+、Google Play Service 4.0+
卓易(Droi ) Freeme OS、Google Play Service 4.0+
其他(ZTE、HTC、Motorola、……) SSUI、Google Play Service 4.0+

注:点赚的 OAID 获取接口主要参考北京数字联盟公开的代码以及逆向分析参考移动安全联盟的 SDK、HUAWEI Ads SDK、小米 DeviceId.jar、Google Play Services SDK 等。

六、APK文件下载

  • SDK支持自定义下载引擎,下载引擎的逻辑优先顺序:filedownloader>开发者自定义下载引擎>SDK默认http下载

1、第三方下载引擎

  • SDK已支持适配第三方开源的下载引擎,若需使用此下载引擎,请在项目中引用下列SDK即可:
    implementation 'com.liulishuo.filedownloader:library:1.7.7'

2、自定义下载引擎

2.2.1、自定义下载引擎实现
  • 实现DownloadEngine接口扩展你自己的下载引擎,请参考Demo中的CustomDownloadEngine类,示例:
public class CustomDownloadEngine implements DownloadEngine {

    private OnDownloadListener mListener;

    /**
     * 注册下载地址
     * @param listener
     */
    @Override
    public void setDownloadListener(OnDownloadListener listener) {
        this.mListener=listener;
    }

    /**
     * 移除下载监听器
     */
    @Override
    public void removeDownloadListener() {
        mListener=null;
    }

    /**
     * 返回文件下载保存的路径地址
     * @param context
     * @return
     */
    @Override
    public String getOutPutPath(Context context) {
        return getOutCacheDir(context);
    }

    /**
     * 开始下载,自己判断是否下载过apk文件和维护下载任务池。如需SDK内部显示下载进度,则必须将下载事件回调通过mListener给SDK内部。自定义下载进度条UI无需回调给SDK
     * @param apkPath 开始下载,待下载的文件路径
     * @param context 开始下载,当前界面的上下文
     */
    @Override
    public void download(String apkPath,final Context context) {
        //在这里实现自己的下载器,如需SDK内部显示下载进度,则必须将下载事件通过mListener回调给SDK内部。自定义下载进度条UI无需回调给SDK
    }

    /**
     * 结束所有下载
     */
    @Override
    public void stopAllDownload() {
        this.mListener=null;
        if(null!= mApkDownloadTask){
            mApkDownloadTask.stop();
        }
    }

    /**
     * 返回一个下载存储路径
     * @param context
     * @return
     */
    private String getOutCacheDir(Context context) {
        File file= new File(context.getFilesDir().getAbsolutePath() + File.separator+"A"+ File.separator);
        if(!file.exists()){
            file.mkdirs();
        }
        return file.getAbsolutePath();
    }
}
2.2.2、自定义下载引擎的使用
    //在开始下载前设置您自己的下载引擎,只需设置一次即可
    Ls.getWrapper().setDownloadEngine(new CustomDownloadEngine());

七、更多SDK特性

1、Fragment片段场景

  • SDK支持返回一个Fragment,只需要将Fragment添加到您的Activity中即可,Fragment方式仅支持首次渲染时打开点赚首页
  • 具体使用请参考Demo中的FragmentActivity类
    Fragment fragment=Ls.getWrapper().getFragment(userId);//无极分传0,有积分必须传入非0的用户ID

2、RewardPointView组件

  • 为方便开发者的高度自定义UI需求,SDK自2.x版本起支持直接使用ViewGroup组件方式接入,请参考Demo中的CustomDetailsActivity类
  • RewardPointView的所有功能API请阅读IPointControl类
2.1、组件声明及使用
2.1.1、在任意位置的xml中申明组件
        <com.android.point.widget.RewardPointView
            android:id="@+id/cpl_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/white"/>
2.1.2、组件的准备及使用
        mWebContent = (RewardPointView) findViewById(R.id.cpl_view);//或者直接new RewardPointView(this);后将RewardPointView添加到您的ViewGroup中
        //禁用内部刷新按钮,内部默认开启
        //mWebContent.disableRefresh();
        //禁用标题栏交互,内部默认开启
        //mWebContent.disableToolBar();
        //禁用调用SDK层面产生的错误UI交互,内部默认开启
        //mWebContent.disableSdkErrorUI();
        //监听WebView交互事件
        mWebContent.setOnStatusListener(new OnStatusListener() {

            /**
             * 内部web加载完成
             */
            @Override
            public void onLoadSuccess() {
                if(null!=mRefreshLayout) mRefreshLayout.setRefreshing(false);
            }

            /**
             * 返回当前宿主Activity
             * @return 如果返回为空,SDK内部会自动尝试获取当前宿主Activity
             */
            @Override
            public Activity getActivity() {
                return CustomDetailsActivity.this;
            }

            /**
             * 返回事件
             */
            @Override
            public void onBackPressed() {
                CustomDetailsActivity.this.onBackPressed();
            }

            /**
             * 内部加载出错了
             * @param error 组件加载失败了,失败描述信息
             */
            @Override
            public void onError(String error) {
                Toast.makeText(getApplicationContext(),error,Toast.LENGTH_SHORT).show();
                if(null!=mRefreshLayout) mRefreshLayout.setRefreshing(false);
            }

            /**
             * 请求关闭界面
             */
            @Override
            public void onFinish() {
                CustomDetailsActivity.this.finish();
            }

            //更多回调请阅读OnPagerStatusListener申明的方法
        });

        //设置自定义下载引擎
        //mWebContent.setDownloadEngine(实现DownloadEngine接口的自定义下载引擎);
        //设置动作意图,参阅Ls申明的常量:0:首页,1:详情页(开始渲染前需设置广告id),2:搜索页
        //mWebContent.setAction(0);
        //设置广告ID,直接打开详情页必须传入,配合mWebContent.setAction(Ls.ACTION_DETAILS);使用
        //mWebContent.setAid("00000");
        //设置是否应用于Fragment场景
        //mWebContent.setIsFragment(false);
        //设置自定义参数(保留功能,暂未启用)
        //mWebContent.setCustomParams(null);

        //一定要调用此方法开始加载并渲染
        mWebContent.load(userId);//无积分传0,有积分必须传非0的用户ID
2.2、生命周期及权限处理
  • 直接使用RewardPointView组件需要在您的宿主Activity中处理下列逻辑
    /**
     * 必须调用,配合内部权限获取
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if(null!= mWebContent) mWebContent.onRequestPermissionsResult(requestCode,permissions,grantResults);
    }

    /**
     * 必须调用
     */
    @Override
    protected void onResume() {
        super.onResume();
        if(null!= mWebContent) mWebContent.onResume();
    }

    /**
     * 必须调用
     */
    @Override
    protected void onPause() {
        super.onPause();
        if(null!= mWebContent) mWebContent.onPause();
    }

    /**
     * 必须调用
     */
    @Override
    public void onBackPressed() {
        if(null== mWebContent){
            super.onBackPressed();
            return;
        }
        if(mWebContent.canGoBack()){
            super.onBackPressed();
        }
    }

    /**
     * 必须调用
     */
    @Override
    protected void onDestroy() {
        if(null!= mWebContent) mWebContent.onDestroy();
        super.onDestroy();
    }

八、常见问题

1、Android 10、11适配

  • Android 10、11的设备并且主项目的targetSdkVersion =29、30的编译环境下的 apk下载存储、安装状态检测等场景兼容适配:
<application
<!--此属性仅针对Android 29的设备有效,Android 30的设备覆盖安装有效,新安装无效-->
    android:requestLegacyExternalStorage="true">
...
</application>