###### tags: `android`, `android 11`, `Permission`, `FFMpeg`, `Storage`
# 升級 android 11
[Toc]
## 前言
這次升級實在太痛了, 有些問題相關發文數甚少, 只能身先士卒. 因此在此寫下個人經驗, 希望能幫助到後面的人
## 主要改動
### [Storage](https://developer.android.com/about/versions/11/privacy/storage)
以前在升到android 10 的時候, 其實 google 就有警告, storage 的方式將會變動:
- `external` 區域不再給你亂存, 你只能存到自己package 底下
- `Enveriment.getExtrenalXXX()` 大部分都Deprecated
最好的方式是透過`ContentResolver` + `MediaStore` 去存取.
但當時`AndroidManifest.xml`, Application 有一個 flag:
:::info
android:requestLegacyExternalStorage="true"
:::
可以強制無視, 當時沒想那麼多就用了, 但...
:::warning
android 11 將會無視這個flag, [可參考這](https://developer.android.com/about/versions/11/privacy/storage#scoped-storage)
:::
結果現在還是要還債XD
最主要還是一堆第三方 package 要跟著改動, 改著改著, 就整包都要換掉了, 因為他們沒在維護了 :cry:
--------------------
### [Permission](https://developer.android.com/about/versions/11/privacy/permissions)
這部分還好, 主要異動就是
- 加入一次性權限.
- App 太久沒用, 權限會被收回, 至於多久沒說明, 應該是by device.
- WRITE_EXTERNAL_STORAGE 在`android 10以上`不需要用了, [可參考這](https://developer.android.com/training/data-storage/shared/media#request-permissions)
> Don't unnecessarily request storage-related permissions for devices that run **Android 10 or higher**. Your app can contribute to well-defined media collections, ...
程式碼request permission 自然就變成:
```kotlin=
fun requestWritePermission() {
if (SDK < 29) // 請求permission
else // 略過
}
```
--------------------
### [Heap pointer tagging](https://developer.android.com/about/versions/11/behavior-changes-11#heap-pointer-tagging)
:::danger
:warning: 如果你的專案有用到 C, 請注意 :warning:
:::
小弟並不懂這個改動意味著什麼, 看起來是ARM 的擴展, 但因為它, 我們的 **ffmepg lib 不能動了!!!!!**
若有好心大神路過, 煩請解惑這個東西是什麼.
雖然你可以透過flag:
:::info
android:allowNativeHeapPointerTagging="false"
:::
暫時關掉這項改動, 但根據[google 說明](https://source.android.com/devices/tech/debug/tagged-pointers), 你之後還是要改的, 早死晚死的問題.
所以這部分最後選擇**找出問題,重新編譯so檔** :disappointed:
-----
### [Package Visibility](https://developer.android.com/about/versions/11/privacy/package-visibility)
大致上的意思就是:
:::info
跨App 進行資料查詢, 只能用query(由於上述storage 改動), 並且要宣告 你要query 的 pacakge.
:::
這部分也還好, 大部分的SDK, 官網都有提供如何支援android 11 的 visibility.
比如:
- [FB SDK login](https://developers.facebook.com/docs/facebook-login/android#expresslogin)
```xml=
<queries>
<package android:name="com.facebook.katana" />
</queries>
```
- [WeCaht SDK](https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Access_Guide/Android.html)
```xml=
<queries>
<package android:name="com.tencent.mm" />
</queries>
```
如果你有用 `intent.resolveActivity` 之類的, 需要**查詢相對應APP** 也要注意有沒有宣告, 否則會傳null. [可參考 issue](https://stackoverflow.com/questions/62535856/intent-resolveactivity-returns-null-in-api-30
)
比如: `camera`
```xml=
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
```
:::warning
Android Studio 跟 gradle 版本需注意:
---
- Android Studio 需要升级至 3.3 及以上,建議升级至 4.0 及以上版本
- Android SDK Build-Tools 需要升级至 30 及以上版本
- com.android.tools.build:gradle 需要升级至 3.6.0 版本,建議升级至最新的 3.6.4 版本
不然gradle認不得 <queries> 喔~
:::
----------------
### UI dark mode
#### Issue
我的狀況是
- App 有用`DayNight` 的 Theme
- Application init 時, 有呼叫 `AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);`
:::warning
一但 **target 改到30**, user device 有開啟 **黑夜模式**時, 顏色就會跑掉
:::
#### Solution
查文查不到解決方法. 但後來發現自己的 `color-resource`, 有`night` 資料夾......
刪掉後, 就不會再有奇怪的顏色出現.
--------------
### 其他
其他改動對我來說沒什麼影響, 比如 [Foreground-Service](https://developer.android.com/about/versions/11/privacy/foreground-services), [Camera Intent](https://developer.android.com/about/versions/11/behavior-changes-11#camera), [Toast](https://developer.android.com/about/versions/11/behavior-changes-11#toasts), ...
就交給各位自己去了解吧~
## [Google Play Store](https://android-developers.googleblog.com/2020/11/new-android-app-bundle-and-target-api.html)
### 強制更新 target 30
:::success
- 新 APP 在 2021/8 以後發布, target 必須為 30
- 既有 APP 在 2021/11 以後更新, target 必須為 30
:::
### 上傳格式
:::success
- android 11 的APK 一定要sign v2, [參考APK Signature Scheme v2 now required](https://developer.android.com/about/versions/11/behavior-changes-11#minimum-signature-scheme)
- 2021/8 以後只接受 AAB 上傳格式
:::
嘛~ 既然如此我建議各位就直接上AAB
## 相關文章
- [Firebase Distribution 上傳 AAB](https://hackmd.io/@Nacro/firebase_distribution_aab)