淺談Android 14適配

引言

距離 Android 14 發布已經有一段時間了,趁著這次機會,了解和熟悉了 Android 14 更新的內容,現在來和大家分享一下,大家喜歡的話可以點個贊多多支持一下,文章的內容按照適配內容的重要程度進行排序。

targetSdk 版本要求

在 Android 14 上面,新增了一個要求,要求新安裝的應用的 targetSdkVersion 需要大于等于 23(即 Android 6.0 及以上),如果小于這個值將無法在 Android 14 的設備上面安裝,此時大家心里可能有疑惑了,谷歌為什么要求那么做呢?我們來看看谷歌的原話是什么

惡意軟件通常會以較舊的 API 級別為目標平臺, 以繞過在較新版本 Android 中引入的安全和隱私保護機制。 例如,有些惡意軟件應用使用 targetSdkVersion 22, 以避免受到 Android 6.0 Marshmallow(API 級別 23)在 2015 年引入的運行時權限模型的約束。 這項 Android 14 變更使惡意軟件更難以規避安全和隱私權方面的改進限制。

  • 從上面這段話不難看出來谷歌的用意,其實為了保障用戶的手機安全,如果用戶安裝應用的 targetSdkVersion 版本過低,有一些惡意軟件會利用高系統會兼容舊軟件這一特性(漏洞),故意繞過系統的安全檢查,從而會導致 Android 高版本上面一些安全特性無法生效,沒有了系統的管束,這些惡意軟件可能就會肆意亂來。

  • 另外你如果想在 Android 14 系統上面,仍然要安裝 targetSdkVersion 小于 23 的應用,可以通過以下 adb 命令來安裝 apk,這樣就能繞過系統的安裝限制。

adb install --bypass-low-target-sdk-block xxx.apk?

前臺服務類型要求
  • 如果你的應用 targetSdkVersion 升級到了 34(即 Android 14),并且在 Service 中調用了 startForeground 方法,那么就需要進行適配了,否則系統會拋出 MissingForegroundServiceTypeException 異常,這是因為在 Android 14 上面,要求應用在開啟前臺服務的時候,需要注明這個前臺服務的用途,谷歌給我們列舉了以下幾種用途:
用途說明清單文件權限要求運行時要求
攝像頭繼續在后臺訪問相機,例如支持多任務的視頻聊天應用FOREGROUND_SERVICE_CAMERA請求 CAMERA 運行時權限
連接的設備與需要藍牙、NFC、IR、USB 或網絡連接的外部設備進行互動FOREGROUND_SERVICE_CONNECTED_DEVICE必須至少滿足以下其中一個條件:

在清單中至少聲明以下其中一項權限:

CHANGE_NETWORK_STATE
CHANGE_WIFI_STATE
CHANGE_WIFI_MULTICAST_STATE
NFC
TRANSMIT_IR
至少請求以下其中一項運行時權限:

BLUETOOTH_CONNECT
BLUETOOTH_ADVERTISE
BLUETOOTH_SCAN
UWB_RANGING
調用 UsbManager.requestPermission()
?
數據同步數據傳輸操作,例如:

數據上傳或下載
備份和恢復操作
導入或導出操作
獲取數據
本地文件處理
通過網絡在設備和云端之間傳輸數據
FOREGROUND_SERVICE_DATA_SYNC
健康為健身類別的應用(例如鍛煉追蹤器)提供支持的所有長時間運行的用例FOREGROUND_SERVICE_HEALTH必須至少滿足以下其中一個條件:

在清單中聲明 HIGH_SAMPLING_RATE_SENSORS 權限。

至少請求以下其中一項運行時權限:

BODY_SENSORS
ACTIVITY_RECOGNITION
位置需要位置信息使用權的長時間運行的用例,
例如導航和位置信息分享
FOREGROUND_SERVICE_LOCATION至少請求以下其中一項運行時權限:

ACCESS_COARSE_LOCATION
ACCESS_FINE_LOCATION
媒體在后臺繼續播放音頻或視頻。
在 Android TV 上支持數字視頻錄制 (DVR) 功能。
FOREGROUND_SERVICE_MEDIA_PLAYBACK
媒體投影使用 MediaProjection API 將內容投影到非主要顯示屏或外部設備。這些內容不必全都為媒體內容。不包括 Cast SDKFOREGROUND_SERVICE_MEDIA_PROJECTION調用 createScreenCaptureIntent() 方法。 無
麥克風在后臺繼續捕獲麥克風內容,例如錄音器或通信應用FOREGROUND_SERVICE_MICROPHONE請求 RECORD_AUDIO 運行時權限
打電話使用 ConnectionService API 繼續當前通話FOREGROUND_SERVICE_PHONE_CALL在清單文件中聲明 MANAGE_OWN_CALLS 權限。
消息服務將短信從一臺設備轉移到另一臺設備。在用戶切換設備時,幫助確保用戶消息任務的連續性FOREGROUND_SERVICE_REMOTE_MESSAGING
短期服務快速完成不可中斷或推遲的關鍵工作。

這種類型有一些獨特的特征:

只能持續運行一小段時間(大約 3 分鐘)。
不支持粘性前臺服務。
無法啟動其他前臺服務。
不需要類型專用權限,不過它仍需要 FOREGROUND_SERVICE 權限。
正在運行的前臺服務不能更改為 shortService 類型或從該類型更改為其他類型。
特殊用途涵蓋其他前臺服務類型未涵蓋的所有有效前臺服務用例。

除了聲明 FOREGROUND_SERVICE_TYPE_SPECIAL_USE 前臺服務類型之外,開發者還應在清單中聲明用例。為此,他們會在 `` 元素內指定 <property> 元素。當您在 Google Play 管理中心內提交應用時,我們會審核這些值和相應的用例。
FOREGROUND_SERVICE_SPECIAL_USE
系統豁免為系統應用和特定系統集成預留,
使其能繼續使用前臺服務。

如需使用此類型,應用必須至少滿足以下條件之一:

設備處于演示模式狀態
應用是設備所有者
應用是性能分析器所有者
屬于具有 ROLE_EMERGENCY 角色的安全應用
屬于設備管理應用
否則,聲明此類型會導致系統拋出 ForegroundServiceTypeNotAllowedException
FOREGROUND_SERVICE_SYSTEM_EXEMPTED
  • 介紹完這幾種前臺服務類型,接下來介紹如何適配它,適配前臺服務類型的特性方式具體有兩種方式,一種是注冊清單屬性,另外一種是代碼動態注冊
<serviceandroid:name=".XxxService"android:foregroundServiceType="dataSync"android:exported="false">
</service>

startForeground(xxx, xxx, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC);

  • 另外附上前臺服務類型對應的適配屬性
用途清單文件屬性值Java 常量值
攝像頭cameraServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
連接的設備connectedDeviceServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE
數據同步dataSyncServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
健康healthServiceInfo.FOREGROUND_SERVICE_TYPE_HEALTH
位置locationServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION
媒體mediaPlaybackServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
媒體投影mediaProjectionServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
麥克風microphoneServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
打電話phoneCallServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL
消息服務remoteMessagingServiceInfo.FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING
短期服務shortServiceServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE
特殊用途specialUseServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE
系統豁免systemExemptedServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED
圖片和視頻的部分訪問權限
  • 谷歌在 API 33(Android 13)上面引入了 READ_MEDIA_IMAGESREAD_MEDIA_VIDEO 這兩個權限,目前針對這兩個權限在 Android 14 上面有新的變動,具體的變動點就是新增了 READ_MEDIA_VISUAL_USER_SELECTED 權限,那么這個權限的作用是什么呢?我們都知道 READ_MEDIA_IMAGESREAD_MEDIA_VIDEO 是申請圖片和視頻權限的,但是這樣會有一個問題,當第三方應用申請到權限后,就擁有了手機相冊中所有照片和視頻的訪問權限,這是十分危險的,也是非常不可控的,因為用戶也無法知道第三方應用會干什么,所以谷歌在 API 34(Android 14)引入了這個權限,這樣用戶擁有了更多的選擇,可以將相冊中所有的圖片和視頻授予給第三方應用,也可以將部分的圖片和視頻給第三方應用。

  • 講完了這個特性的來龍去脈,那么接下來講講這個權限如何適配,如果你的應用申請了 READ_MEDIA_IMAGES 或者 READ_MEDIA_VIDEO 權限,并且 targetSdkVersion 大于等于 33(Android 13),那么需要在申請權限時攜帶上 READ_MEDIA_VISUAL_USER_SELECTED 權限方能正常申請,如果不攜帶上 READ_MEDIA_VISUAL_USER_SELECTED 權限就申請 READ_MEDIA_IMAGES 或者 READ_MEDIA_VIDEO 權限,會彈出權限詢問對話框,但是如果用戶是選擇全部授予,那么 READ_MEDIA_IMAGES 或者 READ_MEDIA_VIDEO 權限狀態是已授予的狀態,如果用戶是選擇部分授予,那么 READ_MEDIA_IMAGES 或者 READ_MEDIA_VIDEO 權限狀態是已拒絕的狀態,假設此時有攜帶了 READ_MEDIA_VISUAL_USER_SELECTED 權限的情況下,那么 READ_MEDIA_VISUAL_USER_SELECTED 權限是已授予的狀態。

  • 看到這里,腦洞大的同學可能有想法了,那我不申請 READ_MEDIA_IMAGES 或者 READ_MEDIA_VIDEO 權限,我就只申請 READ_MEDIA_VISUAL_USER_SELECTED 權限行不行啊?答案也是不行的,我替大家試驗過了,這個權限申請會在不會詢問用戶的情況下,被系統直接拒絕掉。

  • 另外需要的一點是 READ_MEDIA_VISUAL_USER_SELECTED 屬于危險權限,除了在運行時動態申請外,還需要在清單文件中進行注冊。

registerReceiver 需要指定導出行為
  • 谷歌在 Android 12 (API 31)新增了四大組件需要指定 android:exported 屬性的特性,這次在 Android 13 上面做了一些變動,因為谷歌之前只考慮到靜態注冊四大組件的情況,但是遺漏了一種情況,BroadcastReceiver 不僅可以靜態注冊,還可以動態注冊,動態注冊的廣播不需要額外在 AndroidManifest.xml 中再進行靜態注冊,所以這次谷歌將這個規則漏洞補上了,并且要求開發者在動態注冊廣播的時候,能夠指定 BroadcastReceiver 是否能支持導出,由此來保護應用免受安全漏洞的影響。

  • 到此,大家心中可能有一個疑惑,這里的支持導出是什么意思?有產生什么作用?可以先看一下谷歌官方的原話

為了幫助提高運行時接收器的安全性,Android 13 允許您指定您應用中的特定廣播接收器是否應被導出以及是否對設備上的其他應用可見。 如果導出廣播接收器,其他應用將可以向您的應用發送不受保護的廣播。 此導出配置在以 Android 13 或更高版本為目標平臺的應用中可用,有助于防止一個主要的應用漏洞來源。 在以前的 Android 版本中,設備上的任何應用都可以向動態注冊的接收器發送不受保護的廣播,除非該接收器受簽名權限的保護。?

  • 谷歌的解釋很明了,如果廣播支持導出,那么其他應用可以通過發送這個廣播觸發我們應用的邏輯,這可能會發生程序安全漏洞的問題。

  • 那么該如何適配這一特性呢?谷歌官方提供了一個 registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) API,flags 參數傳入 Context.RECEIVER_EXPORTED(支持導出) 或 Context.RECEIVER_NOT_EXPORTED(不支持導出),具體的代碼適配代碼如下:

String action = "xxxxxx";
IntentFilter filter = new IntentFilter(action);
if (VERSION.SDK_INT >= VERSION_CODES.TIRAMISU) {context.registerReceiver(new LocaleChangeReceiver(), filter, Context.RECEIVER_EXPORTED);
} else {context.registerReceiver(new LocaleChangeReceiver(), filter);
}
  • 還有一種情況,不需要指定 flag 參數,就是當要注冊的廣播 action 隸屬系統的 action 時候,這個時候可以不需要指定導出行為。
更安全的動態代碼加載
  • 如果我們應用有動態加載代碼的需求,并且此時 targetSdk 升級到了 API 34(即 Android 14),那么需要注意一個點,動態加載的文件(Jar、Dex、Apk 格式)需要設置成可讀的,具體案例的代碼如下:
File jar = new File("xxxx.jar");
try (FileOutputStream os = new FileOutputStream(jar)) {jar.setReadOnly();
} catch (IOException e) { ... }
PathClassLoader cl = new PathClassLoader(jar, parentClassLoader);
  • 至于谷歌這樣做的原因,我覺得十分簡單,是為了程序的安全,防止有人搶先在動態加載之前先把動態文件替換了,那么會導致執行到一些惡意的代碼,間接導致應用被入侵或者篡改。
  • 另外需要注意的一個點的是,如果你的應用 targetSdk 大于等于 API 34(即 Android 14),如果不去適配這一特性,那么運行在 Android 14 的手機上面系統會拋出異常。

屏幕截圖檢測

Android 14 新增引入了屏幕截圖檢測的 API,方便開發者更好地檢測到用戶的操作,具體的使用案例如下:

在清單文件中靜態注冊權限

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

創建監聽器對象

final Activity.ScreenCaptureCallback screenCaptureCallback = new Activity.ScreenCaptureCallback() {@Overridepublic void onScreenCaptured() {// 監聽到截圖了}
};

在合適的時機注冊監聽

public final class XxxActivity extends Activity {@Overrideprotected void onStart() {super.onStart();registerScreenCaptureCallback(executor, screenCaptureCallback);}
}

在合適的時機取消注冊監聽

public final class XxxActivity extends Activity {@Overrideprotected void onStop() {super.onStop();unregisterScreenCaptureCallback(screenCaptureCallback);}
}
  • 需要注意的是,如果使用的是 adb 進行的截圖,并不會觸發 onScreenCaptured 監聽方法。

  • 如果不想你的應用能被系統截圖,可以考慮給當前的 Window 窗口加上 WindowManager.LayoutParams.FLAG_SECURE 標記位。

  • 最后表達一下我對這個 API 看法,這個 API 設計得不是很好,比如應用想知道用戶是否截圖了,應用可能需要知道的是,截圖文件的存放路徑,但是 onScreenCaptured 是一個空參函數,也就意味著沒有攜帶任何參數,如果要實現獲取截圖文件存放路徑的需求,可能還需要沿用之前的老方式,即使用 ContentObserver 監聽媒體數據庫的變化,然后從幾個維度(文件時間維度、文件路徑維度、圖片尺寸維度)判斷新增的圖片是否為用戶的截圖,這種實現的方式相對是比較麻煩的,但是也無發現更好的實現方式。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/206847.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/206847.shtml
英文地址,請注明出處:http://en.pswp.cn/news/206847.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

機器學習實戰:預測波士頓房價

前言&#xff1a; Hello大家好&#xff0c;我是Dream。 今天來學習一下機器學習中一個非常經典的案例&#xff1a;預測波士頓房價&#xff0c;在此過程中也會補充很多重要的知識點&#xff0c;歡迎大家一起前來探討學習~ 一、導入數據 在這個項目中&#xff0c;我們利用馬薩諸…

python-根據文件名移動已處理的文件

假設NC文件所在的文件夾為"nc_files"&#xff0c;CSV文件所在的文件夾為"csv_files"&#xff0c;目標文件夾為"target_folder"&#xff1a; import os import shutilnc_folder nc_files csv_folder csv_files target_folder target_folder# …

SAP UI5 walkthrough step4 XML Views

SAPUI5 指出多種VIEW類型&#xff0c;包括XML,HTML,JavaScript 推薦使用XML&#xff0c;因為可讀性更高 我們提前介紹一下MVC架構。 MVC是一種軟件架構模式&#xff0c;它包括三個主要組件&#xff1a;模型&#xff08;Model&#xff09;、視圖&#xff08;View&#xff09;…

element el-pagination solt 使用

起初只是想修改一下&#xff0c;共多少條的顏色&#xff0c;和跳轉至 發現并不支持 網上找通過js修改&#xff0c;因為我這是在 dialog里面的 好像并不能適用 mounted() {document.getElementsByClassName("el-pagination__jump")[0].childNodes[0].nodeValue &quo…

企業集團采購系統(供應商、詢價、招投標)-源碼

一、業務需求 企業招標詢價供應商管理系統是一種專業的采購管理系統&#xff0c;旨在幫助企業實現供應商關系的管理和采購成本的控制。該系統涵蓋了企業采購管理的各個方面&#xff0c;包括采購預算、供應商管理、產品管理、采購計劃、詢價、競價、招標、采購訂單、采購合同執…

Python零基礎入門之詳解sort排序使用

文章目錄 1.前言2.環境準備3.程序實現4.sort拓展關于Python技術儲備一、Python所有方向的學習路線二、Python基礎學習視頻三、精品Python學習書籍四、Python工具包項目源碼合集①Python工具包②Python實戰案例③Python小游戲源碼五、面試資料六、Python兼職渠道 1.前言 昨天一…

低代碼平臺選型標準:功能、應用與優劣勢分析

在數字化轉型的浪潮下&#xff0c;中小企業面臨滿足市場需求、提高效率和競爭力的挑戰。低代碼平臺做為數字化轉型的重要工具&#xff0c;為中小企業帶來了快速開發和定制應用程序解決方案。但是&#xff0c;在很多低代碼平臺中&#xff0c;選擇是一個重要的環節。企業應該根據…

Linux學習教程(第十一章 Linux高級文件系統管理)二

第十一章 Linux高級文件系統管理&#xff08;二&#xff09; 九、Linux如何判斷磁盤配額是否生效&#xff1f; 我們的磁盤配額已經生效&#xff0c;接下來測試一下是否會限制我們的用戶。以 lamp1 用戶為例&#xff0c; 因為 lamp1 用戶除容量被限制外&#xff0c;也限制了文…

如何選擇靠譜的軟件測試外包公司?CMA、CNAS軟件測試報告獲取

作為信息科技產業的代表之一&#xff0c;軟件公司受到了越來越多的關注&#xff0c;它們的發展為我國的科技創新提供了強大的戰略支撐。軟件測試作為提升軟件產品質量的后盾&#xff0c;日益成為一個專業化、標準化和規范化的行業&#xff0c;軟件測試外包公司就是這種背景下成…

免費接口匯總,為程序員節省開發成本

最近整理的好用免費API接口&#xff0c;趕緊收藏起來吧&#xff01; 短信驗證碼&#xff1a;可用于登錄、注冊、找回密碼、支付認證等等應用場景。支持三大運營商&#xff0c;3秒可達&#xff0c;99.99&#xff05;到達率&#xff0c;支持大容量高并發。通知短信&#xff1a;當…

軟件開發全過程必備文檔下載(@附所有文檔)

在軟件開發的全過程中&#xff0c;編寫文檔是一項至關重要的任務。良好的文檔記錄不僅可以提高開發效率&#xff0c;減少錯誤&#xff0c;還可以為后續維護和擴展提供可靠的依據。下面我們將探討軟件開發全過程中必備的幾種文檔。 1.需求文檔 需求文檔是軟件開發項目的起點&a…

VSCode 附加 Windows C/C++ 程序配置(launch.json)

{// 使用 IntelliSense 了解相關屬性。 // 懸停以查看現有屬性的描述。// 欲了解更多信息&#xff0c;請訪問: https://go.microsoft.com/fwlink/?linkid830387"version": "0.2.0","configurations": [{"name": "Attach To Game…

flutter添加全局水印

效果&#xff1a; 可以直接引用&#xff1a;disable_screenshots: ^0.2.0 但是有時候直接引用會報錯&#xff0c;可以不引用插件直接把下面的源碼工具類放在項目里面 工具類源碼&#xff1a; import dart:io; import dart:math;import package:flutter/cupertino.dart; impor…

FastAPI請求體-多個參數

路徑參數、查詢參數&#xff0c;和請求體混合 首先&#xff0c;我們需要導入所需的庫。我們將使用FastAPI、Path和Annotated來處理路由和參數&#xff0c;并使用BaseModel和Union來自定義數據模型。 完整示例代碼 from typing import Annotated, Unionfrom fastapi import F…

剪切板管理 Paste中文 for Mac

Paste是一個方便的剪貼板管理工具&#xff0c;它可以幫助你更好地組織、查找和管理剪貼板中的內容。它提供了歷史記錄、搜索、組織、格式處理和云同步等功能&#xff0c;使你能夠更高效地使用剪貼板&#xff0c;并節省時間和精力。無論是在個人使用還是團隊協作中&#xff0c;P…

linux云服務器開啟防火墻注意事件

重要的事情先說三遍: linux云服務器開啟防火墻要先獲取到云服務器的管理界面控制權!! linux云服務器開啟防火墻要先獲取到云服務器的管理界面控制權!! linux云服務器開啟防火墻要先獲取到云服務器的管理界面控制權!! 也就是能打開這個頁面: 為什么這么說呢?如果你…

11.Java安卓程序設計-基于SSM框架的Android平臺健康管理系統的設計與實現

摘要 隨著人們生活水平的提高和健康意識的增強&#xff0c;健康管理系統在日常生活中扮演著越來越重要的角色。本研究旨在設計并實現一款基于SSM框架的Android平臺健康管理系統&#xff0c;為用戶提供全面的健康監測和管理服務。 在需求分析階段&#xff0c;我們明確了系統的…

帆軟報表決策報表改變屏幕大小后出現字體大小或滾動條異常解決方案:雙向自適應

帆軟報表決策報表改變屏幕大小后出現字體大小或滾動條異常。 解決方案&#xff1a;在模板和報表塊中配置雙向自適應 在每一個報表塊中設置&#xff1a;

記錄每日LeetCode 763.劃分字母區間 Java實現

題目描述&#xff1a; 給你一個字符串 s 。我們要把這個字符串劃分為盡可能多的片段&#xff0c;同一字母最多出現在一個片段中。 注意&#xff0c;劃分結果需要滿足&#xff1a;將所有劃分結果按順序連接&#xff0c;得到的字符串仍然是 s 。 返回一個表示每個字符串片段的…