主頁 > 移動端開發 > Android各版本迭代改動與適配集合

Android各版本迭代改動與適配集合

2020-12-19 08:35:45 移動端開發

前言

今天分享的面試題是:

Android在版本迭代中,總會進行很多改動,那么你熟知各版本都改動了什么內容?又要怎么適配呢?

Android4.4

  • 發布ART虛擬機,提供選項可以開啟,
  • HttpURLConnection的底層實作改為了OkHttp,

Android5.0

  • ART成為默認虛擬機,完全代替Dalvik虛擬機,
  • Context.bindService() 方法需要顯式 Intent,如果提供隱式 intent,將引發例外,

Android6.0

  • 增加運行時權限限制

如果你的應用使用到了危險權限,比如在運行時進行檢查和請求權限,checkSelfPermission()方法用于檢查權限,requestPermissions() 方法用于請求權限,

  • 取消支持Apache HTTP

Android 6.0 版移除了對 Apache HTTP相關類別庫的支持,要繼續使用 Apache HTTP API,您必須先在 build.gradle 檔案中宣告以下編譯時依賴項:

android {useLibrary 'org.apache.http.legacy'}

有的小伙伴可能不熟悉這是啥,簡單說下:

Apache HttpClient 是Apache開源組織提供的一個開源的專案,它是一個簡單的HTTP客戶端(并不是瀏覽器),可以發送HTTP請求,接受HTTP回應,

所以說白了,其實就是一個請求網路的專案框架,

Android 7.0

  • Android 7.0 引入一項新的應用簽名方案 APK Signature Scheme v2

  • Toast導致的BadTokenException

  • 在Android7.0系統上,Android 框架強制執行了 StrictMode API 政策禁止向你的應用外公開 file:// URI, 如果一項包含檔案 file:// URI型別 的 Intent 離開你的應用,應用失敗,并出現 FileUriExposedException 例外,如呼叫系統相機拍照錄制視頻,或裁切照片,

這一點其實就是限制了在應用間共享檔案,如果需要在應用間共享,需要授予要訪問的URI臨時訪問權限,我們要做的就是注冊FileProvider

1)宣告FileProvider,

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="app的包名.fileProvider"
    android:grantUriPermissions="true"
    android:exported="false">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>
<!--androidx版本類路徑為:androidx.core.content.FileProvider-->

2)撰寫xml檔案,確定可訪問的目錄

<paths xmlns:android="http://schemas.android.com/apk/res/android">
	//代表設備的根目錄new File("/");
    <root-path name="root" path="." /> 
    //context.getFilesDir()
    <files-path name="files" path="." /> 
    //context.getCacheDir()
    <cache-path name="cache" path="." /> 
    //Environment.getExternalStorageDirectory()
    <external-path name="external" path="." />
    //context.getExternalFilesDirs()
    <external-files-path name="name" path="path" />
    //getExternalCacheDirs()
     <external-cache-path name="name" path="path" />
</paths>

3)使用FileProvider

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    Uri uri = FileProvider.getUriForFile(CameraActivity.this, "app的包名.fileProvider", photoFile);
} else {
    Uri uri = Uri.fromFile(photoFile);
}

Android8.0

  • 修改運行時權限錯誤

Android 8.0 之前,如果應用在運行時請求權限并且被授予該權限,系統會錯誤地將屬于同一權限組并且在清單中注冊的其他權限也一起授予應用,
對于針對 Android 8.0 的應用,系統只會授予應用明確請求的權限,然而,一旦用戶為應用授予某個權限,則所有后續對該權限組中權限的請求都將被自動批準,

也就是說,以前你申請了READ_EXTERNAL_STORAGE權限,應用會同時給你授予同權限組的WRITE_EXTERNAL_STORAGE權限,如果Android8.0以上,只會給你授予你請求的READ_EXTERNAL_STORAGE權限,如果需要WRITE_EXTERNAL_STORAGE權限,還要單獨申請,不過系統會立即授予,不會提示,

  • 修改通知

Android 8.0 對于通知修改了很多,比如通知渠道、通知標志、通知超時、背景顏色,其中比較重要的就是通知渠道,其允許您為要顯示的每種通知型別創建用戶可自定義的渠道,

這樣的好處就是對于某個應用可以把權限分成很多類,用戶來控制是否顯示哪些類別的通知,而開發者要做的就是必須設定這個渠道id,否則通知可能會失效,

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

            NotificationManager notificationManager = (NotificationManager)
                    getSystemService(Context.NOTIFICATION_SERVICE);

            //分組(可選)
            //groupId要唯一
            String groupId = "group_001";
            NotificationChannelGroup group = new NotificationChannelGroup(groupId, "廣告");

            //創建group
            notificationManager.createNotificationChannelGroup(group);

            //channelId要唯一
            String channelId = "channel_001";

            NotificationChannel adChannel = new NotificationChannel(channelId,
                    "推廣資訊", NotificationManager.IMPORTANCE_DEFAULT);
            //補充channel的含義(可選)
            adChannel.setDescription("推廣資訊");
            //將渠道添加進組(先創建組才能添加)
            adChannel.setGroup(groupId);
            //創建channel
            notificationManager.createNotificationChannel(adChannel);

			//創建通知時,標記你的渠道id
            Notification notification = new Notification.Builder(MainActivity.this, channelId)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
                    .setContentTitle("一條新通知")
                    .setContentText("這是一條測驗訊息")
                    .setAutoCancel(true)
                    .build();
            notificationManager.notify(1, notification);

        }
    }
  • 懸浮窗

Android8.0以上必須使用新的視窗型別(TYPE_APPLICATION_OVERLAY)才能顯示提醒懸浮窗:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    mWindowParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
}else {
    mWindowParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
}
  • 不允許安裝未知來源的應用

Android 8.0去除了“允許未知來源”選項,所以如果我們的App有安裝App的功能(檢查更新之類的),那么會無法正常安裝,

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

private void installAPK(){

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            boolean hasInstallPermission = getPackageManager().canRequestPackageInstalls();
            if (hasInstallPermission) {
                //安裝應用
            } else {
                //跳轉至“安裝未知應用”權限界面,引導用戶開啟權限
                Uri selfPackageUri = Uri.parse("package:" + this.getPackageName());
                Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, selfPackageUri);
                startActivityForResult(intent, 100);
            }
        }else {
            //安裝應用
        }

    }

    //接收“安裝未知應用”權限的開啟結果
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 100) {
            installAPK();
        }
    }

  • Only fullscreen opaque activities can request orientation

只有全屏不透明的activity才可以設定方向,這應該是個bug,在Android8.0中出現,8.1中被修復,

我們的處理辦法就是要么去掉設定方向的代碼,要么舍棄透明效果,

Android9.0

  • 在9.0中默認情況下啟用網路傳輸層安全協議 (TLS),默認情況下已停用明文支持,也就是不允許使用http請求,要求使用https,解決辦法就是添加網路安全配置:
<application android:networkSecurityConfig="@xml/network_security_config">

<network-security-config>
 <base-config cleartextTrafficPermitted="true" />
</network-security-config>


<!--或者在AndroidManifest.xml中配置:
android:usesCleartextTraffic="true"
-->

  • 移除Apache HTTP 客戶端

在6.0中取消了對Apache HTTP 客戶端的支持,Android9.0中直接移除了該庫,要使用的話需要添加配置:

<uses-library android:name="org.apache.http.legacy" android:required="false"/>
  • 前臺服務呼叫

Android 9.0 要求創建一個前臺服務需要請求 FOREGROUND_SERVICE 權限,否則系統會引發 SecurityException,

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

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
    startForegroundService(intentService);
} else {
    startService(intentService);
}

  • 不能在非Acitivity環境中啟動Activity

在9.0 中,不能直接非 Activity 環境中(比如Service,Application)啟動 Activity,否則會崩潰報錯,解決辦法就是加上FLAG_ACTIVITY_NEW_TASK

Intent intent = new Intent(this, TestActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

Android10

  • 磁區存盤

Android10中默認開啟了磁區存盤,也就是沙盒模式,應用只能看到本應用專有的目錄(通過 Context.getExternalFilesDir() 訪問)以及特定型別的媒體,

如果需要關閉這個功能可以配置:

android:requestLegacyExternalStorage="true"

磁區存盤下,訪問檔案的方法:

1)應用專屬目錄

//磁區存盤空間
val file = File(context.filesDir, filename)

//應用專屬外部存盤空間
val appSpecificExternalDir = File(context.getExternalFilesDir(), filename)

2)訪問公共媒體目錄檔案

val cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, "${MediaStore.MediaColumns.DATE_ADDED} desc")
if (cursor != null) {
    while (cursor.moveToNext()) {
        val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID))
        val uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)
        println("image uri is $uri")
    }
    cursor.close()
}

3)SAF(存盤訪問框架--Storage Access Framework)

    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
    intent.addCategory(Intent.CATEGORY_OPENABLE)
    intent.type = "image/*"
    startActivityForResult(intent, 100)

    @RequiresApi(Build.VERSION_CODES.KITKAT)
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (data =https://www.cnblogs.com/jimuzz/p/= null || resultCode != Activity.RESULT_OK) return
        if (requestCode == 100) {
            val uri = data.data
            println("image uri is $uri")
        }
    }

  • 權限再次升級

從Android10開始普通應用不再允許請求權限android.permission.READ_PHONE_STATE,而且,無論你的App是否適配過Android Q(既targetSdkVersion是否大于等于29),均無法再獲取到設備IMEI等設備資訊,

如果Android10以下設備獲取設備IMEI等資訊,可以配置最大sdk版本:

<uses-permission android:name="android.permission.READ_PHONE_STATE"
        android:maxSdkVersion="28"/>

Android 11

  • 磁區存盤強制執行

沒錯,Android11強制執行磁區存盤,也就是沙盒模式,這次真的沒有關閉功能了,離Android11出來也有一段時間了,還是抓緊適配把,

  • 修改電話權限

改動了兩個API:getLine1Number()和 getMsisdn() ,需要加上READ_PHONE_NUMBERS權限

  • 不允許自定義toast從后臺顯示了

  • 必須加上v2簽名

  • 增加5g相關API

  • 后臺位置訪問權限再次限制

你一定很奇怪,為什么Android11的適配就這么草草收尾了?這可是我們最需要的啊?

哈哈,因為改動還是挺多的,所以給你推薦文章—Android11最全適配指南,應該有很多朋友都看過了:
https://juejin.cn/post/6860370635664261128

參考

https://juejin.cn/post/6898176468661059597
https://blog.csdn.net/qq_17766199/article/details/80965631
https://weilu.blog.csdn.net/article/details/98336225

拜拜

有一起學習的小伙伴可以關注下?? 我的公眾號——碼上積木,每天剖析一個知識點,我們一起積累知識,公眾號回復111可獲得面試題《思考與解答》以往期刊,

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/237074.html

標籤:Android

上一篇:【請教】PHP使用JSAPI支付,是和JSON包一樣的?還是只能XML?

下一篇:Android各版本迭代改動與適配集合

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more