Document description
-
This document is based on Google AndroidQ Official Documents and Huawei Q Version Application Compatibility Correction Guidance (Huawei is a bit outdated)
-
Testing machines used: Pixel, Android Q-beta 6-190730.005
-
Version Number Correspondence
Android-Q = Android-10 = Api29
Android-P = Android-9.0 = Api28
Device Hardware Identifier Access Restriction
Restrict application access to non-reset device identification codes, such as IMEI, serial number, etc., and system applications are not affected.
The original approach
// Return: 866976045261713; TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); tm.getDeviceId(); //Return: 66J0218B19000977; Build.getSerial();
-
No problem with systems below AndroidQ
-
Running on AndroidQ and above systems:
-
For example, targetSdkVersion < Q, return null or "unknown";
-
If targetSdkVersion >= Q, throw an exception:
SecurityException: getDeviceId: The user 10196 does not meet the requirements to access device identifiers.
-
Alternatives
-
Programme 1:
The disadvantage of using AndroidId instead is that different Id returned by different signing keys or users (such as system recovery settings) is different.
// Return: 496836e3a48d2d9d String id = Settings.System.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
-
Programme II:
The disadvantage of hardware information splicing is that it can not guarantee uniqueness.
private static String makeDeviceId(Context context) { String deviceInfo = new StringBuilder() .append(Build.BOARD).append("#") .append(Build.BRAND).append("#") .append(Build.CPU_ABI).append("#") .append(Build.DEVICE).append("#") .append(Build.DISPLAY).append("#") .append(Build.HOST).append("#") .append(Build.ID).append("#") .append(Build.MANUFACTURER).append("#") .append(Build.MODEL).append("#") .append(Build.PRODUCT).append("#") .append(Build.TAGS).append("#") .append(Build.TYPE).append("#") .append(Build.USER).append("#") .toString(); try { return UUID.nameUUIDFromBytes(deviceInfo.getBytes("utf8")).toString(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } String androidId = Settings.System.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); return androidId; }
Prohibit background activation of Activity
Situation description
- On AndroidQ, the background activation Activity will be ignored by the system, no matter how many targetSdkVersion;
- On AndroidQ, even if there is a front desk service for the application to return to;
- The AndroidQ version below has no effect.
Solution
Send full-screen notifications:
//Android Manifest declares new permissions without dynamic application <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/> Intent intent = new Intent(this, ScopedStorageActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT); Notification notification = new NotificationCompat.Builder(this, Constants.CHANNEL_ID) .setSmallIcon(R.drawable.ic_launcher_foreground) .setContentTitle("Incoming call") .setContentText("(919) 555-1234") .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_ALARM) //After setting up full-screen notification, send notification and start Activity directly .setFullScreenIntent(pendingIntent, true) .build(); NotificationManager manager = getSystemService(NotificationManager.class); manager.notify(445456, notification);
However: on Huawei Mat20 (Api-28), you need to open the banner notification in the settings; native AndroidQ (beta6) is valid.
Increasing Location Limitation for Background Applications
Situation description
-
Background applications need to dynamically apply for permission to obtain location information.
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
-
Run on AndroidQ:
- Target SdkVersion < Q, no effect, the system will add background location permission by default when applying for permission.
- Target SdkVersion >= Q, need to apply;
- Pixel Android Q-beta 6)
-
ACCESS_BACKGROUND_LOCATION cannot be applied separately. It needs to be applied together with ACCESS_COARSE_LOCATION/ACCESS_FINE_LOCATION.
Solution
-
Dynamic application is enough.
-
Start the Front Desk Service
<!-Need to set foregroundServiceType For " location" -> <service android:name=".permission.LocationService" android:foregroundServiceType="location"/>
Partitioned storage
Situation description
- Run on AndroidQ:
- Target SdkVersion < Q, no effect;
- Target SdkVersion >= Q, enabling filtering view by default, files other than applications need to be passed Storage access framework (SAF, Storage Access Framework) Read and write.
- sdaf
Solution
-
Disable filtered views and use old storage mode
<manifest ... > <!-- This attribute is "false" by default on apps targeting Android Q. --> <application android:requestLegacyExternalStorage="true" ... > ... </application> </manifest>
-
Store files in filtered views
// /Android/data/com.example.androidq/files/Documents File dir = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
Advantages: ** No need to apply for permission to read and write;
** Disadvantages: ** Deleted with application uninstall;