Android 获取手机名称

您所在的位置:网站首页 微信登录设置管理出现安卓设备和手机型号 Android 获取手机名称

Android 获取手机名称

2024-07-10 00:12| 来源: 网络整理| 查看: 265

1. 需求

在这里插入图片描述 获取框中的手机名称,注意这里与其他文章不一样的地方,这个手机名称可以修改,并且会作用于蓝牙以及热点等功能。

2. 问题分析

首先查阅了网上关于获取手机名称或者设备名称的解决方案,一般包括两种:

2.1 Build.MODEL

显然这个名称与目标完全不符,自行尝试

2.2 BluetoothAdapter.getName()

这个是一个解决方法,但是当关闭蓝牙后再修改手机名称的话,通过这个方式获取的是旧名称,修改后的名称获取不到

也就是说,网上给出的解决方法已经到了尽头,需要自己找个解决方案,那么我的分析思路:

先查看Build.MODEL源码,发现最后是通过SystemProperties.get(property, UNKNOWN)得到属性,传入的值是属性对应的键,比如MODEL对应ro.product.model,那么手机名称是否也是类似的键值属性呢;搜索ro.product.model和SystemProperties相关的内容,我了解了它确实是可以获取系统属性的,我感觉手机名称也属于系统属性,因此继续搜索下去;后来查到了通过命令adb shell getprop > prop.txt可以导出系统属性,那么我来看看结果是什么,果然,这个文件中包括了“小米手机”这个名称,然后修改名称再看一次,发现确实是对应的,那么我们就获得了key:persist.sys.device_name,同时找到ro.product.model对应的值,这样就确定可以通过SystemProperties得到结果;又因为SystemProperties不能直接使用,那么寻找其他办法,显然可以通过反射使用get方法,那么就尝试一下,当然还有另一个方式就是通过代码执行cmdgetprop,这里就仅用反射吧。 [persist.sys.dalvik.vm.lib.2]: [libart.so] [persist.sys.datastall.detect]: [0] [persist.sys.device_name]: [小米手机] [persist.sys.enable_inputopts]: [true] [persist.sys.enable_ioprefetch]: [false] 3. 代码

通过反射将key传入,得到deviceName,最终任务完成,搞定

String deviceName = ""; try{ Class cls = Class.forName("android.os.SystemProperties"); Object object = (Object) cls.newInstance(); Method getName = cls.getDeclaredMethod("get", String.class); deviceName = (String) getName.invoke(object, "persist.sys.device_name"); } catch (Exception e){ e.printStackTrace(); } 4. 测试

MIUI可以,其他系统GG,其他系统类似华为、三星都失败了,从prop.txt文件来看,并没有将谁被名称存在系统配置文件中。那么问题来了,这个属性去哪了?

5. 再分析

如果从目标往前走已经是死路了,那么不妨从前往后走,我们从设置手机名称这个地方寻找它调用了什么方法,说不定就能发现一些东西。

显然,Android开源的优势体现出来,在查询了Google关于Android的源码后我发现,在关于手机这个界面,保存和获取手机名称都是在一个类叫做DeviceManager中实现的,具体相关的两部分代码为

package com.android.tv.settings.name; import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.provider.Settings; public class DeviceManager { /** * Retrieves the name from Settings.Global.DEVICE_NAME * * @param context A context that can access Settings.Global * @return The device name. */ public static String getDeviceName(Context context) { return Settings.Global.getString(context.getContentResolver(), Settings.Global.DEVICE_NAME); } /** * Sets the system device name. * * For now it will explicitly call the different discoverable services that haven't been ported * to use the Settings.Global.DEVICE_NAME entry. * * @param context A context that can access Settings.Global * @param name The new device name. */ public static void setDeviceName(Context context, String name) { Settings.Global.putString(context.getContentResolver(), Settings.Global.DEVICE_NAME, name); BluetoothAdapter.getDefaultAdapter().setName(name); } }

由上面的代码可知,原生Android在保存设备名称时会同时保存蓝牙的名称,而获取名称时是从Settings.Global中获取的,因此如果我们要在代码里得到设备名称,理论上应该也可以通过Settings.Global得到。

但是,根据我的测试,小米/三星/华为这三家都将Settings.Global设置为一个定值,也就是说,他们修改了这里的存储逻辑,在不知道系统源码的情况下我们应该是拿不到设别名称,除非通过蓝牙得到(但是蓝牙获取有Bug),而小米是个例外,他存储设备名称的位置被我碰巧找到了,所以这个需求还是没办法完美的实现,主要是各个Android厂商背锅。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3