Unity 之 安卓平台上架隐私问题解决方案

news2024/12/26 23:04:35

Unity 之 助力游戏增长 -- 解决隐私问题

  • 一,平台测试隐私问题
  • 二,解决方式一
    • 2.1 勾选自定义Mainifest
    • 2.2 修改自定义Mainifest
    • 2.3 隐私协议弹窗逻辑
  • 三,解决方式二
    • 3.1 导出安卓工程
    • 3.2 创建上层Activity
    • 3.3 配置AndroidManifest
  • 四,源码分享

一,平台测试隐私问题

场景 1:
APP 未见向用户明示个人信息收集使用的目的、方式和范围,未经用户同意,存在收集 Android ID、SIM 卡信息的行为。(存在风险)

场景 2:
APP 未见向用户明示 SDK 收集使用个人信息的目的、方式和范围,未经用户同意,SDK 存在收集 com.unity3d.player 获 取 SIM 卡信息、com.unity3d.player 获取 Android ID 的行为。(存在风险)


二,解决方式一

在Unity启动前,添加Activity 用于进行隐私政策的展示和授权。

PS:不导出安卓工程直接打包apk的方式可以使用此解决方案,导出安卓工程的打包apk方式的看后面的方案二。

下面是在Unity中的操作步骤。

2.1 勾选自定义Mainifest

勾选自定义Mainifest。Project Settings --> Player --> Andorid–>Publishing Settings -->Custom Main Manifest

2.2 修改自定义Mainifest

最终的Mainifest截图:

添加代码释义:

  • 设置为主 Activity,当应用程序启动时。系统将会查找具有该 intent action 的 Activity 并将其作为默认启动界面。
    <action android:name="android.intent.action.MAIN" />

  • 设置为启动 Activity。 它将会在应用程序列表中显示一个应用图标,并且当用户点击次图标时,它将作为默认启动界面启动应用程序。
    <category android:name="android.intent.category.LAUNCHER" />

  • 添加网络访问权限
    <uses-permission android:name="android.permission.INTERNET"/>


最终的AndroidManifest源码:

<?xml version="1.0" encoding="utf-8"?>
<manifest
        xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.unity3d.player"
        xmlns:tools="http://schemas.android.com/tools">
    <application>
        <activity android:name="com.unity3d.player.PrivacyActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.unity3d.player.UnityPlayerActivity"
                  android:theme="@style/UnityThemeSelector">
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>

2.3 隐私协议弹窗逻辑

创建PrivacyActivity.java文件,路径:Assets/Plugins/Android/com.unity3d.player/PrivacyActivity.java

注意文件夹名称不要写错,因为Unity导出的安卓工程使用的就是com.unity3d.player路径。


使用时需将下面代码:隐私政策的描述和网络地址 修改为自己的项目需要的即可。代码注释比较详细不在赘述。

PrivacyActivity 代码如下:

package com.unity3d.player;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.webkit.WebView;
 
public class PrivacyActivity extends Activity implements DialogInterface.OnClickListener {

   // 隐私协议内容
   final String privacyContext =
             "欢迎使用本游戏,在使用本游戏前,请您充分阅读并理解 <a href=\"https://blog.csdn.net/czhenya\">" +
             "《用户协议》</a>和<a href=\"https://blog.csdn.net/czhenya\">《隐私政策》</a>各条;\n" +
     "1.保护用户隐私是本游戏的一项基本政策,本游戏不会泄露您的个人信息;\n" +
     "2.我们会根据您使用的具体功能需要,收集必要的用户信息(如申请设备信息,存储等相关权限);\n" +
     "3.在您同意App隐私政策后,我们将进行集成SDK的初始化工作,会收集您的android_id、Mac地址、IMEI和应用安装列表,以保障App正常数据统计和安全风控;\n" +
     "4.为了方便您的查阅,您可以通过“设置”重新查看该协议;\n" +
     "5.您可以阅读完整版的隐私保护政策了解我们申请使用相关权限的情况,以及对您个人隐私的保护措施。";
     
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
  
        // 如果已经同意过隐私协议则直接进入Unity Activity
        if (GetPrivacyAccept()){
            EnterUnityActivity();
            return;
        }
        // 弹出隐私协议对话框
        ShowPrivacyDialog();
    }
 
    // 显示隐私协议对话框
    private void ShowPrivacyDialog(){
        WebView webView = new WebView(this);
        webView.loadData(privacyContext, "text/html", "utf-8");         
        AlertDialog.Builder privacyDialog = new AlertDialog.Builder(this);
        privacyDialog.setCancelable(false);
        privacyDialog.setView(webView);
        privacyDialog.setTitle("提示");
        privacyDialog.setNegativeButton("拒绝",this);
        privacyDialog.setPositiveButton("同意",this);
        privacyDialog.create().show();
    }
    
    @Override
    public void onClick(DialogInterface dialogInterface, int i) {
        switch (i){
            case AlertDialog.BUTTON_POSITIVE://点击同意按钮
                SetPrivacyAccept(true);
                EnterUnityActivity(); //启动Unity Activity
                break;
            case AlertDialog.BUTTON_NEGATIVE://点击拒绝按钮,直接退出App
                finish();
                break;
        }
    }
    
    // 启动Unity Activity
    private void EnterUnityActivity(){
        Intent unityAct = new Intent();
        unityAct.setClassName(this, "com.unity3d.player.UnityPlayerActivity");
        this.startActivity(unityAct);
    }
    
    // 本地存储保存同意隐私协议状态
    private void SetPrivacyAccept(boolean accepted){
        SharedPreferences.Editor prefs = this.getSharedPreferences("PlayerPrefs", MODE_PRIVATE).edit();
        prefs.putBoolean("PrivacyAcceptedKey", accepted);
        prefs.apply();
    }
    
    // 获取是否已经同意过
    private boolean GetPrivacyAccept(){
        SharedPreferences prefs = this.getSharedPreferences("PlayerPrefs", MODE_PRIVATE);
        return prefs.getBoolean("PrivacyAcceptedKey", false);
    }
}

至此,就完成全部流程了,直接导出apk。运行会先弹出隐私界面,同意后才启动Unity


三,解决方式二

此方案适用于Unity项目导出Android工程后在打包apk的方式。逻辑同上,只是将上面在Unity里面的操作修改到Android工程中了。

操作步骤如下:

3.1 导出安卓工程

  1. 目标平台切换到Android
  2. 勾选Export Project
  3. 点击Export选择导出目录导出即可

导出后工程目录:

然后使用AndroidStudio打开即可


3.2 创建上层Activity

还是使用的上文2.3中的代码逻辑,在com.unity3d.player下创建PrivacyActivity把代码粘贴进去即可:

将工程模式调整成Project,即可看到下图一样的目录结构:


3.3 配置AndroidManifest

添加新的PrivacyActivity,然后将UnityPlayerActivity中的intent-filter 剪切上来:

<activity android:name="com.unity3d.player.PrivacyActivity"
        android:exported="true">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
</activity>


四,源码分享

实现逻辑就是在Unity启动前添加一个同意隐私的弹出,实现步骤就按照上面的操作即可,还有不明白的童鞋可以评论或私信,我看到就会及时回复。

为了便于以后其他项目复用,我导出UnityPackage和安卓工程进行保存:

工程源码
在这里插入图片描述
点击下面👇🏻卡片,回复 隐私 可获得上图解决隐私问题的源码工程~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/767058.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SOMEIP协议----第一节(概述)

SOMEIP协议 概述 1.什么是SOME/IP? SOME/IP: 如上图所述,连起来就是基于车载以太网技术的面向服务的可扩展中间件 汽车某ECU软件算法如果需要和其他ECU交互,大部分都通过跨ECU之间的服务来实现,即可以通过车载以太网异步调用其他ECU上的服务,应用开发者只需要关注服务…

携带时间戳主动写入数据到prometheus service

使用到的github公开项目 https://github.com/castai/promwrite 拉下来装依赖&#xff0c;然后使用 client_test.go t.Run(“write with custom options”, func(t *testing.T) 这个测试用例里面&#xff0c;删掉srv初始化的部分&#xff0c;这个是模拟一个客户端&#xff0c;直…

MySQL数据备份与恢复

目录 ​编辑 一、数据备份 1.1物理备份 1.1.1冷备份 1.1.2热备份 1.1.3温备份 二、逻辑分区 2.1完全分区 2.2差异分区 2.3增量备份 三、数据备份恢复实验 3.1做一个数据 3.2物理冷备份与恢复 3.3mysqldump 备份与恢复&#xff08;温备份&#xff09; 3.4Mysql数据…

mmdetection3.1.0 训练自己的数据集

目录 前言安装mmcv安装mmdetection验证安装数据集转为COCO划分训练集、验证集及测试集安装PaddlePaddle安装PaddleX划分数据集 修改对应文件修改coco.py重新安装修改模型文件 训练测试测试带真值的图像测试不带真值的图像批量测试 错误集锦ValueError: need at least one array…

设计模式 ~ 发布订阅者

发表订阅者模式 用于实现对象之间的松耦合通信&#xff1b; 在该模式中&#xff0c;存在一个或多个发布者&#xff08;Publishers&#xff09;和一个或多个订阅者&#xff08;Subscribers&#xff09;&#xff1b; 发布者负责发布消息&#xff0c;而订阅者负责订阅感兴趣的消息…

C++中的“三重”

博文内容&#xff1a;重载、重定义&#xff08;隐藏&#xff09;&#xff0c;重写&#xff08;覆盖&#xff09; 三重区别及联系 概念联系及区别1、作用域2、函数要求 概念 重载 函数名相同,函数的参数列表不同(包括参数个数和参数类型)&#xff0c;至于返回类型可同可不同。 …

如何应对黑产进行验证图片资源遍历

第一期&#xff0c;我们分享的攻防点是&#xff1a;验证图片资源遍历。 “遍历”指黑产通过穷举法获得所有验证码图片的答案&#xff0c;以便能在未来彻底无视验证码。由于验证码主要是通过图片语义答案来识别人机&#xff0c;因此攻破这层防御最有效的方式就是遍历该验证码图…

【电路原理学习笔记】第4章:能量与功率:4.4 能量转换与电阻的电压降

第4章&#xff1a;能量与功率 4.4 能量转换与电阻的电压降 图4-11以电子作为电荷进行举例说明&#xff0c;电子从电池的负极流过电路&#xff0c;然后流回正极。当它们从负极出来时&#xff0c;电子具有最高的能量水平。电子流经过每个电阻&#xff0c;这些电阻连接在一起形成…

微信要怎么定时自动发布朋友圈呢?

大家都知道&#xff0c;朋友圈营销在当今十分重要。对于那些做了私域的人来说&#xff0c;他们知道这可以给自己带来多少的收益。最近&#xff0c;很多客户都纷纷向我咨询朋友圈发圈的问题。客户们认为朋友圈多号操作很费事&#xff0c;拥有多个号容易漏发&#xff1b;若看到同…

【Ceph集群应用】Ceph对象存储系统之RGW接口详解

Ceph对象存储系统之RGW接口详解 1.创建Ceph对象存储系统RGW接口2. 开启httphttps,更改监听端口3. 更改监听端口4.S3接口访问测试5.实验中遇到的故障案例 接上文基于ceph-deploy部署Ceph集群详解 1.创建Ceph对象存储系统RGW接口 &#xff08;1&#xff09;对象存储概念 对象存…

【C语言】杨氏矩阵中寻找元素

题目名称&#xff1a; 杨氏矩阵 题目内容&#xff1a; 有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从下到上递增的&#xff08;杨氏矩阵的定义&#xff09;&#xff0c;请编写程序在这样的矩阵中查找某个数字是否存在。 形如这样的矩阵就是杨氏…

基于51单片机和proteus的八路抢答器系统

此系统是基于51单片机和proteus的仿真设计&#xff0c;功能如下&#xff1a; 1. 分别采集八路抢答器按键输入信号和系统按键信号。 2. 检测到按键输入后蜂鸣器发出提示音。 3. 数码管显示八路中首次按下的按键。 4. 重置按键可重置系统&#xff0c;重新抢答。 功能框图如下…

【文生图系列】stable diffusion webui 汉化(双语)教程

文章目录 安装双语插件下载json源文件设置双语 这篇博文记录于我成功安装双语插件之后&#xff0c;所以以下的示例页面均是双语。汉化教程分为三步&#xff0c;安装插件&#xff0c;JSON源文件下载和最后一步的双语设置。 安装双语插件 在扩展&#xff08;extensions&#xf…

HCIA作业(一)

题目 实现Client1能够通过域名www.baidu.com来获取Serverlet1&#xff08;Http服务器&#xff09;所放置的文件 配置信息 Servlet1配置&#xff1a; PC1配置&#xff1a; PC2配置&#xff1a; Client1配置&#xff1a; Servlet2配置&#xff1a; AR1配置&#xff1a; 结果

ceph集群(二)

ceph 一、资源池 Pool 管理二、创建 CephFS 文件系统 MDS 接口三、创建 Ceph 块存储系统 RBD 接口四、创建 Ceph 对象存储系统 RGW 接口五、OSD 故障模拟与恢复 一、资源池 Pool 管理 上次我们已经完成了 Ceph 集群的部署&#xff0c;但是我们如何向 Ceph 中存储数据呢&#x…

problem(1):VMware网络虚拟编辑器添加VMnet0+IDA远程调试

VMware网络虚拟编辑器添加VMnet0 桥接模式&#xff1a;由于VMnet0是跟桥接模式有关系的&#xff0c;是ping通的条件&#xff0c;所以很重要。是IDA远程调试的 关键&#xff08;remote window debugger&#xff09; NAT模式&#xff1a;外部网络&#xff08;桥接模式&#xff…

Pyhon:串口应用及数据解析过程

Pyhon:串口应用及数据解析过程 串口通信是一种常用的通信协议&#xff0c;本文重点记录在Python中使用串口&#xff0c;并且以一款电源保护板的串口数据协议为例&#xff0c;对其进行解析&#xff0c;记录收发过程中对16进制数据进行转换的过程。 1. 调用串口 在Python中进行…

浅谈HTTPS抓包原理,为什么Charles能够抓取HTTPS报文?

Charles作用其实相当于拦截器&#xff0c;当客户端和服务器通信时&#xff0c;Charles其实会先接收到服务器的证书&#xff0c;但是它会自己生成一个证书发送给客户端(不管是Web端或App应用)&#xff0c;也就是说它不仅仅是拦截&#xff0c;甚至还可以修改。 由于Charles更改了…

[数据结构 -- 手撕排序算法第六篇] 递归实现快速排序(集霍尔版本,挖坑法,前后指针法为一篇的实现方法,很能打)

目录 1、常见的排序算法 1.1 交换排序基本思想 2、快速排序的实现方法 2.1 基本思想 3 hoare&#xff08;霍尔&#xff09;版本 3.1 实现思路 3.2 思路图解 3.3 为什么实现思路的步骤2、3不能交换 3.4 hoare版本代码实现 3.5 hoare版本代码测试 4、挖坑法 4.1 实现…

SpringCloud(六)Config配置中心

一、配置中心 官方文档&#xff1a;**https://docs.spring.io/spring-cloud-config/docs/current/reference/html/ 经过前面的学习&#xff0c;我们对于一个分布式应用的技术选型和搭建已经了解得比较多了&#xff0c;但是如果我们的微服务项目需要部署很多个实例&#xff0c…