Android適配之版本適配

這篇文章用來記錄學(xué)習(xí)和開發(fā)時(shí)遇到的版本適配問題轰坊,持續(xù)更新

\color{red}{Android9.0即API 28-適配}
  • 全面屏铸董、劉海屏的適配:
    Android 9 支持最新的全面屏,其中包含為攝像頭和揚(yáng)聲器預(yù)留空間的屏幕缺口肴沫。
    通過 DisplayCutout 類可確定非功能區(qū)域的位置和形狀粟害,這些區(qū)域不應(yīng)顯示內(nèi)容。
    要確定這些屏幕缺口區(qū)域是否存在及其位置颤芬,使用 getDisplayCutout()函數(shù)悲幅。
    LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT:
    只有當(dāng)DisplayCutout完全包含在系統(tǒng)欄中時(shí),才允許窗口擴(kuò)展到DisplayCutout區(qū)域站蝠。否則汰具,窗口的布局不會(huì)與顯示剪切區(qū)域重疊。
    LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES:
    屏幕短邊有cutout菱魔,會(huì)延伸過去留荔;若cutout在長(zhǎng)邊,一定不會(huì)延伸過去澜倦。
    LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER:
    窗口決不允許與顯示剪切區(qū)域重疊聚蝶。
    設(shè)置代碼:
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
getWindow().setAttributes(lp);
  • 通知功能的變更
    Android 8.0 引入了通知渠道,允許您為要顯示的每種通知類型創(chuàng)建可由用戶自定義的渠道藻治。 Android 9 通過下列變更簡(jiǎn)化通知渠道設(shè)置:
    1.)屏蔽渠道組:現(xiàn)在碘勉,用戶可以針對(duì)某個(gè)應(yīng)用在通知設(shè)置中屏蔽整個(gè)渠道組。 您可以使用 isBlocked() 函數(shù)確定何時(shí)屏蔽一個(gè)渠道組桩卵,從而不會(huì)向該組中的渠道發(fā)送任何通知验靡。
    此外,您的應(yīng)用可以使用全新的 getNotificationChannelGroup() 函數(shù)查詢當(dāng)前渠道組設(shè)置雏节。
    2.)全新的廣播 Intent 類型:現(xiàn)在胜嗓,當(dāng)通知渠道和渠道組的屏蔽狀態(tài)發(fā)生變更時(shí),Android 系統(tǒng)將發(fā)送廣播 Intent矾屯。 擁有已屏蔽的渠道或渠道組的應(yīng)用可以偵聽這些 Intent 并做出相應(yīng)的回應(yīng)兼蕊。
    有關(guān)這些 Intent 操作和 extra 的更多信息,請(qǐng)參閱 NotificationManager 參考中更新的常量列表件蚕。 有關(guān)響應(yīng)廣播 Intent 的信息孙技,請(qǐng)參閱廣播。

  • 權(quán)限收緊
    1.)為了增強(qiáng)用戶隱私排作,Android 9 引入了若干行為變更牵啦,如限制后臺(tái)應(yīng)用訪問設(shè)備傳感器、限制通過 Wi-Fi 掃描檢索到的信息妄痪,以及與通話哈雏、手機(jī)狀態(tài)和 Wi-Fi 掃描相關(guān)的新權(quán)限規(guī)則和權(quán)限組。
    無論采用哪一種目標(biāo) SDK 版本,這些變更都會(huì)影響運(yùn)行于 Android 9 上的所有應(yīng)用裳瘪。
    2.)Android 9 限制后臺(tái)應(yīng)用訪問用戶輸入和傳感器數(shù)據(jù)的能力土浸。
    如果您的應(yīng)用在運(yùn)行 Android 9 設(shè)備的后臺(tái)運(yùn)行,系統(tǒng)將對(duì)您的應(yīng)用采取以下限制:
    您的應(yīng)用不能訪問麥克風(fēng)或攝像頭彭羹。
    使用連續(xù)報(bào)告模式的傳感器(例如加速度計(jì)和陀螺儀)不會(huì)接收事件黄伊。
    使用變化或一次性報(bào)告模式的傳感器不會(huì)接收事件。
    如果您的應(yīng)用需要在運(yùn)行 Android 9 的設(shè)備上檢測(cè)傳感器事件派殷,請(qǐng)使用前臺(tái)服務(wù)还最。

  • 對(duì)使用非 SDK 接口的限制
    目前處理方式掃描代碼,避免使用或者使用類似的替代方法毡惜,如果避免不了拓轻,最粗暴的是try-catch,正統(tǒng)做法是每處都做if-else的Android9適配经伙,如果是第三方庫扶叉,可以屏蔽入口,或者反編譯sdk處理帕膜,
    處理起來比較復(fù)雜辜梳,官方受限制名單也還沒完全確定,等待后續(xù)解決辦法吧泳叠。

\color{red}{Android8.0即API 26-27適配}
  • 自定義icon-launcher圖標(biāo)

  • 通知相關(guān)修改
    1.)通知渠道組 NotificationChannel,渠道ID channelId的規(guī)則茶宵,大改很多危纫,包括提供了應(yīng)用桌面圖標(biāo)有通知顯示小圓點(diǎn),長(zhǎng)按圖標(biāo)還能進(jìn)行消息操作等
    顯示小圓點(diǎn):
    channel.setShowBadge(true);
    右上角還有一個(gè)數(shù)字角標(biāo):
    Notification.Builder builder=new Notification.Builder(this, channelId);
    builder.setNumber(10);
    通知超時(shí):
    Notification.Builder builder=new Notification.Builder(this, channelId);
    builder.setTimeoutAfter(timeout*1000)
    背景顏色:這個(gè)屬性要生效乌庶,必須是持續(xù)任務(wù)种蝶,且是前臺(tái)服務(wù)
    builder.setColorized(true);
    builder.setColor(Color.BLACK);
    通知清除回調(diào):
    系統(tǒng)現(xiàn)在可區(qū)分通知是由用戶清除,還是由應(yīng)用自己移除瞒大。要查看清除通知的方式螃征,應(yīng)實(shí)現(xiàn)NotificationListenerService類的新onNotificationRemoved()方法
    AndroidManifest里面不要忘記加配置,這么做透敌,我還是可以保證你沒有任何回調(diào)會(huì)發(fā)生盯滚,因?yàn)檫@里面有個(gè)別別竅,要手動(dòng)開啟通知訪問權(quán)限酗电。來看模擬器上的操作流程魄藕,設(shè)置>應(yīng)用和通知>高級(jí)>特殊應(yīng)用權(quán)限->通知使用權(quán)
    通過判斷第三個(gè)參數(shù)reason是REASON_CANCEL還是REASON_LISTENER_CANCEL就可以知道是用戶刪除還是系統(tǒng)刪除了

  • 后臺(tái)服務(wù)限制
    在后臺(tái)中運(yùn)行的服務(wù)會(huì)消耗系統(tǒng)資源,這可能降低用戶體驗(yàn)撵术。 為了緩解這一問題背率,系統(tǒng)對(duì)這些服務(wù)施加了一些限制。那么什么情況下應(yīng)用被視為處于前臺(tái)?
    1.)具有可見Activity(不管該Activity已啟動(dòng)還是已暫停)
    2.)具有前臺(tái)服務(wù)
    3.)另一個(gè)前臺(tái)應(yīng)用已關(guān)聯(lián)到該應(yīng)用(不管是通過綁定到其中一個(gè)服務(wù)寝姿,還是通過使用其中一個(gè)內(nèi)容提供程序)交排。
    例如,如果另一個(gè)應(yīng)用綁定到該應(yīng)用的服務(wù)饵筑,那么該應(yīng)用處于前臺(tái):輸入法埃篓、壁紙服務(wù)、語音等
    如果以上條件均不滿足翻翩,應(yīng)用將被視為處于后臺(tái)都许。
    startForegroundService方法調(diào)用后,記得5秒鐘內(nèi)調(diào)用startForeground方法嫂冻,否則系統(tǒng)將停止服務(wù)并聲明此應(yīng)用為ANR胶征。具體使用看官方文檔即可,不做贅述桨仿。
    4.)后臺(tái)位置限制:
    之前說的后臺(tái)服務(wù)限制目前只針對(duì)目標(biāo)SDK版本為8.0的app睛低,但是涉及到后臺(tái)位置限制就是所有版本SDK都要調(diào)整的了,它限制后臺(tái)應(yīng)用每小時(shí)只接收幾次位置更新服傍。
    當(dāng)然钱雷,解決的辦法是一樣的,依然是建立前臺(tái)服務(wù)

  • Android 8.0去除“允許未知來源”選項(xiàng)吹零,需手動(dòng)確認(rèn)罩抗。
    如果我們的App具備安裝App的功能,那么AndroidManifest文件需要包含REQUEST_INSTALL_PACKAGES權(quán)限灿椅,未聲明此權(quán)限的應(yīng)用將無法安裝其他應(yīng)用套蒂。
    我們可以選擇使用 Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES這個(gè)action將用戶引導(dǎo)至安裝未知應(yīng)用權(quán)限界面。
    同時(shí)也可以使用 packageManager.canRequestPackageInstalls()查詢此權(quán)限的狀態(tài)
    不過最簡(jiǎn)單的辦法就是直接在AndroidManifest中配置一下就行了茫蛹,這樣會(huì)在App調(diào)用安裝界面的同時(shí)操刀,系統(tǒng)會(huì)自動(dòng)詢問用戶完成授權(quán),體驗(yàn)尚可婴洼。

  • 懸浮窗相關(guān)
    這個(gè)東西篇幅較長(zhǎng)骨坑,使用頻率不高,后面可能會(huì)單獨(dú)一篇文章說這個(gè)柬采,在此便不做贅述欢唾,有興趣的可自行了解。

\color{red}{Android7.0即API 24-25適配}
  • FileProvider
    對(duì)于app目標(biāo)版本大于等于24的應(yīng)用粉捻,禁止在應(yīng)用外部公開 file:// URI 匈辱, 如果一項(xiàng)包含文件 URI 的 intent 離開應(yīng)用,則應(yīng)用出現(xiàn) FileUriExposedException 異常杀迹。
    要應(yīng)用間共享文件亡脸,您應(yīng)發(fā)送一項(xiàng) content:// URI押搪,并授予 URI 臨時(shí)訪問權(quán)限。進(jìn)行此授權(quán)的最簡(jiǎn)單方式是使用 FileProvider類浅碾。如需了解有關(guān)權(quán)限和共享文件的詳細(xì)信息大州,請(qǐng)參閱官方文檔。
    FileProvider 實(shí)際上是 ContentProvider 的一個(gè)子類垂谢,它的作用也比較明顯厦画,file://Uri 不給用,那么換個(gè) Uri 為 content:// 來替代滥朱。

接下來看下如何使用:
1根暑、定義 FileProvider
我們先在 AndroidManifest 中進(jìn)行注冊(cè)

  <!-- provider -->
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.hccf.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths_public" />
        </provider>

2、指定可分享的文件路徑
FileProvider 只能為指定的目錄中的文件生成內(nèi)容 URI徙邻。要指定目錄排嫌,就必須使用 <paths> 元素的子元素在 XML 中指定其存儲(chǔ)區(qū)域和路徑。

我們先創(chuàng)建一個(gè)名為 res/xml/file_paths_public.xml 的新文件

<paths>
    <!--圖片-->
    <external-path
        name="my_images"
        path="Pictures/" />

    <!--自定義根目錄-->
    <root-path
        name="root_path"
        path="." />
</paths>

在 paths 節(jié)點(diǎn)內(nèi)部支持以下幾個(gè)子節(jié)點(diǎn)缰犁,分別為:

  • root-path:設(shè)備的根目錄 new File("/")
  • files-path:context.getFileDir()
  • cache-path:context.getCacheDir()
  • external-path:Environment.getExternalStorageDirectory()
  • external-files-path:context.getExternalFilesDirs()
  • external-cache-path:getExternalCacheDirs()

代碼中的常見用法:

Intent intent = new Intent("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // FileProvider方式必須加這個(gè)臨時(shí)權(quán)限
Uri uri = FileProvider.getUriForFile(mContext, "com.hccf.fileprovider", file);
intent.setDataAndType(uri, "application/pdf");
mContext.startActivity(intent);

還有一種用法是: 使用Context 的 grantUriPermission() 方法和revokeUriPermission(); 這種比較少用淳地。

至此,FileProvider的介紹就差不多結(jié)束了帅容。

  • V2簽名
    APK signature scheme v2:
    Android 7.0 引入一項(xiàng)新的應(yīng)用簽名方案 APK Signature Scheme v2颇象,它能提供更快的應(yīng)用安裝時(shí)間和更多針對(duì)未授權(quán) APK 文件更改的保護(hù)。在默認(rèn)情況下并徘,Android Studio 2.2 和 Android Plugin for Gradle 2.2 會(huì)使用 APK Signature Scheme v2 和傳統(tǒng)簽名方案來簽署您的應(yīng)用遣钳。

使用Android Studio 自帶的打包工具的話,只有勾選了了v2簽名的方式麦乞,app才能在目標(biāo)版本24及以上的7.0系統(tǒng)手機(jī)安裝耍贾。

還有一些其他的比較少遇到的,就不做贅述了路幸,參考文章:
https://blog.csdn.net/qq_17766199/article/details/77404712

\color{red}{Android6.0即API 23適配}
  • 運(yùn)行時(shí)權(quán)限
    Android6.0推出的重大更新,收緊權(quán)限付翁,提高應(yīng)用安全简肴。具體介紹參考文章即可:
    https://blog.csdn.net/qq_17766199/article/details/77404712
    一般推薦使用一些第三方框架,他們已經(jīng)幫你做好了大部分機(jī)型的適配問題百侧。
    本人使用的RxPermissions
    使用方式:
            // 獲取權(quán)限
            RxPermissions rxPermissions = new RxPermissions(getActivity());
            rxPermissions.request(Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    .subscribe(new Observer<Boolean>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onNext(Boolean aBoolean) {
                            if (aBoolean){
                                // 權(quán)限獲取成功 開始下載
                            }
                        }

                        @Override
                        public void onError(Throwable e) {
                            // 獲取權(quán)限失敗砰识,跳轉(zhuǎn)設(shè)置頁面
                            new PermissionPageUtils(getActivity()).jumpPermissionPage();
                            ToastUtils.showLongBottom("獲取權(quán)限失敗,請(qǐng)檢查是否開啟所需權(quán)限");
                        }

                        @Override
                        public void onComplete() {

                        }
                    });
\color{red}{Android5.0即API 21-22適配}
  • 未完待續(xù)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末佣渴,一起剝皮案震驚了整個(gè)濱河市辫狼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌辛润,老刑警劉巖膨处,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡真椿,警方通過查閱死者的電腦和手機(jī)鹃答,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來突硝,“玉大人测摔,你說我怎么就攤上這事〗馇。” “怎么了锋八?”我有些...
    開封第一講書人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)护盈。 經(jīng)常有香客問我挟纱,道長(zhǎng),這世上最難降的妖魔是什么黄琼? 我笑而不...
    開封第一講書人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任樊销,我火速辦了婚禮,結(jié)果婚禮上脏款,老公的妹妹穿的比我還像新娘围苫。我一直安慰自己,他們只是感情好撤师,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開白布剂府。 她就那樣靜靜地躺著,像睡著了一般剃盾。 火紅的嫁衣襯著肌膚如雪腺占。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評(píng)論 1 312
  • 那天痒谴,我揣著相機(jī)與錄音衰伯,去河邊找鬼。 笑死积蔚,一個(gè)胖子當(dāng)著我的面吹牛意鲸,可吹牛的內(nèi)容都是我干的膏潮。 我是一名探鬼主播抱怔,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼兼贸,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼勘纯!你這毒婦竟也來了崇众?” 一聲冷哼從身側(cè)響起榄审,我...
    開封第一講書人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤巾遭,失蹤者是張志新(化名)和其女友劉穎若河,沒想到半個(gè)月后幅狮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體募强,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡株灸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钻注。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚂且。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖幅恋,靈堂內(nèi)的尸體忽然破棺而出杏死,到底是詐尸還是另有隱情,我是刑警寧澤捆交,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布淑翼,位于F島的核電站,受9級(jí)特大地震影響品追,放射性物質(zhì)發(fā)生泄漏玄括。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一肉瓦、第九天 我趴在偏房一處隱蔽的房頂上張望遭京。 院中可真熱鬧,春花似錦泞莉、人聲如沸哪雕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽斯嚎。三九已至,卻和暖如春挨厚,著一層夾襖步出監(jiān)牢的瞬間堡僻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工疫剃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钉疫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓巢价,卻偏偏與公主長(zhǎng)得像牲阁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蹄溉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容