23 February 2016
Breaking change: Android 6 and device IDs
Before the release of Android 6, users were regularly asked to grant permissions when installing new apps. Often times users were asked to grant the android.permission.READ_PHONE_STATE
permission, which is considered a dangerous permission. This caused many people to not install apps for fear of what the apps might be doing with that granted permission.
Android 6 eases those fears by moving permissions to an on-demand system. Now you can request android.permission.READ_PHONE_STATE
when your app needs it. However, this change creates an issue with the Corona SDK API that allows you to get the device’s device ID using system.getInfo("deviceID")
.
If the user’s device grants the android.permission.READ_PHONE_STATE
permission, then the device’s unique phone ID (IMEI, MEID or ESN depending on the carrier) is returned. For devices without a phone or which have not granted the permission, a unique system ID assigned by the operating system is returned.
If your app currently uses the deviceID value, it’s very likely that any users who upgrade to Android 6 will have a different deviceID
than they had with earlier versions of Android. If it is important to your app to maintain the same ID, you must take steps to ensure that your app continues to get the phone ID instead of the OS ID.
You can do this in main.lua by requesting the proper android.permission.READ_PHONE_STATE
permission before attempting to get the deviceID. Consider this code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
-- get the default deviceID local deviceID = system.getInfo( "deviceID" ) local deviceIDText = display.newText(deviceID, display.contentCenterX, 50, native.systemFontBold, 20 ) local function appPermissionsListener( event ) -- regardless of what the user chose, we now either have the Phone permission or we don't -- so grab the current deviceID in case it's different than the pre-permission check value. deviceID = system.getInfo( "deviceID" ) deviceIDText.text = deviceID end -- -- all of this only matters for Android 6 or later, so don't bother non-Android 6 users: -- if system.getInfo( "androidApiLevel" ) >= 23 then -- Ah ha! Android 6 or later -- -- Check to see if the user has previouslly granted permissions. -- if they have not, then we should prompt them to ask. -- local grantedPermissions = system.getInfo( "grantedAppPermissions" ) local hasPhonePermission = false for i = 1, #grantedPermissions do -- -- check for the specific READ_PHONE_STATE permission or the "Phone" group permission -- if "android.permission.READ_PHONE_STATE" == grantedPermissions[i] or "Phone" == grantedPermissions[i] then -- found phone permissions hasPhonePermission = true -- exit the loop. break end end -- -- if we get to this point and hasPhonePermission is false, then we didn't find it in the -- permissions list, so prompt the user for it. -- if not hasPhonePermission then -- -- Create a table for the options to pass to requestAppPermission -- local permissionOptions = { appPermission = "android.permission.READ_PHONE_STATE", urgency = "Critical", listener = appPermissionsListener, rationaleTitle = "Read phone state required", rationaleDescription = "This app needs this state to retrieve previously saved data. Re-request now?", settingsRedirectTitle = "Alert", settingsRedirectDescription = "Without the ability to access your device's unique ID, it can't function properly. Please grant camera access within Settings." } native.showPopup( "requestAppPermission", permissionOptions ) end end |
Since the OS-based ID doesn’t require special permissions, we recommend that you standardize on the OS generated ID instead of the Phone ID moving forward.
Have questions? Join us in the Corona Labs Android forum!
Felix
Posted at 16:40h, 25 FebruaryI am trying to implement this code, but it gives a runtime error because system.getInfo( “androidApiLevel” ) returns nil. I implemented a check for Android, like
if system.getInfo( “platformName” ) == “Android” then
but it even return nil on android devices. any idea whats the problem here?
Best,
Felix
Felix
Posted at 17:11h, 25 FebruaryAh, never mind. Updating corona to the newest public build resolved the problem…
Charlotte Hook
Posted at 04:00h, 13 MarchSince a newer version of android is being released, does this mean some older versions of android will no longer be compatible? the only article i can find is from april 2014 which says 2.3.3 is the earliest now compatible, just wondering if this will change
Rob Miracle
Posted at 12:15h, 13 MarchWe still support a minimum of 2.3.3 on Android, but we don’t know how much longer that will be the case. More and more plugins are asking for features that want a higher minimum. It won’t happen in the near future since we just released a pubic build that still supports 2.3.3 in February.