Summary of Android Q Adaptation

Posted by dungareez on Mon, 19 Aug 2019 05:31:17 +0200

Document description

  1. This document is based on Google AndroidQ Official Documents and Huawei Q Version Application Compatibility Correction Guidance (Huawei is a bit outdated)

  2. Testing machines used: Pixel, Android Q-beta 6-190730.005

  3. 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();
  1. No problem with systems below AndroidQ

  2. 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

  1. 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);
    
  2. 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

Official Documents

Situation description

  1. On AndroidQ, the background activation Activity will be ignored by the system, no matter how many targetSdkVersion;
  2. On AndroidQ, even if there is a front desk service for the application to return to;
  3. 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

Official Documents

Situation description

  1. Background applications need to dynamically apply for permission to obtain location information.

    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

  2. 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)
  3. ACCESS_BACKGROUND_LOCATION cannot be applied separately. It needs to be applied together with ACCESS_COARSE_LOCATION/ACCESS_FINE_LOCATION.

Solution

  1. Dynamic application is enough.

  2. Start the Front Desk Service

    <!-Need to set foregroundServiceType For " location" ->
    <service 
     android:name=".permission.LocationService"
        android:foregroundServiceType="location"/>
    

Partitioned storage

Official Documents

Situation description

  1. 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.
  2. sdaf

Solution

  1. 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>
    
  2. 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;

Topics: Android Google Attribute