Android APP隐私权限整改
一、背景简介
前段时间,国内对于安卓APP隐私问题做了一波整改,我们的APP也做了一些整改,现在分块抽空整理出来吧
二、整改项目
1、隐私权限整改
主要是针对现在市场上APP各种乱申请权限,获取用户隐私的行为,整理了一个工具类(主要参考云闪付APP的业务逻辑),如下:
public class PermissionUtils {//*** 当前APP需要动态获取的运行时权限*/private static String[] partnerAppPermissions = {Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE,
// Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.ACCESS_FINE_LOCATION,
// Manifest.permission.ACCESS_COARSE_LOCATION};private static Map<String, String> getPermissionNameMap() {Map<String, String> permissionNameMap = new HashMap<>();permissionNameMap.put(Manifest.permission.CAMERA, "相机");permissionNameMap.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, "存储");
// permissionNameMap.put(Manifest.permission.READ_EXTERNAL_STORAGE, "存储");permissionNameMap.put(Manifest.permission.ACCESS_FINE_LOCATION, "定位");
// permissionNameMap.put(Manifest.permission.ACCESS_COARSE_LOCATION, "定位");return permissionNameMap;}private static Map<String, String> getPermissionDesMap() {Map<String, String> getPermissionDesMap = new HashMap<>();getPermissionDesMap.put(Manifest.permission.CAMERA, "照相设备将被用于****等需要使用相机的功能");getPermissionDesMap.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, "手机存储权限将被用于读写文件系统业务,如图片缓存、主要功能的访问与使用");
// getPermissionDesMap.put(Manifest.permission.READ_EXTERNAL_STORAGE, "手机存储权限将被用于读写文件系统业务,如图片缓存、主要功能的访问与使用");getPermissionDesMap.put(Manifest.permission.ACCESS_FINE_LOCATION, "APP需要获取您的位置信息,用于****等需要位置信息的功能");
// getPermissionDesMap.put(Manifest.permission.ACCESS_COARSE_LOCATION, "APP需要获取您的位置信息,用于*****等需要位置信息的功能");return getPermissionDesMap;}/*** 获取运行时权限列表描述及相关授权情况*/public static List<PermissionBean> getPermissionBeanList(BaseActivity baseActivity) {return getPermissionBeanList(baseActivity, partnerAppPermissions);}private static List<PermissionBean> getPermissionBeanList(BaseActivity baseActivity, String[] permissions) {if (permissions == null || permissions.length == 0) {return null;}List<PermissionBean> permissionBeanList = new ArrayList<>();PermissionBean permissionBean = null;Map<String, String> permissionNameMap = getPermissionNameMap();Map<String, String> getPermissionDesMap = getPermissionDesMap();for (String permission : permissions) {permissionBean = new PermissionBean();permissionBean.setPermission(permission);permissionBean.setPermissionName(permissionNameMap.get(permission));permissionBean.setPermissionDes(getPermissionDesMap.get(permission));permissionBean.setGranted(checkPermissionBefore(baseActivity, permission));permissionBeanList.add(permissionBean);permissionBean = null;}return permissionBeanList;}/*** 获取相机权限* 请勿放在Activity的onResume()中,避免反复弹窗** @param baseActivity 上下文环境* @param listener 权限获取结果监听*/public static void getCameraPermission(BaseActivity baseActivity, PermissionListener listener) {int[] applyMsg = new int[]{R.string.camera_permission, R.string.camera_permission_message, R.string.camera_permission_apply};String[] permissions = new String[]{Manifest.permission.CAMERA};getNeedPermission(baseActivity, listener, applyMsg, permissions);}/*** 获取外部存储权限* 请勿放在Activity的onResume()中,避免反复弹窗** @param baseActivity 上下文环境* @param listener 权限获取结果监听*/public static void getStoragePermission(BaseActivity baseActivity, PermissionListener listener) {int[] applyMsg = new int[]{R.string.external_storage_permission, R.string.external_storage_permission_message, R.string.external_storage_permission_apply};String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE};getNeedPermission(baseActivity, listener, applyMsg, permissions);}/*** 获取定位权限* 请勿放在Activity的onResume()中,避免反复弹窗** @param baseActivity 上下文环境* @param listener 权限获取结果监听*/public static void getLocationPermission(BaseActivity baseActivity, PermissionListener listener) {int[] applyMsg = new int[]{R.string.location_permission, R.string.location_permission_message, R.string.location_permission_apply};String[] permissions = new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};getNeedPermission(baseActivity, listener, applyMsg, permissions);}/*** 需要动态获取的权限申请* 请勿放在Activity的onResume()中,避免反复弹窗** @param baseActivity 上下文环境* @param listener 权限获取结果监听* @param applyMsg 依次为:权限,申请原因说明,申请描述* @param permissions 危险权限名称*/private static void getNeedPermission(BaseActivity baseActivity, PermissionListener listener, int[] applyMsg, String... permissions) {if (applyMsg == null || applyMsg.length != 3) {return;}if (!checkPermissionBefore(baseActivity, permissions)) {requestPermissionDialog(baseActivity, applyMsg[0], applyMsg[1], applyMsg[2], listener, permissions);} else {listener.allow();}}/*** 权限检查*/private static boolean checkPermissionBefore(BaseActivity baseActivity, String... permissions) {if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {return true;}for (String permission : permissions) {if (ContextCompat.checkSelfPermission(baseActivity, permission) != PackageManager.PERMISSION_GRANTED) {return false;}}return true;}/*** 请求权限前的弹窗** @param baseActivity 上下文环境* @param title "APP"想访问您的****** @param message *****权限权限将被用于………的访问与使用* @param unauthorizedMsg 权限获取失败的弹窗提示语*/private static void requestPermissionDialog(BaseActivity baseActivity, @StringRes int title, @StringRes int message, @StringRes int unauthorizedMsg,PermissionListener listener, String... permissions) {CustomDialog.Builder builder = new CustomDialog.Builder(baseActivity);builder.setTitle(title).setTitleVisible(true).setMessage(message).setPositiveButton("允许", (dialog, which) -> {dialog.dismiss();//请求权限requestPermission(baseActivity, unauthorizedMsg, listener, permissions);}).setNegativeButton("不允许", (dialog, which) -> dialog.dismiss()).setCancelable(false).create().show();}/*** 权限获取结果监听*/public interface PermissionListener {void allow();}/*** 权限获取*/private static void requestPermission(BaseActivity baseActivity, @StringRes int unauthorizedMsg, PermissionListener listener, String... permissions) {RxPermissions rxPermissions = new RxPermissions(baseActivity);Disposable disposable = rxPermissions.request(permissions).subscribe(new Consumer<Boolean>() {@Overridepublic void accept(Boolean aBoolean) throws Exception {if (aBoolean) {//权限获取成功listener.allow();} else {//权限获取失败,弹出授权提示框unauthorizedPoint(baseActivity, unauthorizedMsg);}}});}/*** 未授权时,再次点击弹出的授权提示框** @param baseActivity 上下文环境* @param message 因您未授予APP****权限,该功能无法使用,可在设置中修改*/private static void unauthorizedPoint(BaseActivity baseActivity, @StringRes int message) {CustomDialog.Builder builder = new CustomDialog.Builder(baseActivity);builder.setTitle(R.string.permission_apply).setTitleVisible(true).setMessage(message).setPositiveButton("去设置", (dialog, which) -> {dialog.dismiss();//跳转权限设置界面gotoSettings(baseActivity);}).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).setCancelable(false).create().show();}/*** 跳转权限设置界面** @param baseActivity 上下文环境*/public static void gotoSettings(BaseActivity baseActivity) {Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);intent.setData(Uri.parse("package:" + baseActivity.getPackageName()));baseActivity.startActivity(intent);}
}
2、APP隐私政策
- APP隐私政策内容要注意做好APP权限和隐私的说明
- 首次使用APP需要弹出隐私政策弹窗
- 登录APP需要同意隐私政策
- 隐私政策有更新时需要再次弹出隐私政策弹窗
先简单写这些吧,后续有空再整理补充
Android APP隐私权限整改相关推荐
- android APP隐私政策弹框的实现代码实例
android APP隐私政策弹框的实现代码实例 步骤一:在assets目录下放置隐私政策的文本文件,比如privacy.txt 步骤二:在drawable目录下放置圆角弹出框演示: <?xml ...
- 一种有效管控APP隐私权限的解决方案
引言 诸如读写外置存储.读取联系人.发短信等隐私权限,android在6.0系统开始进行动态授权.但在我国,仅向用户提示授权框还不够,工信部在19年11月初发布了专项整治App八类侵权行为审明 ,其文 ...
- Android 查看隐私权限方法调用者集合
文章目录 背景 技术目标 技术方案 技术实践 技术流程 自定义 lint 规则 总结 背景 辛辛苦苦迭代完当前版本,准备推送 App 到应用市场上架,却收到拒审通知:App隐私合规上架护航版检测报告, ...
- 没有授权,Android App 也能获取你的权限?!
Play Trick or Treat! 不给权限就捣乱! 整理 | 屠敏 出品 | CSDN(ID:CSDNnews) 一直以来,无论是 Android 还是 iOS 用户都有一种困扰,即每次下载并 ...
- minio 授予永久访问权限_没有授权,Android App 也能获取你的权限?!
Play Trick or Treat! 不给权限就捣乱! 整理 | 屠敏 出品 | CSDN(ID:CSDNnews) 一直以来,无论是 Android 还是 iOS 用户都有一种困扰,即每次下载并 ...
- Android底层隐私数据,100%安卓APP都在获取用户隐私,网络隐私进入深入区
原标题:100%安卓APP都在获取用户隐私,网络隐私进入深入区 (图片来源:全景视觉) 经济观察网 记者 任晓宁"很多时候用户对自己的隐私是麻木的,"腾讯社会研究中心总监王晓冰去年 ...
- Android App安全监测隐私权限工具及自测
1.参考文章[Android App]安全监测隐私权限工具及自测 图文详解_飞雪金灵的博客-CSDN博客_app权限检测工具 2.修改上文使用到的命令,即不在控制台输出日志,将日志输出到文件中 pyt ...
- android 获取app自启动权限状态_央视批手机App权限问题:频繁自启动 搜集个人隐私触目惊心...
近日据央视新闻报道,有网友反映自己手机上安装的App很多存在频繁自启动.访问.读取手机信息的现象.其中一款名为"优学院"的移动教学软件十多分钟读取近25000次手机照片和文件:而腾 ...
- Android APP过检安全整改
一.背景说明 金融类APP的安全整改,为了提高APP的安全性,达到相关机构的安全标准做的改进.先写个提纲,以后慢慢补充细节 二.改动项整理 报文加解密(RSA+AES,密钥安全保存).防重放 双向证书 ...
最新文章
- nodejs 获取文件夹中所有文件、图片 名
- DL之Mask R-CNN:2018.6.26世界杯阿根廷队VS尼日利亚比赛2:1实现Mask R-CNN目标检测
- 【TF-IDF】传统方法TF-IDF解决短文本相似度问题
- linux ora 00119,ORA-00119和ORA-00132的解决方案
- 【MongoDB】递归获取字段更新表达式,更新复杂数据类型对象
- 关于ajax请求后台获取下拉列表用的数据
- C++编程语言类对象的赋值与复制介绍(二)
- 软件学报 参考文献著录格式
- 建设工程项目全寿命周期管理是指_浅谈工程项目建设全寿命周期管理
- Kubernets:容器日志收集方案
- 通俗易懂的讲解梯度,散度,旋度(有图很好理解)!!!
- 网站建设对企业的好处有哪些?
- 语言表达能力强的人真的就情商高吗?
- JAVA基础篇(一)
- 读《富爸爸穷爸爸》有感
- 运动检测与跟踪之动态背景的更新
- 设计Date类,该类采用3个整型存储日期: month、 data和year。其函数成员具有按如下格式输出日期的功能(异常处理)
- 信息安全导论 实验一 古典密码学
- java 控制器的类型和作用,跳转页面的方式
- 使用phpStudy配置SSL支持Https
热门文章
- lua pairs顺序遍历 table(key必须为连续数值)
- bat脚本 获取当前所在文件夹的路径
- 【转】宇宙的基本法则
- 2017计算机一级选择题及答案,计算机一级MSoffice选择题及答案2017
- matlab parpool 报错,Matlab并行计算1
- 在CentOS 8.3中使用ifconfig添加虚拟网卡
- 全国省市区数据库,带拼音,简称,行政编码,邮政编码等
- 【Flutter】友盟智能认证Android Flutter插件集成
- hdu 1465 不容易系列之一(错位排序)
- 基于CUCM的思科设备的呼叫转移主叫和被叫问题