DeviceId and app permissions

2019-07-04 07:51发布

问题:

My app (S Educate) requires me to get the DeviceId (for Analytics/Recommendations) and hence I added the permission, READ_PHONE_STATE and although the documentation is harmless, when the user installs, the app permissions window shows, "Phone Calls - Monitor, record, and process phone calls" which obviously prevents user from installing and users have informed that they are not installing simply because of this permission.


Screenshot (click for larger variant)

Here are my options:

  1. I state clearly in my app description that I require this permission to get DeviceId and not to monitor/record phone calls and hope the users believe me and install the app
  2. I find an alternate way to get DeviceId - which to my knowledge is not available without using the above mentioned permission

Please advise how do I get around this permission issue.

回答1:

Please use an app-generated UUID. This will allow you to distinguish one app installation from another, without violating user privacy.



回答2:

There are different ways you can retrieve Unique device id in Android.

  1. IMEI (for this, You will need to add READ_PHONE_STATE Permission in Manifest)
  2. Pseudo Unique ID (no need to add READ_PHONE_STATE permission)
  3. Android ID
  4. MAC Address

Check out the details below. http://www.pocketmagic.net/2011/02/android-unique-device-id/#.UsMCatIW2vE



回答3:

From Android Developers Blog

In the past, when every Android device was a phone, things were simpler: TelephonyManager.getDeviceId() is required to return (depending on the network technology) the IMEI, MEID, or ESN of the phone, which is unique to that piece of hardware.

Mac Address

It may be possible to retrieve a Mac address from a device’s WiFi or Bluetooth hardware. We do not recommend using this as a unique identifier. To start with, not all devices have WiFi. Also, if the WiFi is not turned on, the hardware may not report the Mac address.

Serial Number

Since Android 2.3 (“Gingerbread”) this is available via android.os.Build.SERIAL. Devices without telephony are required to report a unique device ID here; some phones may do so also.

ANDROID_ID

More specifically, Settings.Secure.ANDROID_ID. This is a 64-bit quantity that is generated and stored when the device first boots. It is reset when the device is wiped.

ANDROID_ID seems a good choice for a unique device identifier. There are downsides: First, it is not 100% reliable on releases of Android prior to 2.2 (“Froyo”). Also, there has been at least one widely-observed bug in a popular handset from a major manufacturer, where every instance has the same ANDROID_ID.

Solution is given on android blog. Use 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();
    }
}