Android targetSdkVersion升級到28遇到一些問題記錄

將 targetSdkVersion 26 升級到 28 之后,遇到以下的問題。

1. 阿里云OSS上傳圖片失敗

  • 阿里云上傳圖片的接口沒有回調
  • java.net.UnknownServiceException: CLEARTEXT communication to XXX not permitted by network security policy
問題原因:
  • 從 Android 9.0 開始,默認情況下移除HTTP客戶端。項目使用的阿里云OSS的sdk 2.8.1使用到HTTP客戶端,所以會找不到該庫拋出異常。
  • 阿里云OSS的sdk 2.8.1中的網絡請求是http。而Android 9.0限制了明文流量的網絡請求,非加密的流量請求都會被系統禁止掉。
解決方案:

解決方案以下兩種:

  1. 開啟 Android 9.0 兼容 http 的請求
    在 AndroidManifest文件中加入:
<application  
        android:usesCleartextTraffic="true">
        <uses-library 
          android:name="org.apache.http.legacy" 
          android:required="false"/>
</application>
  1. 將本地的 oss 的 sdk 2.8.1版本升級到 2.9.0 以上,api 'com.aliyun.dpa:oss-android-sdk:+'

當然還是推薦第二種解決方案。

2. Android 9.0上QQ分享報錯

在Android 9.0的手機上進行QQ分享報錯,提示找不到org/apache/http/conn/scheme/SchemeRegistry。

問題原因:

從 Android 9.0 開始,默認情況下移除HTTP客戶端。QQ分享中SDK 使用到HTTP客戶端,所以會找不到該庫拋出異常。

解決方案:
  1. 繼續兼容HTTP 客戶端,在 AndroidManifest文件中加入:
<application  
        android:usesCleartextTraffic="true">
        <uses-library 
          android:name="org.apache.http.legacy" 
          android:required="false"/>
</application>

參考文檔:https://developer.umeng.com/docs/66632/detail/94386

3.限制非 SDK 接口的調用

當你調用了非SDK接口時,會有類似Accessing hidden XXX的日志:

Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)

名單分類:

  • Light grey list: targetSDK>=P時,警告;
  • Dark grey list: targetSDK<P時,警告;>=p時,不允許調用;
  • Black list:三方應用不允許調用;

4.移除對 Build.serial 的直接訪問(設備唯一標識符)

問題原因:

((TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId()
獲得設備ID,會返回空值(targetSDK<=P)或者報錯(targetSDK==Q)。且官方所說的READ_PRIVILEGED_PHONE_STATE權限只提供給系統app,所以這個方法算是廢了。

解決方案:

由于唯一標識符權限的更改會導致android.os.Build.getSerial()返回unknown,但是由于m_szDevIDShort是由硬件信息拼出來的,所以仍然保證了UUID的唯一性和持久性。參考代碼如下:

public static String getUUID() {

String serial = null;

String m_szDevIDShort = "35" +

Build.BOARD.length() % 10 + Build.BRAND.length() % 10 +

Build.CPU_ABI.length() % 10 + Build.DEVICE.length() % 10 +

Build.DISPLAY.length() % 10 + Build.HOST.length() % 10 +

Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10 +

Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10 +

Build.TAGS.length() % 10 + Build.TYPE.length() % 10 +

Build.USER.length() % 10; //13 位

try {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

serial = android.os.Build.getSerial();

} else {

serial = Build.SERIAL;

}

//API>=9 使用serial號

return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();

} catch (Exception exception) {

//serial需要一個初始化

serial = "serial"; // 隨便一個初始化

}

//使用硬件信息拼湊出來的15位號碼

return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();

}

5. 前臺服務權限

拋出 SecurityException 異常

Caused by: java.lang.SecurityException: Permission Denial: 
startForeground from pid=6175, uid=10189 requires android.permission.FOREGROUND_SERVICE
問題原因:

在 Android 9.0 中,應用在使用前臺服務之前必須先申請 FOREGROUND_SERVICE 權限,否則就會拋出 SecurityException 異常。

解決方案:

在 AndroidManifest文件中加入:

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

6.不允許共享WebView數據目錄

應用程序不能再跨進程共享單個WebView數據目錄。如果您的應用有多個使用WebView,CookieManager或android.webkit包中的其他API的進程,則當第二個進程調用WebView方法時,您的應用將崩潰。

7.SELinux 禁止訪問應用的數據目錄

系統強制每個應用的 SELinux 沙盒對每個應用的私有數據目錄強制執行逐個應用的 SELinux 限制。現在,不允許直接通過路徑訪問其他應用的數據目錄。應用可以繼續使用進程間通信 (IPC) 機制(包括通過傳遞 FD)共享數據

8.限制訪問通話記錄

  • Android 9.0 引入 CALL_LOG 權限組并將 READ_CALL_LOG、WRITE_CALL_LOG 和 PROCESS_OUTGOING_CALLS 權限移入該組。 在之前的 Android 版本中,這些權限位于 PHONE 權限組。
  • 如果應用需要訪問通話記錄或者需要處理去電,則您必須向 CALL_LOG 權限組明確請求這些權限。 否則會發生SecurityException

9.限制訪問電話號碼

  • 在未首先獲得 READ_CALL_LOG 權限的情況下,除了應用的用例需要的其他權限之外,運行于 Android 9.0 上的應用無法讀取電話號碼或手機狀態。
  • 與來電和去電關聯的電話號碼可在手機狀態廣播(比如來電和去電的手機狀態廣播)中看到,并可通過 PhoneStateListener 類訪問。 但是,如果沒有 READ_CALL_LOG 權限,則 PHONE_STATE_CHANGED 廣播和 PhoneStateListener“提供的電話號碼字段為空”。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容