DeviceId和应用程序权限

时间:2013-12-31 17:35:22

标签: android android-permissions

我的应用程序(S Educate)要求我获取DeviceId(用于Analytics / Recommendations),因此我添加了权限READ_PHONE_STATE,尽管documentation无害,但当用户安装时,应用程序权限窗口显示“电话呼叫 - 监控,记录和处理电话”,这显然会阻止用户安装,并且用户只是因为此权限而已通知他们没有安装。

screenshot
屏幕截图(点击查看大图)

以下是我的选择:

  1. 我在我的应用说明中明确指出,我需要此权限才能获取DeviceId,而不是监控/录制电话,并希望用户相信我并安装应用
  2. 我找到另一种获取DeviceId的方法 - 据我所知,如果不使用上述许可,则无法使用
  3. 请告知我如何解决此许可问题。

3 个答案:

答案 0 :(得分:8)

请使用an app-generated UUID。这样您就可以在不侵犯用户隐私的情况下将一个应用安装与另一个应用安装区分开来。

答案 1 :(得分:4)

您可以通过多种方式在Android中检索唯一设备ID。

  1. IMEI(为此,您需要在Manifest中添加READ_PHONE_STATE权限)
  2. 伪唯一ID(无需添加READ_PHONE_STATE权限)
  3. Android ID
  4. MAC地址
  5. 查看以下详细信息。 http://www.pocketmagic.net/2011/02/android-unique-device-id/#.UsMCatIW2vE

答案 2 :(得分:0)

来自Android Developers Blog

  

过去,当每个Android设备都是手机时,事情就更简单了:TelephonyManager.getDeviceId()需要返回(取决于网络技术)手机的IMEI,MEID或ESN,这是唯一的那件硬件。

Mac地址

  

可以从设备的WiFi或其中检索Mac地址   蓝牙硬件。我们不建议将此作为唯一使用   标识符。首先,并非所有设备都具有WiFi。另外,如果   WiFi未开启,硬件可能无法报告Mac地址。

序列号

  

自Android 2.3(“Gingerbread”)以来,这可以通过   android.os.Build.SERIAL。没有电话的设备是必需的   在此处报告唯一的设备ID;有些手机也可以这样做。

<强> ANDROID_ID

  

更具体地说,是Settings.Secure.ANDROID_ID。这是一个64位   设备首次启动时生成和存储的数量。它   擦除设备时重置。

     

ANDROID_ID似乎是唯一设备标识符的不错选择。那里   是缺点:首先,它在Android版本上并非100%可靠   2.2之前(“Froyo”)。此外,至少有一个   在主要制造商的流行手机中广泛观察到的错误,   其中每个实例都具有相同的ANDROID_ID。

解决方案在Android博客上给出。使用Installation.id(context)

public class Installation {
    private static String sID = null;
    private static final String INSTALLATION = "INSTALLATION";

    public synchronized static String id(Context context) {
        if (sID == null) {  
            File installation = new File(context.getFilesDir(), INSTALLATION);
            try {
                if (!installation.exists())
                    writeInstallationFile(installation);
                sID = readInstallationFile(installation);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return sID;
    }

    private static String readInstallationFile(File installation) throws IOException {
        RandomAccessFile f = new RandomAccessFile(installation, "r");
        byte[] bytes = new byte[(int) f.length()];
        f.readFully(bytes);
        f.close();
        return new String(bytes);
    }

    private static void writeInstallationFile(File installation) throws IOException {
        FileOutputStream out = new FileOutputStream(installation);
        String id = UUID.randomUUID().toString();
        out.write(id.getBytes());
        out.close();
    }
}