Android获取UID的新思路

本文讨论了在Android设备上获取稳定唯一标识符的挑战,如IMEI和AndroidID的限制。作者推荐使用应用内UUID,强调了隐私保护和开发者策略的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在 Android 设备中,获取唯一UID通常是个让程序员头疼的事情。大家都是各显神通来拼接 随机 存值等等。
例如这篇文章非常良心,各种尝试优缺点都有详述:Android Q 获取设备唯一ID(UDID\GUID\UUID\SSAID\GAID)

首先 我们获取UID,很多时候是想圈定一些非正常用户,我这里提供一种思路,例如公司做的是一个招聘类app,那么每次app冷启动时,可以获取微信app的安装时间。

如何获取呢?Android获取某个app首次安装时间和更新时间

获取结果分为三种情况

  1. 微信安装时间远远早于自己app安装时间
  2. 微信安装时间接近自己app安装时间
  3. 微信安装时间获取失败(未安装)

显而易见,1通常是正常用户,2值得怀疑,3要重点怀疑。不用解释,懂的都懂。

当然不同的市场,需要被锚定的app也不一样。例如国内用户,绝大多数正常用户的手机都会安装微信,如果是海外市场,可以锚定Tik Tok,或者直接锚定系统预装app:Google Play ,或者GMS相关的应用等。

以下是ChatGPT 4.0给出的解决方案,聊胜于无吧,营养有限。


在 Android 设备中,UID(User ID)通常指的是应用程序在安装时系统分配给它的唯一标识符。当设备被重置或应用被卸载再重新安装时,这个 UID 是会发生变化的。

要获取一个即使在设备重置或刷机后也不会改变的设备唯一标识符(设备UID),可以使用以下方法:

  1. IMEI (International Mobile Equipment Identity): 这是手机的硬件序列号,用于标识 GSM 和 UMTS 网络中的每个手机。但由于隐私和安全问题,从 Android 10 开始,非系统应用无法访问 IMEI。此外,对于平板电脑和没有电话功能的设备,它们可能根本没有 IMEI。

  2. 序列号 (Serial Number): 每部 Android 设备都有一个唯一的序列号,但是从 Android Oreo 8.0 开始,非系统应用无法访问设备的序列号。

  3. Android ID: 它是在第一次启动设备时随机生成的,并且在恢复出厂设置后可能会更改。因此,它并不完全靠谱如果需要跨设备重置保持唯一性。

  4. 广告ID (Advertising ID): 这是用户可以重置的、与用户 Google 账户相关的 ID。这主要用于广告目的,并不是一个固定不变的标识符。

要注意的是,出于用户隐私保护的原因,Android 不鼓励开发者跟踪设备的唯一标识符。因此,如果你需要为用户在你的应用内生成一个唯一标识符,最好的做法是在用户首次使用你的应用时创建一个 UUID 并将其持久存储在设备上。即使设备被重置,只要用户没有卸载应用,这个 UUID 就会保持唯一和不变。如果用户卸载了应用,则可以允许他们通过账号等信息来恢复自己的数据和设置。

根据当前的 Android 开发者策略和隐私政策,没有一种方法可以保证在所有情况下都能得到设备级别的唯一且不变的标识符。考虑使用基于账户的身份认证或在应用层面生成和管理唯一标识是一个更合适的选择。

<think>好的,我现在需要处理用户的问题:在Android 11上,当设备实际分辨率是480x800时,如何让指定应用显示为576x960。这涉及到修改WindowManagerService、WindowState或其他框架类。我需要逐步分析这个问题。 首先,用户的需求是让特定应用以更高的分辨率渲染,可能涉及到缩放或虚拟分辨率的设置。Android系统中,每个应用的窗口管理由WindowManagerService处理,而窗口的尺寸和位置则由WindowState等类管理。我需要回忆Android的窗口管理机制。 可能的实现思路是修改应用窗口的尺寸或应用一个缩放因子。在Android中,可以通过修改窗口的LayoutParams来调整大小,或者在计算窗口尺寸时应用缩放。例如,在WindowState计算窗口大小时,如果检测到目标应用,就应用一个缩放因子,比如将480x800放大到576x960,缩放因子为1.2(576/480=1.2,960/800=1.2)。 接下来,我需要确定在WindowManagerService的哪个环节进行干预。WindowState在计算窗口框架时,会考虑屏幕尺寸、父窗口限制等因素。可能需要重写WindowState的computeFrame函数,或者修改其mRequestedWidth和mRequestedHeight的值,但需要注意其他依赖这些值的地方,比如布局和测量。 另一个可能性是使用DisplayAdjustments或者创建虚拟的DisplayContent,为特定应用设置不同的显示配置。例如,通过覆盖应用的DisplayMetrics,调整density、scaledDensity等参数,让应用以为自己运行在更高分辨率的屏幕上,但这可能会影响布局的适配。 或者,利用Android的兼容模式,通过修改应用的Configuration或DisplayMetrics,调整屏幕尺寸和密度。这可能需要Hook相关的方法,例如在Activity启动时,为该应用设置特定的DisplayMetrics,或者在WindowManagerService中根据包名动态调整。 还需要考虑屏幕缩放对触摸事件的影响,如果窗口被放大,触摸坐标也需要相应调整。这可能涉及InputDispatcher的相关处理,确保触摸事件的位置正确映射到应用的虚拟分辨率上。 具体到代码层面,可能需要在WindowManagerService中找到处理窗口尺寸和布局的地方。例如,在WindowState的prepareWindowToDisplay过程中,或者在计算窗口框架时应用缩放。如果应用的目标是576x960,可能需要将实际的分辨率按比例缩放,比如在计算窗口大小时,将应用的请求宽度和高度乘以缩放因子,然后在布局时调整。 此外,Android 11的窗口管理可能使用了新的类或方法,比如DisplayPolicy或DisplayFrames,需要查阅相关版本的源码,确认修改点。例如,在DisplayPolicy的layoutWindowLw方法中,调整frame的大小,或者修改DisplayFrames中的参数。 还需要考虑系统权限和签名问题,因为修改WindowManagerService通常需要系统级权限,可能需要在自定义ROM或具有root权限的设备上实现。同时,需要确保修改不会导致其他应用或系统UI的布局错乱,因此需要精确控制只针对特定应用生效。 可能的步骤总结: 1. 在WindowManagerService中识别目标应用的窗口(通过包名或UID)。 2. 在计算窗口尺寸时应用缩放因子(如1.2倍),调整其requestedWidth/Height。 3. 修改窗口的frame尺寸,确保布局和绘制时使用缩放后的尺寸。 4. 调整输入事件坐标,匹配缩放后的窗口。 5. 测试并验证是否影响其他应用或系统稳定性。 需要确认的关键点包括如何正确识别目标应用,如何安全地修改窗口尺寸而不引起系统异常,以及如何处理可能出现的兼容性问题,例如应用本身对分辨率的适配。</think>在Android 11框架中实现应用级分辨率虚拟化,需通过WindowManagerService(WMS)和窗口状态控制,以下是实现步骤: --- ### 一、实现原理 通过拦截目标应用窗口的布局参数,在`WindowState`计算窗口尺寸时注入缩放因子(1.2倍),实现虚拟分辨率效果,同时需同步调整输入事件坐标。 --- ### 二、关键修改点 #### 1. **识别目标应用** - **Hook点**:在`WindowManagerService.addWindow()`中,通过`Session`获取应用包名或UID。 ```java // 伪代码:WindowManagerService.java public int addWindow(...) { String pkg = callingPackage; if (isTargetApp(pkg)) { // 标记为目标应用窗口 } } ``` #### 2. **修改窗口布局参数** - **Hook点**:在`WindowState.computeFrame()`中注入缩放逻辑。 ```java // 伪代码:WindowState.java private void computeFrame() { // 原始计算逻辑 mRequestedWidth = ...; mRequestedHeight = ...; if (isTargetApp) { mRequestedWidth *= 1.2; mRequestedHeight *= 1.2; } // 重新计算Frame mWindowFrames.set(...); } ``` #### 3. **调整DisplayMetrics(可选)** - 通过覆写目标应用的`DisplayMetrics`,使其认为屏幕尺寸为576x960。 ```java // 伪代码:ActivityThread.java public void handleBindApplication(...) { if (isTargetApp) { Resources res = appContext.getResources(); DisplayMetrics metrics = res.getDisplayMetrics(); metrics.widthPixels = 576; metrics.heightPixels = 960; metrics.density *= 1.2; // 同步调整密度 } } ``` #### 4. **输入事件坐标映射** - 在`InputDispatcher`中,对目标应用的输入事件应用反向缩放(坐标/1.2)。 ```cpp // 伪代码:InputDispatcher.cpp void InputDispatcher::dispatchMotion(...) { if (isTargetApp) { event.x /= 1.2; event.y /= 1.2; } } ``` --- ### 三、兼容性处理 1. **SurfaceFlinger同步**:确保`SurfaceControl`的Buffer尺寸正确缩放,避免图形撕裂。 2. **系统UI规避**:在`PhoneWindowManager`中过滤系统进程,避免影响状态栏/导航栏。 3. **生命周期管理**:监听应用切换,动态启用/禁用缩放逻辑。 --- ### 四、验证方法 1. **ADB命令检查窗口尺寸**: ```bash adb shell dumpsys window | grep "mRequested=" ``` 2. **截图分析**:通过`screenrecord`确认目标应用渲染区域是否扩大。 3. **输入事件测试**:验证触摸位置与应用响应是否一致。 --- ### 五、注意事项 - **系统签名**:需在自定义ROM或系统级APK中实现,要求`platform`签名。 - **版本差异**:Android 11的`WindowState`可能已重构,需参考AOSP `r31`代码确认具体实现。 - **性能影响**:缩放可能引入GPU额外开销,需测试渲染性能。 --- 通过以上修改,可实现指定应用在480x800物理分辨率下以576x960虚拟分辨率运行,需结合AOSP源码深度定制。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值