监管部门要求在用户点击隐私协议弹框中 同意 按钮之前,App 不可以调用相关敏感 API。为应对此监管要求,mPaaS Android 10.1.32.17 以上(32 版本) 和 10.1.60.5 以上(60 版本)的基线提供了支持。如果您采用的是组件化的接入方法,请您根据实际情况参考本文对工程进行改造。
使用方法
弹出隐私弹框的 Activity 不可以继承 mPaaS 的 BaseActivity,因为 BaseActivity 会进行埋点数据采集,会导致 App 在同意隐私政策之前采集隐私数据。
新建隐私许可弹框回调类。在代码中新建一个类,实现
PrivacyListener
接口,类的实现可以参考以下代码:public class MyPrivacyListener implements PrivacyListener { // 在本方法内进行隐私许可弹框 @Override public void showPrivacy(final Activity activity, final PrivacyResultCallback privacyResultCallback) { if(null==privacyResultCallback){ return; } if(null!=activity){ new AlertDialog.Builder(activity) .setTitle("隐私许可弹框") .setMessage("主体内容") .setPositiveButton("同意继续使用", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { // 点击确定后,取消弹框 dialogInterface.cancel(); // 将弹框结果设置为 true privacyResultCallback.onResult(true); } }) .setNegativeButton("不同意并退出", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { // 点击不同意后,取消弹框 dialogInterface.cancel(); // 将弹框结果设置为 false privacyResultCallback.onResult(false); // 结束掉当前的 activity,框架会杀掉进程 if(null!=activity){ activity.finish(); } } }) .setCancelable(false) .create() .show(); }else{ // 如果 activity 是空的话,回调结果设置 false privacyResultCallback.onResult(false); } } }
说明如果您使用的是 10.1.68.42 及以上版本基线且需要清除隐私状态,请实现
PrivacyListener2
接口,并实现shouldClear
函数。以下代码是对
shouldClear
函数的说明:@Override public boolean shouldClear(Context context) { //用户没有点同意隐私协议默认用 SharedPreferences 存储 false 设置为 return false。如果需要再次弹窗需 SP 存储 true 设置为return true; return false;//return 的值取 SP 里面存的 boolean 值。 }
回调时,一定要弹出一个对话框来触发
windowFocusChange
,触发后框架才会进行后续的操作。由于该回调类会由系统框架进行反射初始化,且时机非常早,因此请不要添加带方法名的构造函数,以及在构造函数中加入具体逻辑。如果您需要在弹出对话框这里使用资源,在不同基线下需要采用不同的方法。
在 32 基线下,您需要采用如下方法:
Resources resource = QuinoxAgent.getInstance().getResourcesByBundle("资源所在的bundle的bundlename");
说明bundlename
可在 Bundle 工程中的主 module 中的/build/intermediates/bundle/META-INF/BUNDLE.MF
中查看。在 60 基线下,您需要在 Portal 工程的主 module 下,建立
res_slinks
文件,并将您的资源所在的 bundle 的group
和artifact
按照规则写到res_slinks
文件内。规则为group-artifact.split("-")[0]
。如果组合后内容过长需要换行,请您注意进行换行处理。例如:group = com.mpaas.demo.materialdesignartifact = materialdesign-build
,最终写入res_slinks
文件中的配置是com.mpaas.demo.materialdesign-materialdesign
。完成以上内容后,您可以直接使用
LayoutInflator.inflate(R.layout.xxx)
来调用资源。
在
AndroidManifest
中注册弹框回调类。在portal
的AndroidManifest
中注册隐私许可弹框回调类,value
是刚才实现的隐私许可弹框回调类的全路径。代码如下所示。注意将全路径及类名要替换成您自己的回调类。<!--隐私许可弹框回调--> <meta-data android:name="privacy.listener" android:value="com.mpaas.demo.launcher.MyPrivacyListener" />
启动弹框拦截。在
MockLauncherApplicationAgent
的preInit
中,加入启动弹框拦截。代码如下所示://检测是否要向用户进行隐私许可弹框 if(!PrivacyUtil.isUserAgreed(getApplicationContext())){ PermissionGate.getInstance().waitForUserConform(mContext, getMicroApplicationContext()); }
启动第一个 Activity。在
MockLauncherActivityAgent
的postInit
中,进行第一个Activity
的跳转。代码如下所示:public class MockLauncherActivityAgent extends LauncherActivityAgent { private Handler mUIHandler = new Handler(Looper.getMainLooper()); @Override public void preInit(Activity activity) { super.preInit(activity); } @Override public void postInit(final Activity activity) { super.postInit(activity); if (PrivacyUtil.isUserAgreed(activity)) { mUIHandler.postDelayed(new Runnable() { public void run() { Intent intent = new Intent(activity, MainActivity.class); activity.startActivity(intent); activity.finish(); } }, 1000); } else { PermissionGate.getInstance().registerPrivacyCallback( new PrivacyCallback() { @Override public void onTermsOfUseAgreed() { mUIHandler.postDelayed(new Runnable() { public void run() { Intent intent = new Intent(activity, MainActivity.class); activity.startActivity(intent); activity.finish(); } }, 1000); } } ); } } }