【1——Android端添加隐私协议(unity)1/3】
前言:这篇仅对于unity 发布Android端上架国内应用商店添加隐私协议,隐私协议是很重要的东西,没有这个东西,是不上了应用商店的。
对于仅仅添加隐私协议,我知道有三种方式,第一种和第二种基本一样
1.直接在unity里面新建PrivacyActivity.java,然后自定义一下AndroidManifest,就可以(就是直接在unity里面建java类了)(复杂度 低)
2.从Android studio 里面打出arr包,导入unity 里面使用 (复杂度 高)
3.从unity里面导出android studio 工程,在Android studio里面添加 (复杂度 高)
如何选择,这三种方法,我个人建议,如果只是添加隐私协议这种简单的需求,第一种就可以。我会实际演示这三种方式
以下是第二和第三方法的优缺点对比:
方法 | 优点 | 缺点 |
---|---|---|
从 Android Studio 导出 AAR 包到 Unity | 1. 灵活性高,可以专注于 Android 原生代码的开发,而 Unity 负责游戏逻辑和渲染。 2. 适合需要在 Unity 中调用 Android 原生功能的场景,比如调用 Android 的 API 或第三方 SDK。 3. AAR 包可以独立于 Unity 项目开发和维护,便于模块化管理。 | 1. 需要额外的步骤来确保 AAR 包与 Unity 的兼容性,比如导入 classes.jar 和处理资源文件冲突。 2. 如果需要频繁修改 Android 代码,每次都需要重新导出 AAR 包并更新 Unity 项目,流程相对繁琐。 |
从 Unity 导出 Android Studio 工程,在 Android Studio 里面添加 | 1. 适合需要对 Unity 生成的 Android 项目进行深度定制的场景,比如修改 Gradle 配置、添加原生代码或第三方库。 2. 可以直接在 Android Studio 中调试和优化 Unity 生成的代码,便于解决复杂的构建问题。 | 1. Unity 导出的 Android 工程结构复杂,包含大量自动生成的代码,可能增加开发和维护的难度。 2. 如果需要频繁在 Unity 和 Android Studio 之间切换开发,可能会导致项目文件的不一致。 |
因为这个字数比较多,我先介绍一下第三中,第一二种,后续会更新
三.第三种方法
从unity里面导出android studio 工程,在Android studio里面添加
步骤介绍,四步走
- 第一步从unity打包出Android studuio 工程文件
- - 第二步 使用Android studio 打开项目
-
我这里选的是Use Android Studio SDK,点击完成后,就打开了
- 第三步,新建一个软件包,(我们把自己写逻辑代码都放在里面,比如隐私协议啊,或者微信登录支付什么的都可以放在这里,软件包的本质就是一个文件夹),具体步骤如下图
右上角,视图选择为项目,Android studio 好几种视图模式,我们这里选择项目
- 第四步,在com.companyName.projcetName,文件夹下新建一个PrivacyActvity活动,(实现我们隐私协议部分),并替换代码,具体如下图
package com.companyName.projectName; //这里修改为你的包名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.util.TypedValue;
import android.webkit.WebView;public class PrivacyActivity extends Activity implements DialogInterface.OnClickListener {private static final String PREFS_NAME = "PlayerPrefs"; // SharedPreferences的文件名private static final String PRIVACY_ACCEPTED_KEY = "PrivacyAcceptedKey"; // 用于存储用户是否同意隐私政策的键@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 检查用户是否已经同意隐私政策if (getPrivacyAccept()) {// 如果已经同意,直接进入Unity主ActivityenterUnityActivity();return;}// 如果未同意,显示隐私政策对话框showPrivacyDialog();}private String buildPrivacyHtml() {// 在这里设置隐私政策和用户协议的链接,修改为你的String userAgreementUrl = "https://blog.csdn.net/weixin_45478456?type=blog";String privacyPolicyUrl = "https://blog.csdn.net/weixin_45478456?type=blog";// 动态生成隐私政策的HTML内容return "欢迎使用本应用,在使用本应用前,请您充分阅读并理解 " +"<a href=\"" + userAgreementUrl + "\">《用户协议》</a>和" +"<a href=\"" + privacyPolicyUrl + "\">《隐私政策》</a>各条;" +"<br/>" +"1.保护用户隐私是本应用的一项基本政策,本应用不会泄露您的个人信息;" +"<br/>" +"2.我们会根据您使用的具体功能需要,收集必要的用户信息(如申请设备信息,存储等相关权限);" +"<br/>" +"3.在您同意App隐私政策后,我们将进行集成SDK的初始化工作,会收集您的android_id、Mac地址、IMEI和应用安装列表,以保障App正常数据统计和安全风控;" +"<br/>" +"4.为了方便您的查阅,您可以通过“设置-关于我们”重新查看该协议;" +"<br/>" +"5.您可以阅读完整版的隐私保护政策了解我们申请使用相关权限的情况,以及对您个人隐私的保护措施。";}private void showPrivacyDialog() {// 创建一个WebView用于显示隐私政策的HTML内容WebView webView = new WebView(this);webView.loadData(buildPrivacyHtml(), "text/html", "utf-8");// 创建一个不可取消的对话框AlertDialog.Builder privacyDialog = new AlertDialog.Builder(this);privacyDialog.setCancelable(false);privacyDialog.setView(webView); // 设置WebView为对话框的内容视图privacyDialog.setTitle("提示"); // 设置对话框标题// 设置“拒绝”按钮,并指定点击事件监听器privacyDialog.setNegativeButton("拒绝", this);// 设置“同意”按钮,并指定点击事件监听器privacyDialog.setPositiveButton("同意", this);// 创建并显示对话框privacyDialog.create().show();}@Overridepublic void onClick(DialogInterface dialogInterface, int i) {// 处理对话框按钮点击事件switch (i) {case AlertDialog.BUTTON_POSITIVE:// 如果点击了“同意”按钮setPrivacyAccept(true); // 保存用户同意隐私政策的状态enterUnityActivity(); // 进入Unity主Activitybreak;case AlertDialog.BUTTON_NEGATIVE:// 如果点击了“拒绝”按钮finish(); // 结束当前Activity,退出应用break;}}private void enterUnityActivity() {// 创建一个Intent,用于启动Unity主ActivityIntent unityAct = new Intent();unityAct.setClassName(this, "com.unity3d.player.UnityPlayerActivity");startActivity(unityAct);}private void setPrivacyAccept(boolean accepted) {// 使用SharedPreferences保存用户是否同意隐私政策的状态SharedPreferences.Editor prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit();prefs.putBoolean(PRIVACY_ACCEPTED_KEY, accepted);prefs.apply(); // 提交更改}private boolean getPrivacyAccept() {// 从SharedPreferences中获取用户是否同意隐私政策的状态,默认为falseSharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);return prefs.getBoolean(PRIVACY_ACCEPTED_KEY, false);}}
代码关键处都注释了,不懂,拿代码直接问AI就好
- 第五步,替换AndroidManifest.xml里的内容,具体如图,代码在图下面(!注意,这里的内容和第一个,第二个方法里的不同)
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><uses-permission android:name="android.permission.INTERNET" /><uses-feature android:glEsVersion="0x00030000" /><uses-featureandroid:name="android.hardware.vulkan.version"android:required="false" /><uses-featureandroid:name="android.hardware.touchscreen"android:required="false" /><uses-featureandroid:name="android.hardware.touchscreen.multitouch"android:required="false" /><uses-featureandroid:name="android.hardware.touchscreen.multitouch.distinct"android:required="false" /><application android:extractNativeLibs="true"><activityandroid:name="com.companyName.projectName.PrivacyActivity"android:exported="true"><!-- 添加以下 intent-filter --><intent-filter><category android:name="android.intent.category.LAUNCHER" /><action android:name="android.intent.action.MAIN" /></intent-filter></activity><meta-dataandroid:name="unity.splash-mode"android:value="0" /><meta-dataandroid:name="unity.splash-enable"android:value="True" /><meta-dataandroid:name="unity.launch-fullscreen"android:value="True" /><meta-dataandroid:name="unity.render-outside-safearea"android:value="True" /><meta-dataandroid:name="notch.config"android:value="portrait|landscape" /><meta-dataandroid:name="unity.auto-report-fully-drawn"android:value="true" /><activityandroid:name="com.unity3d.player.UnityPlayerActivity"android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"android:exported="true"android:hardwareAccelerated="false"android:launchMode="singleTask"android:resizeableActivity="false"android:screenOrientation="fullUser"android:theme="@style/UnityThemeSelector"><meta-dataandroid:name="unityplayer.UnityActivity"android:value="true" /><meta-dataandroid:name="notch_support"android:value="true" /></activity></application></manifest>
- 第六步,打包测试,我这里用的是雷电模拟器测试,步骤如下
先打开雷电模拟器
等待一会,就可以在模拟器里看到了
这样子就OK啦
如果想打包出正式版本,打包出apk的话,大致步骤如下图
填写好之后,无脑下一步
成功后,去下图项目这个文件夹就可以找到apk
至此,结束,如果简单添加隐私协议个人推荐第一种或者直接使用我打包好的第二种方法的arr包。我使用第三种只是因为公司电脑环境复杂,无法打包出来,修了一天,试了N多种方法没解决,又不能重装,所以才使用第三种。 如果有任何疑问,可以私信联系我,尽量回复。个人拙作,欢迎斧正、转载。
相关文章:

【1——Android端添加隐私协议(unity)1/3】
前言:这篇仅对于unity 发布Android端上架国内应用商店添加隐私协议,隐私协议是很重要的东西,没有这个东西,是不上了应用商店的。 对于仅仅添加隐私协议,我知道有三种方式,第一种和第二种基本一样 1.直接在unity里面新…...

Linux之概述和安装vm虚拟机
文章目录 操作系统概述硬件和软件操作系统常见操作系统 初识LinuxLinux的诞生Linux内核Linux发行版 虚拟机介绍虚拟机 VMware WorkStation安装虚拟化软件VMware WorkStation 安装查看VM网络连接设置VM存储位置 在VMware上安装Linux(发行版CentOS7)安装包获取CentOS7 安装 Mac系…...
深入理解 Linux 的 set、env 和 printenv 命令
在 Linux 和类 Unix 系统中,环境变量是配置和管理 Shell 及进程行为的核心机制。set、env 和 printenv 是与环境变量交互的三个重要命令,每个命令都有其独特的功能和用途。本文将详细探讨这三个命令的区别,帮助大家更好地理解和使用这些命令。…...

LeetCode热题100--19.删除链表的倒数第N个结点--中等
1. 题目 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head [1,2,3,4,5], n 2 输出:[1,2,3,5] 示例 2: 输入:head [1], n 1 输出:[] 示例…...
开发AR导航助手:ARKit+Unity+Mapbox全流程实战教程
引言 在增强现实技术飞速发展的今天,AR导航应用正逐步改变人们的出行方式。本文将手把手教你使用UnityARKitMapbox开发跨平台AR导航助手,实现从虚拟路径叠加到空间感知的完整技术闭环。通过本教程,你将掌握: AR空间映射与场景理…...

git学习与使用(远程仓库、分支、工作流)
文章目录 前言简介git的工作流程git的安装配置git环境:git config --globalgit的基本使用新建目录初始化仓库(repository)添加到暂存区新增/修改/删除 文件状态会改变 提交到仓库查看提交(commit)的历史记录git其他命令…...
嵌入式预处理链接脚本lds和map文件
在嵌入式开发中,.lds.S 文件是一个 预处理后的链接脚本(Linker Script),它结合了 C 预处理器(Preprocessor) 的功能和链接脚本的语法。它的核心作用仍然是 定义内存布局和链接规则,但通过预处理…...
9. Spring AI 各版本的详细功能与发布时间整理
目录 一、旧版本(Legacy) 0.8.1(2024年3月) 二、里程碑版本(Milestone) 1.0.0-M1(2024年5月30日) 1.0.0-M2(2024年7月) 1.0.0-M3(2024年10月8日) 1.0.0-M4(2024年12月) 1.0.0-M5(2025年1月9日) 1.0.0-M6(2025年3月) 1.0.0-M7(2025年4月14日) 1.…...

《Android 应用开发基础教程》——第十四章:Android 多线程编程与异步任务机制(Handler、AsyncTask、线程池等)
目录 第十四章:Android 多线程编程与异步任务机制(Handler、AsyncTask、线程池等) 🔸 14.1 为什么需要多线程? 🔸 14.2 Handler Thread 模型 ✦ 使用 Handler 与 Thread 进行线程通信 ✦ 简要说明&am…...
Apache 高级配置实战:从连接保持到日志分析的完整指南
Apache 高级配置实战:从连接保持到日志分析的完整指南 前言 最近在深入学习 Apache 服务器配置时,发现很多朋友对 Apache 的高级功能还不够了解。作为一个在运维路上摸爬滚打的技术人,我想把这些实用的配置技巧分享给大家。今天这篇文章会带…...
开源 OIDC(OpenID Connect)身份提供方(IdP)、iam选型
文章目录 开源 OIDC(OpenID Connect)身份提供方(IdP)、iam选型主流开源 OIDC(OpenID Connect)身份提供方(IdP)zitadeldexory开源 OIDC(OpenID Connect)身份提供方(IdP)、iam选型 主流开源 OIDC(OpenID Connect)身份提供方(IdP) 当前主流的**开源 OIDC(OpenI…...
Android OkHttp控制链:深入理解网络请求的流程管理
OkHttp作为Android和Java平台上广泛使用的HTTP客户端,其核心设计之一就是"控制链"(Chain)机制。本文将深入探讨OkHttp控制链的工作原理、实现细节以及如何利用这一机制进行高级定制。 一、什么是OkHttp控制链 OkHttp控制链是一种责任链模式的实现&#…...

【JVM 01-引言入门篇】
JVM 引言篇01 笔记记录 1. 什么是JVM?2. 学习JVM有什么用?3. 常见的JVM4. 学习路线 学习资料来源-b站黑马 1. 什么是JVM? 定义:Java虚拟机(Java Virtual Machine 简称JVM)是运行所有Java程序的抽象计算机&a…...

Pandas数据规整
(1)层次化索引 1.创建带层次化索引的df 第一种,直接创建 import pandas as pd import numpy as npdata pd.Series(np.random.randn(9),index [[a, a, a, b, b, c, c, d, d],[1, 2, 3, 1, 3, 1, 2, 2, 3]]) print(data) # a 1 -0.6416…...

ThreadLocal线程本地变量在dubbo服务使用时候遇到的一个坑
我昨天遇到一个问题,就是我springboot项目里面有一个提供代办服务审核的dubbo接口,这个接口给房源项目调用,但是碰到一个问题就是,房源项目每天凌晨5点会查询满足条件过期的数据,然后调用我这边的代办审核dubbo接口&am…...
pga 作用
Oracle pga的作用 PGA 内存结构与功能解释: PGA ├── 1. Private SQL Area ├── 2. Session Memory ├── 3. SQL Work Areas │ ├── Sort Area │ ├── Hash Area │ ├── Bitmap Merge Area │ └── Bitmap Create Area └── 4. Stack S…...
setup.py Pip wheel
. ├── my_package │ ├── __init__.py │ └── my_file.py └── setup.pymy_file.py def my_func():print("Hello World")setup.py from setuptools import setup, find_packages import datetimesetup(namemy_package, # 记得改version0.1.1,packag…...
GO 语言进阶之 时间处理和Json 处理
更多个人笔记见: github个人笔记仓库 gitee 个人笔记仓库 个人学习,学习过程中还会不断补充~ (后续会更新在github上) 文章目录 时间处理基本例子 Json处理基础案例 时间处理 时间格式化必须使用:2006-01-…...
对WireShark 中的UDP抓包数据进行解析
对WireShark 中的UDP抓包数据进行解析 本文尝试对 WireShark 中抓包的 UDP 数据进行解析。 但是在尝试对 TCP 中的 FTP 数据进行解析的时候,发现除了从端口号进行区分之外, 没有什么好的方式来进行处理。 import numpy as np import matplotlib.pyplot …...
Flannel后端为UDP模式下,分析数据包的发送方式(二)
发往 10.244.2.5 的数据包最终会经过物理网卡 enp0s3,尽管路由表直接指定通过 flannel.1 发出。以下以 Markdown 格式详细解释为什么会经过 enp0s3,结合 Kubernetes 和 Flannel UDP 模式的背景。 问题分析 在 Kubernetes 环境中,使用 Flanne…...

从 0 到 1:Spring Boot 与 Spring AI 深度实战(基于深度求索 DeepSeek)
在人工智能技术与企业级开发深度融合的今天,传统软件开发模式与 AI 工程化开发的差异日益显著。作为 Spring 生态体系中专注于 AI 工程化的核心框架,Spring AI通过标准化集成方案大幅降低 AI 应用开发门槛。本文将以国产大模型代表 ** 深度求索ÿ…...

upload-labs通关笔记-第20关 文件上传之杠点绕过
系列目录 upload-labs通关笔记-第1关 文件上传之前端绕过(3种渗透方法) upload-labs通关笔记-第2关 文件上传之MIME绕过-CSDN博客 upload-labs通关笔记-第3关 文件上传之黑名单绕过-CSDN博客 upload-labs通关笔记-第4关 文件上传之.htacess绕过-CSDN…...

Vscode +Keil Assistant编译报错处理
Vscode Keil Assistant编译报错处理 1.报错图片内容 所在位置 行:1 字符: 25 chcp.com 65001 -Command & c:\Users\92170.vscode\extensions\cl.keil-a … ~ 不允许使用与号(&)。& 运算符是为将来使用而保留的;请用双引号将与号引起来(“&”)&…...
记录python在excel中添加一列新的列
思路是,先将需要添加为新的列存储到一个暂时的列表中,然后用到以下函数来存储 data_.loc[:, "新列的名字"] save_list_ 上面的save_list_就是暂时存储了信息的列表了。 以下是我的代码,供以后快速回忆。 schools_data {"98…...
WebRTC:实时通信的未来之路
WebRTC:实时通信的未来之路 目录 WebRTC:实时通信的未来之路一、背景介绍二、使用方式三、前途展望 一、背景介绍 随着互联网的飞速发展,实时音视频通信需求日益增长。传统的音视频通信多依赖于专有协议和插件(如Flash、ActiveX等…...
探索产品经理的MVP:从概念到实践
在产品开发的世界里,MVP(Minimum Viable Product,最小可行产品)是一个至关重要的概念。它不仅帮助团队快速验证假设,还能降低失败风险,为后续的产品迭代奠定坚实的基础。本文将深入探讨MVP的概念、重要性及…...
用python实现中国象棋
一.象棋规则 象棋是二人对弈的棋类游戏,棋盘由 9 条竖线和 10 条横线交叉构成,中间 “河界” 分楚汉,两端 “九宫” 各 9 个交叉点。棋子分红黑,各 16 枚,含 7 兵种。 1.棋子走法 1.1 红方棋子 帅:1 个…...
GO 语言基础3 struct 结构体
更多个人笔记见: github个人笔记仓库 gitee 个人笔记仓库 个人学习,学习过程中还会不断补充~ (后续会更新在github上) 文章目录 strcut结构体基本例子传入数值和指针的区别初始化方法汇总结构体特点结构体方法定义基于…...

VSCode C/C++ 开发环境完整配置及一些扩展用途(自用)update:2025/3/31
这里主要记录了一些与配置相关的内容。由于网上教程众多,部分解决方法并不能完全契合我遇到的问题,因此我选择以自己偏好的方式,对 VSCode 进行完整的配置,并记录在使用过程中遇到的问题及解决方案。后续内容也会持续更新和完善。…...
iOS 上线前的性能与稳定性检查流程实录:开发者的“最后一公里”(含 KeyMob 应用经验)
一个 iOS 项目写完功能、跑完测试,离上线只差一步了——但很多问题恰恰就在“这最后一公里”暴露:某些设备发热严重,部分流程偶发卡顿,某些崩溃只有长时间运行后才出现。 今天我分享的是我在多个 iOS 项目上线前实际执行过的性能…...