<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Android 11 適配,看這篇就夠了!

          共 17103字,需瀏覽 35分鐘

           ·

          2021-05-14 08:22

           微信改了推動機制,真愛請星標(biāo)本公號
          公眾號回復(fù)加入BATcoder技術(shù)群BAT

          作者:唯鹿 

          https://juejin.cn/post/6948211914455384072

          1.準(zhǔn)備工作

          老規(guī)矩,首先將我們項目中的 targetSdkVersion 改為 30。或者使用兼容性調(diào)試工具,后面我會說到。

          2.存儲機制更新


          Scoped Storage(分區(qū)存儲)


          具體適配方法和去年的Android 10 適配攻略中的沒有太大區(qū)別。

          https://weilu.blog.csdn.net/article/details/104513170


          不過需要注意的是,應(yīng)用targetSdkVersion >= 30,強制執(zhí)行分區(qū)存儲機制。之前在AndroidManifest.xml中添加 android:requestLegacyExternalStorage="true"的適配方式已不起作用。


          還有一個變化:Android 11 允許使用除 MediaStore API 之外的 API 通過文件路徑直接訪問共享存儲空間中的媒體文件。其中包括:


          • File API。


          • 原生庫,例如 fopen()


          如果你之前沒有適配Android 10,這一點對你來說是個好消息。Android 10在AndroidManifest.xml中添加 android:requestLegacyExternalStorage="true"來適配,Android 11上直接使用File API訪問媒體文件。


          不過,使用原始文件路徑直接訪問共享存儲空間中的媒體文件會重定向到 MediaStoreAPI,這次重定向會造成性能影響(隨機讀寫慢一倍左右)。而且直接使用原始文件路徑,并不會比使用 MediaStore API 有更多優(yōu)勢,因此官方強烈建議直接使用 MediaStore API


          MANAGE_EXTERNAL_STORAGE


          當(dāng)然還有一種簡單粗暴的適配方法,獲取外部存儲管理權(quán)限。如果你的應(yīng)用是手機管家、文件管理器這類需要訪問大量文件的app,可以申請MANAGE_EXTERNAL_STORAGE權(quán)限,將用戶引導(dǎo)至系統(tǒng)設(shè)置頁面開啟。代碼如下:


             
          <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
                  tools:ignore="ScopedStorage" />



          public static void checkStorageManagerPermission(Context context) {
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
                          !Environment.isExternalStorageManager()) {

                  Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                  intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                  context.startActivity(intent);
              }
          }




          需要注意的是即使你有了MANAGE_EXTERNAL_STORAGE權(quán)限,也無法訪問Android/data/ 目錄下的文件。


          對于MANAGE_EXTERNAL_STORAGE權(quán)限,國內(nèi)使用應(yīng)該沒有什么影響。但是在Google Play上需要說明為什么已有的SAF或MediaStore不滿足你的應(yīng)用需求,審核通過才允許上架使用。所以一般情況下,我個人不推薦你為了適配簡單,直接申請使用MANAGE_EXTERNAL_STORAGE權(quán)限。


          其他細節(jié)變更見文檔:Android 11 中的存儲機制更新

          https://developer.android.google.cn/about/versions/11/privacy/storage#scoped-storage


          相關(guān)api變更及使用推薦郭霖大神的這篇:Android 11新特性,Scoped Storage又有了新花樣

          https://guolin.blog.csdn.net/article/details/113954552


          存儲訪問框架 (SAF)變更


          Android 11對SAF添加以下限制:


          • 使用 ACTION_OPEN_DOCUMENT_TREE ACTION_OPEN_DOCUMENT,無法瀏覽到Android/data/  Android/obb/ 目錄及其所有子目錄。


          • 使用 ACTION_OPEN_DOCUMENT_TREE無法授權(quán)訪問存儲根目錄、Download文件夾。


          REQUEST_INSTALL_PACKAGES


          在8.0的適配中,我們安裝apk包之前需要申請“安裝未知來源應(yīng)用”的權(quán)限。一般來說首次是跳轉(zhuǎn)到授權(quán)頁面讓用戶手動開啟,然后返回app進行安裝。


          在Android 11中當(dāng)用戶開啟“安裝未知來源應(yīng)用”的權(quán)限,app就會被殺死。該行為與強制分區(qū)存儲有關(guān),因為持有 REQUEST_INSTALL_PACKAGES 權(quán)限的應(yīng)用可以訪問其他應(yīng)用的Android/obb 目錄。


          好在用戶授予權(quán)限之后,雖然app會被殺死,但是安裝頁面依然會彈出。


          目前對于這一變更我沒有發(fā)現(xiàn)可以適配處理的方式,詳細介紹見:Android 11特性調(diào)整:安裝外部來源應(yīng)用需要重啟APP

          https://news.51cto.com/art/202006/618118.htm

          3.權(quán)限變化


          單次權(quán)限授權(quán)


          從 Android 11 開始,每當(dāng)應(yīng)用請求與位置信息、麥克風(fēng)或攝像頭相關(guān)的權(quán)限時,面向用戶的權(quán)限對話框會包含僅限這一次選項。如果用戶在對話框中選擇此選項,系統(tǒng)會向應(yīng)用授予臨時的單次授權(quán)。



          單次權(quán)限授權(quán)的應(yīng)用可以在一段時間內(nèi)訪問相關(guān)數(shù)據(jù),具體時間取決于應(yīng)用的行為和用戶的操作:


          • 當(dāng)應(yīng)用的 Activity 可見時,應(yīng)用可以訪問相關(guān)數(shù)據(jù)。


          • 如果用戶將應(yīng)用轉(zhuǎn)為后臺運行,應(yīng)用可以在短時間內(nèi)繼續(xù)訪問相關(guān)數(shù)據(jù)。


          • 如果您在 Activity 可見時啟動了一項前臺服務(wù),并且用戶隨后將您的應(yīng)用轉(zhuǎn)到后臺,那么您的應(yīng)用可以繼續(xù)訪問相關(guān)數(shù)據(jù),直到該前臺服務(wù)停止。


          • 如果用戶撤消單次授權(quán)(例如在系統(tǒng)設(shè)置中撤消),無論您是否啟動了前臺服務(wù),應(yīng)用都無法訪問相關(guān)數(shù)據(jù)。與任何權(quán)限一樣,如果用戶撤消了應(yīng)用的單次授權(quán),應(yīng)用進程就會終止。


          當(dāng)用戶下次打開應(yīng)用并且應(yīng)用中的某項功能請求訪問位置信息、麥克風(fēng)或攝像頭時,系統(tǒng)會再次提示用戶授予權(quán)限。


          如果你之前就是使用權(quán)限時才請求相關(guān)權(quán)限,那么這一變更對于你的應(yīng)用沒有影響。


          請求位置權(quán)限


          這部分在Android 10的適配有過調(diào)整,當(dāng)時規(guī)則如下:


          請求ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION權(quán)限表示在前臺時擁有訪問設(shè)備位置信息的權(quán)限。在請求彈框中,選擇“始終允許”表示前后臺都可以獲取位置信息,選擇“僅在應(yīng)用使用過程中允許”只表示擁有前臺的權(quán)限。


          在Android 11中,請求彈框中取消了“始終允許”這一選項。也就是說默認不會授予你后臺訪問設(shè)備位置信息的權(quán)限。如果嘗試請求ACCESS_BACKGROUND_LOCATION權(quán)限的同時請求任何其他權(quán)限,系統(tǒng)會拋出異常,不會向應(yīng)用授予其中的任一權(quán)限。


          官方給出的適配建議及原因如下:


          建議應(yīng)用對位置權(quán)限執(zhí)行遞增請求,先請求前臺位置信息訪問權(quán)限,再請求后臺位置信息訪問權(quán)限。執(zhí)行遞增請求可以為用戶提供更大的控制權(quán)和透明度,因為他們可以更好地了解應(yīng)用中的哪些功能需要后臺位置信息訪問權(quán)限。


          總結(jié)一下得出兩點:


          1,先請求前臺位置信息訪問權(quán)限,再請求后臺位置信息訪問權(quán)限。


          2,單獨請求后臺位置信息訪問權(quán)限,不要與其他權(quán)限一同請求。


          這里還需要注意不同目標(biāo)平臺應(yīng)用在Android 11上的表現(xiàn):


          • Android 10 為目標(biāo)平臺的應(yīng)用 允許同時訪問前后臺的位置信息權(quán)限,但同樣不會有“始終允許”這一選項。


          1,沒有前后臺的位置信息權(quán)限時:



          2,有前臺的位置信息權(quán)限時:



          • Android 11 為目標(biāo)平臺的應(yīng)用


          1,沒有前后臺的位置信息權(quán)限時,只能先請求前臺的位置信息權(quán)限。



          2,有前臺的位置信息權(quán)限,請求后臺的位置信息時系統(tǒng)會跳轉(zhuǎn)到下面的設(shè)置頁面。



          選擇“始終允許”表示具有前后臺位置信息訪問權(quán)限,如果用戶拒絕兩次應(yīng)用定位訪問請求(直接返回等),后面請求相同權(quán)限都會被直接提示請求失敗。(這里就需要我們給用戶以引導(dǎo)了)


          這里解釋一下“拒絕兩次”,這是Android 11 上添加的權(quán)限對話框的可見性,以前我們點擊了“不再詢問”表示拒絕授權(quán)。現(xiàn)在還包含類似上面這種轉(zhuǎn)到系統(tǒng)設(shè)置,然后點返回按鈕,也算是拒絕授權(quán)。當(dāng)然,用戶按返回按鈕關(guān)閉權(quán)限對話框,此操作不算。


          總結(jié)一下,與Android 10的區(qū)別就是將后臺權(quán)限的申請分離了出來,增加了用戶“拒絕”的條件,避免了應(yīng)用重復(fù)請求用戶已拒絕的權(quán)限。


          軟件包可見性


          軟件包可見性是Android 11上提升系統(tǒng)隱私安全性的一個新特性。它的作用是限制app隨意獲取其他app的信息和安裝狀態(tài)。避免病毒軟件、間諜軟件利用,引發(fā)網(wǎng)絡(luò)釣魚、用戶安裝信息泄露等安全事件。


          獲取自動可見應(yīng)用的列表,可以執(zhí)行命令adb shell dumpsys package queries,找到 forceQueryable 部分。下面是在vivo iqoo手機的執(zhí)行結(jié)果。


          Queries:
            system apps queryable: false
            forceQueryable:
              [com.android.BBKCrontab,com.vivo.fingerprint,com.vivo.epm,com.vivo.abe,com.vivo.fingerprintengineer,com.vivo.contentcatcher,com.vivo.floatingball,com.vivo.agent,com.vivo.nightpearl,android,com.wapi.wapicertmanage,com.vivo.vms,co
          m.android.providers.settings,com.vivo.upslide,com.vivo.assistant,com.vivo.vivokaraoke,com.vivo.fingerprintui,com.android.wallpaperbackup,com.bbk.facewake,com.vivo.faceunlock,com.vivo.doubleinstance,com.vivo.audiofx,com.iqoo.powersav
          ing,com.bbk.SuperPowerSave,com.vivo.vibrator4d,com.vivo.smartunlock,com.vivo.globalanimation,com.vivo.appfilter,com.vivo.voicewakeup,com.vivo.minscreen,com.android.bbklog,com.mobile.cos.iroaming,com.vivo.networkstate,com.vivo.daemon
          Service,com.vivo.smartshot,com.vivo.vtouch,com.android.networkstack.tethering.inprocess,com.android.localtransport,com.vivo.pem,com.vivo.wifiengineermode,com.android.server.telecom,com.vivo.gamecube,com.vivo.aiengine,com.vivo.multin
          lp,com.vivo.smartmultiwindow,com.vivo.permissionmanager,com.qti.diagservices,com.vivo.bsptest,com.qti.snapdragon.qdcm_ff,com.vivo.dr,com.vivo.sps,com.android.dynsystem,com.vivo.setupwizard,com.vivo.gamewatch,com.android.keychain,com
          .vivo.faceui,com.android.networkstack.inprocess,com.android.location.fused,com.android.inputdevices,com.android.settings,com.iqoo.engineermode,com.vivo.fuelsummary
          ]
              [com.qualcomm.uimremoteserver,com.vivo.devicereg,com.qti.qualcomm.deviceinfo,com.volte.config,com.android.mms.service,com.android.ons,com.qualcomm.qcrilmsgtunnel,com.vivo.sim.contacts,com.qualcomm.qti.uimGbaApp,com.qualcomm.qti.
          modemtestmode,com.android.stk,com.android.vendors.bridge.softsim,com.qualcomm.uimremoteclient,com.qti.qualcomm.datastatusnotification,com.qualcomm.qti.uim,com.android.phone,com.qualcomm.qti.dynamicddsservice,com.qualcomm.qti.telepho
          nyservice,com.android.cellbroadcastservice,com.android.providers.telephony,com.qti.dpmserviceapp,com.android.incallui
          ]
              [com.android.vivo.tws.vivotws,com.android.bluetooth]
              com.android.nfc
              com.android.se
              com.android.networkstack.permissionconfig
              com.android.shell
              com.android.providers.media.module
              com.android.wifi.resources.overlay.common
              com.android.theme.icon_pack.filled.themepicker
              com.android.theme.icon_pack.circular.themepicker
              com.android.server.telecom.overlay.common
          ......


          可以看到都是系統(tǒng)應(yīng)用包名,所以我們的三方應(yīng)用默認是不可見的。此項變更影響比較多的是分享支付一類需要與其他應(yīng)用交互的功能。下面舉一個簡單的例子:


          private static boolean hasActivity(Context context, Intent intent) {
              PackageManager packageManager = context.getPackageManager();
              return packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
          }

          public void test() {
              Intent intent = new Intent();
              intent.setClassName("com.tencent.mm""com.tencent.mm.ui.tools.ShareImgUI");
              Log.d("hasActivity:", hasActivity(this, intent) + "");
          }


          hasActivity方法中通過queryIntentActivities來判斷此頁面是否存在。但是在targetSdkVersion >= 30中,這些三方默認都是不可見的。所以都會返回false。類似方法getInstalledPackagesgetPackageInfo也受到相應(yīng)的限制。


          解決方法很簡單,在AndroidManifest.xml 中添加queries元素,里面添加需要可見的應(yīng)用包名。


          <manifest package="com.example.app">
              <queries>
                  <package android:name="com.tencent.mm" /> <- 指定微信包名
              </queries>

              ...
          </manifest>


          我在適配中用到的還有下面的包名,我們可以按需添加:


          <queries>
              <!-- 微博 -->
              <package android:name="com.sina.weibo" />
              <!-- QQ -->
              <package android:name="com.tencent.mobileqq" />
              <!-- 支付寶 -->
              <package android:name="com.eg.android.AlipayGphone" /> 
              <!-- AlipayHK -->
              <package android:name="hk.alipay.wallet" />
          </queries>


          除了直接添加包名的方式外,我們可以按intentprovider來添加:


          <manifest package="com.example.app">
              <queries>
                  <intent>
                      <action android:name="android.intent.action.SEND" />
                      <data android:mimeType="image/jpeg" />
                  </intent>

                  <provider android:authorities="com.example.settings.files" />
              </queries>
              ...
          </manifest>


          具體的規(guī)則參見:管理軟件包可見性

          https://developer.android.google.cn/training/basics/intents/package-visibility#intent-signature


          當(dāng)然,還有一種簡單粗暴的方式,可以直接申請權(quán)限QUERY_ALL_PACKAGES。如果你的應(yīng)用需要上架Google Play,那么可能要注意相關(guān)政策。為了尊重用戶隱私,建議我們的應(yīng)用按正常工作所需的最小軟件包可見性來適配。


          有一點需要說明一下,我們?nèi)粘J褂玫?/span>startActivity 方法不受系統(tǒng)軟件包可見性行為的影響,即使hasActivityfalse,一樣可以跳轉(zhuǎn)。如果我們在做跳轉(zhuǎn)前,進行類似hasActivity的判斷,那么會受影響。


          最后需要注意的是,使用queries元素需要Android Gradle 插件版本是 4.1及以上,因為舊版本的插件并不兼容此元素,出現(xiàn)合并 manifest 的錯誤。


          前臺服務(wù)類型


          Android 10中,在前臺服務(wù)訪問位置信息,需要在對應(yīng)的service中添加 location 服務(wù)類型。


          同樣的,Android 11中,在前臺服務(wù)訪問攝像頭或麥克風(fēng),需要在對應(yīng)的service中添加camera或microphone 服務(wù)類型。


          <manifest>
              ...
             <service 
                 android:name="MyService"
                 android:foregroundServiceType="microphone|camera" />

          </manifest>


          這一限制的變更,使得程序無法在后臺啟動服務(wù)訪問攝像頭和麥克風(fēng)。如需使用,只能是前臺開啟前臺服務(wù)。除非有如下情況:


          • 服務(wù)由系統(tǒng)組件啟動。


          • 服務(wù)是通過應(yīng)用小部件啟動。


          • 服務(wù)是通過與通知交互啟動的。


          • 服務(wù)是PendingIntent啟動的,它是從另一個可見的應(yīng)用程序發(fā)送過來的。


          • 服務(wù)由一個應(yīng)用程序啟動,該應(yīng)用是一個DPC,且在設(shè)備所有者模式下運行。


          • 服務(wù)由一個提供VoiceInteractionService的應(yīng)用啟動。


          • 服務(wù)由一個具有START_ACTIVITIES_FROM_BACKGROUND權(quán)限的應(yīng)用啟動。


          權(quán)限自動重置


          如果應(yīng)用以 Android 11 或更高版本為目標(biāo)平臺并且數(shù)月未使用,系統(tǒng)會通過自動重置用戶已授予應(yīng)用的運行時敏感權(quán)限來保護用戶數(shù)據(jù)。如下圖所示:



          注意上圖中有一個啟動自動重置的開關(guān)。如果我們的應(yīng)用有特殊需要,可以引導(dǎo)用戶關(guān)閉它。示例代碼如下:


          public void checkAutoRevokePermission(Context context{
              // 判斷是否開啟
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
                      !context.getPackageManager().isAutoRevokeWhitelisted()) {
                  // 跳轉(zhuǎn)設(shè)置頁    
                  Intent intent = new Intent(Intent.ACTION_AUTO_REVOKE_PERMISSIONS);
                  intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                  intent.setData(Uri.fromParts("package", context.getPackageName(), null));
                  context.startActivity(intent);
              }
          }


          SYSTEM_ALERT_WINDOW權(quán)限


          這部分我在適配中沒有用到,直接照搬文檔:


          在 Android 11 中,系統(tǒng)會根據(jù)請求自動向某些類型的應(yīng)用授予 SYSTEM_ALERT_WINDOW 權(quán)限:


          • 系統(tǒng)會自動向具有 ROLE_CALL_SCREENING 且請求 SYSTEM_ALERT_WINDOW 的所有應(yīng)用授予該權(quán)限。如果應(yīng)用失去 ROLE_CALL_SCREENING,就會失去該權(quán)限。


          • 系統(tǒng)會自動向通過 MediaProjection 截取屏幕且請求 SYSTEM_ALERT_WINDOW 的所有應(yīng)用授予該權(quán)限,除非用戶已明確拒絕向應(yīng)用授予該權(quán)限。當(dāng)應(yīng)用停止截取屏幕時,就會失去該權(quán)限。此用例主要用于游戲直播應(yīng)用。


          這些應(yīng)用無需發(fā)送 ACTION_MANAGE_OVERLAY_PERMISSION 以獲取 SYSTEM_ALERT_WINDOW 權(quán)限,它們只需直接請求 SYSTEM_ALERT_WINDOW 即可。


          MANAGE_OVERLAY_PERMISSION intent 始終會將用戶轉(zhuǎn)至系統(tǒng)權(quán)限屏幕。


          從 Android 11 開始,ACTION_MANAGE_OVERLAY_PERMISSION intent 始終會將用戶轉(zhuǎn)至頂級設(shè)置屏幕,用戶可在其中授予或撤消應(yīng)用的 SYSTEM_ALERT_WINDOW 權(quán)限。intent 中的任何 package: 數(shù)據(jù)都會被忽略。


          在更低版本的 Android 中,ACTION_MANAGE_OVERLAY_PERMISSION intent 可以指定一個軟件包,它會將用戶轉(zhuǎn)至應(yīng)用專用屏幕以管理權(quán)限。從 Android 11 開始將不再支持此功能,而是必須由用戶先選擇要授予或撤消哪些應(yīng)用的權(quán)限。此變更可以讓權(quán)限的授予更有目的性,從而達到保護用戶的目的。


          讀取手機號


          如果你是通過TelecomManagergetLine1Number方法,或TelephonyManagergetMsisdn方法獲取電話號碼。那么在Android 11中需要增加READ_PHONE_NUMBERS權(quán)限。使用其他方法不受限。


          <manifest>
              <!-- 如果應(yīng)用僅在 Android 10及更低版本中使用該權(quán)限,可以添加 maxSdkVersion="29" -->
              <uses-permission android:name="android.permission.READ_PHONE_STATE"
                               android:maxSdkVersion="29" />

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

          4.其他行為變更

          自定義view的Toast


          Android 11 為目標(biāo)平臺的應(yīng)用,從后臺發(fā)送自定義view的Toast消息系統(tǒng)會進行屏蔽。前臺使用不受影響。Toast相應(yīng)的setView getView也已經(jīng)廢棄不建議使用。


          如果要在后臺使用,推薦使用默認的toast或Snackbar替代。


          APK簽名


          Android 11 為目標(biāo)平臺的應(yīng)用,僅通過v1 簽名的應(yīng)用無法在Android 11的設(shè)備上安裝或更新。必須使用v2或更高版本進行簽名。


          同時Android 11 添加了對 APK 簽名方案 v4 的支持。

          https://developer.android.google.cn/studio/command-line/apksigner?hl=zh_cn#v4-signing-enabled


          AsyncTask


          AsyncTask在Android 11已經(jīng)不建議使用,建議遷移至kotlin的協(xié)程。

          此外Handler未指定Looper的構(gòu)造方法也已不建議使用。

          建議明確指定Looper

             
          private Handler handler = new Handler(Looper.myLooper());
          // 或
          private Handler handler = new Handler(Looper.getMainLooper());

          5.新增工具


          兼容性調(diào)試工具


          以往我們做適配的時候,需要先將我們項目中的 targetSdkVersion 修改為對應(yīng)版本。這就導(dǎo)致你適配過程中有可能受到其他變更的影響,而這個新增的兼容性調(diào)試工具可以讓你在不升級targetSdkVersion的情況下,針對每項變更逐個開啟適配。


          使用方法:


          • 開發(fā)者選項中找到應(yīng)用兼容性變更選項。


          • 點擊進入找到你需要調(diào)試的應(yīng)用。


          • 在變更列表中,找到想要開啟或關(guān)閉的變更,然后點擊相應(yīng)的開關(guān)。




          上面第一行DEFAULT_SCOPED_STORAGE就是啟用分區(qū)儲存,這些常量詳細的含義見:Android 11 變更列表

          https://developer.android.google.cn/about/versions/11/reference/compat-framework-changes


          對于兼容性調(diào)試工具詳細的使用方法見:兼容性框架工具,這里限于篇幅就不展開說了。


          無線調(diào)試


          Android 11的開發(fā)者選項中添加了一個無線調(diào)試的功能。類似于連接藍牙耳機功能,可以無需USB連接線進行日常開發(fā)調(diào)試工作。(區(qū)別于以前的Android WIFI ADB,這個是真無線,哈哈)



          使用方法:


          • 開發(fā)者選項中找到無線調(diào)試并打開。


          • 首次配對需點擊“使用配對碼配對設(shè)備”。


          • 運行 adb pair ipaddr:port后輸入配對碼進行連接。


          注意事項:



          • 保持電腦和手機在一個網(wǎng)絡(luò)。


          • Platform Tools 版本需大于30.0。可使用adb --version查看。


          不過我自己體驗下來,感覺連接不是很穩(wěn)定,不知是AS的問題還是手機問題。同時鎖屏后也會斷開連接,體驗不是很好。。。期待后續(xù)的優(yōu)化吧。

          6.總結(jié)

          本篇內(nèi)容有點多。總結(jié)一下,Android 11在權(quán)限上的變更比較多,但如果你一直遵守申請權(quán)限相關(guān)的最佳做法,那么基本上不需要額外的適配工作。

          https://developer.android.google.cn/privacy/best-practices#permissions


          最后強調(diào)一下,對于單次授權(quán),權(quán)限對話框的可見性,SYSTEM_ALERT_WINDOW 權(quán)限,安裝apk這些變更只要在Android 11上就會生效,不論你是否適配Android 11。對于其他變更和API(相機、5G、瀑布屏、鍵盤等),因為我暫時沒有遇到,也就沒有列出,有需要的可以點擊文末的官方文檔鏈接查看。


          截止發(fā)這篇博客時,我手機上只發(fā)現(xiàn)嗶哩嗶哩已經(jīng)適配了Android 11。大多數(shù)停留在28、29,更有甚者還在26(Android 8.0 國內(nèi)上架的最低適配標(biāo)準(zhǔn))。


          所以我順便附上之前寫的Android 9、10的適配攻略:


          Android 9.0 適配指南

          https://blog.csdn.net/qq_17766199/article/details/98336225?spm=1001.2014.3001.5501


          Android 10 適配攻略

          https://blog.csdn.net/qq_17766199/article/details/104513170?spm=1001.2014.3001.5501




          ·················END·················

          推薦閱讀

          ? 耗時2年,Android進階三部曲第三部《Android進階指北》出版!

          ? 『BATcoder』做了多年安卓還沒編譯過源碼?一個視頻帶你玩轉(zhuǎn)!

          ? 引入Jetpack架構(gòu)后,你的App會發(fā)生哪些變化?(建議收藏)

          ? 重生!進階三部曲第一部《Android進階之光》第2版 出版!

          BATcoder技術(shù)群,讓一部分人先進大廠

          大家,我是劉望舒,騰訊云最具價值專家TVP,著有暢銷書《Android進階之光》《Android進階解密》《Android進階指北》,蟬聯(lián)四屆電子工業(yè)出版社年度優(yōu)秀作者,谷歌開發(fā)者社區(qū)特邀講師,百度百科收錄的技術(shù)專家。

          前華為面試官,現(xiàn)大廠技術(shù)負責(zé)人。


          想要加入 BATcoder技術(shù)群,公號回復(fù)BAT 即可。

          為了防止失聯(lián),歡迎關(guān)注我的小號


              
            微信改了推送機制,真愛請星標(biāo)本公號??
          瀏覽 231
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  www.毛片av | 女同性恋一区二区 | 亚洲小黄片 | 91欧美日韩 | 国产一级片内射 |