草庐IT

android新版本适配-android13最全适配方案

失落夏天 2023-04-26 原文

前言:

 适配Android13事不容缓

2022年9月14-2022年9月15日,Google中国开发者大会在上海举办,大会上,演讲嘉宾大约抽出了半个小时时间讲解android13的新特性。这也意味着,Android离我们越来越近了。

目前,小米,VIVO等中国厂商的主流手机已经支持Android了,我估计,大约年底应该就会有Android13的系统逐渐推送到用户手机上,所以,适配Android13已经变的非常紧迫了。

官方文档:

本身主要是参考谷歌官方文档来写的,是对官方文章的一个实践和细化,官方文档链接如下:

https://developer.android.com/about/versions/13/features#themed-app-icons

我们把Android13的变化主要分为两部分,第一部分,原来就有的,在第二篇章讲解。另外一部分是新增的,有可能用得到的,放在第三章中去讲解。

所以,本文主要分为三大块讲解:

1.真机如何升级到Android13;

2.Android13有哪些功能的变化以及对应的适配方案;

3.Android13有哪些新的功能以及如何使用。

一.真机如何升级Android13

真机我们主要分为两类,谷歌pixel和其它品牌手机。

1.1其它品牌

其它品牌手机,主要是通过注册开发者版本进行升级的,因为不同品牌的手机升级方式不一样,这里就不具体讲解了。

目前支持的品牌列表如下:

  • 华硕
  • 联想
  • 诺基亚
  • 一加
  • OPPO
  • 真我
  • 夏普
  • TECNO
  • Vivo
  • 小米
  • 中兴

1.2 Pixel升级

本文主要以Pixel升级Android13为例。

谷歌升级主页链接如下:https://developer.android.com/about/versions/13/get

主要分为两种升级方式:

1.注册Pixel的Android13 Beta版计划

2.刷写或手动安装系统映像

注册Pixel的Android13 Beta版计划

首先第一种方式,需要登陆Google账号,然后在官方网页点击注册“注册适用于 Pixel 的 Android 13 Beta 版计划”,然后一步步操作就可以。最后点击pixel手机的系统,就会提示新版本可更新了。

但是这种方式有几个缺陷,首先,登陆Google账号需要翻墙。其次同一步手机只能加入一个版本计划,加入了android12后必须退出才能加入android13。电脑翻墙还可以通过代理,手机翻墙还是蛮麻烦的。安卓11升12时我使用的是这种方式,但是12升13搞了好久还是无法解决手机翻墙的问题,于是放弃了这种方式。

直接刷写的方式

第二种方式就是直接刷写的方式。pixel的可以直接把chrome浏览器当作刷写工具,不需要下载额外的软件,这一点还是蛮方便的,我最终也是选择的这种方式升级的,具体介绍一下这种方式:

1:手机设置打开开发者模式,允许USB调试;

2:点击 Android刷写工具,打开新网页,如下图所示:

 3:新打开的网页,有一个弹出框(这里需要注意是否被浏览器拦截掉),点击同意ADB调试。(注意,这里也需要翻墙的,电脑要翻墙)

 4.识别到手机之后,需要在手机上设置为unlock模式才能刷机,否则刷不进去的。

5.设置完成后,点击install,就可以开始刷机了。首先是下载刷机包,然后安装。注意,此后就不要操作手机了,否则会导致刷机失败。

 6.刷机成功后,如下图所示,这时候,只要手机上点击按钮进行重启可以了。 

升级成功后,版本就升级到Android13了。

二.功能变化概览及适配方案

1.通知权限的调整

介绍:

Android13中,notifcation权限改成了运行时权限。运行时权限的意思不是说运行的时候申请,运行完就自动释放,而是说这是一个较为危险的权限,有可能涉及到用户隐私的权限。

简单来说,就是把权限级别升级了,申请方式不变,流程也不变,但是需要申请新的权限,老的已申请的通知权限在13版本上无法使用,哪怕targetSDK=32也不行。

总结下来,分为三种场景:

1.应用在系统升级到13之前已经具有通知权限,则自动授予新的通知权限POST_NOTIFICATIONS。

2.应用在13上新装,targetSDK<33,则申请该权限时只会弹一次,如果拒绝则此应用失去申请该权限的权利。

3.应用在13上新装,targetSDK>=33,每次申请该权限时都会弹。如果用户拒绝,下一次还可以继续申请。

适配方案:

首先,targetSdkVersion改为33。

其次,manifest中声明相关权限

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

最后代码中判断版本进行相关申请,如下:

private void checkAndShow() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            NotificationManager manager = getSystemService(NotificationManager.class);
            boolean b = manager.areNotificationsEnabled();
            if (!b) {
                String[] strings = {Manifest.permission.POST_NOTIFICATIONS};
                requestPermissions(strings, 0);
                return;
            }
            showNotification();
            return;
        } else {
            //继续执行老版本逻辑
        }
    }

2.读写SD卡权限的调整

介绍:

Android13之前,读取SD卡只需要申请一个权限

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

但是Android13之后,这个权限被细化成了三个,也就是说,这是三个权限需要分别单独去申请了。

适配方案:

如果是升级Android13之前就已经具有读写SDK的权限,那么升级到13之后,自己具有上述三个权限。

如果是升级Android13之后新装的应用,并且targetSDK小于33,则申请READ_EXTERNAL_STORAGE权限时,会自动转化为对上述三个权限的申请,权限申请框只一个

如果是升级Android13之后新装的应用,并且targetSDK大于等于33,则申请READ_EXTERNAL_STORAGE权限时会自动拒绝(同理WRITE_EXTERNAL_STORAGE也是一样)。必须申请上面三个权限才可以。

         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            checkPermission.add(Manifest.permission.READ_MEDIA_AUDIO);
            checkPermission.add(Manifest.permission.READ_MEDIA_IMAGES);
            checkPermission.add(Manifest.permission.READ_MEDIA_VIDEO);
        } else {
            checkPermission.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);//启动
        }

4.后台运行限制

13之前,应用的service是可以后台正常执行的。在13之后,某些情况下(比如低电量),会限制service的一些后台行为,比如限制网络的访问等等。用户进行前台互动操作后,则APP可以从受限分区移除。

主要分为三个级别,代码和描述如下:

private void handleAction() {
        UsageStatsManager systemService = getSystemService(UsageStatsManager.class);
        int appStandbyBucket = systemService.getAppStandbyBucket();
        //1.没有任何限制
        if (appStandbyBucket <= UsageStatsManager.STANDBY_BUCKET_ACTIVE) {

            return;
        }
        //2.应用最近几个小时内使用过,受到一定限制,限制程度较低。此时定时任务会被禁止执行
        if (appStandbyBucket <= UsageStatsManager.STANDBY_BUCKET_WORKING_SET) {

            return;
        }
        //3.和上面一样,只不过是几天内使用过。
        if (appStandbyBucket <= UsageStatsManager.STANDBY_BUCKET_FREQUENT) {

            return;
        }
        //4.限制访问网络
    }

三.新功能使用及使用样例

1.可降级权限

之前权限只有申请,没有降级。这次,新增了权限降级功能,开发者如果之前申请了某个权限,但是后续版本不需要了,可以主动调用API进行相关的降级处理。

        //activity or fragment 
        List<String> checkPermission = new ArrayList<>();
        checkPermission.add(Manifest.permission.READ_MEDIA_AUDIO);
        checkPermission.add(Manifest.permission.READ_MEDIA_IMAGES);
        checkPermission.add(Manifest.permission.READ_MEDIA_VIDEO);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            this.revokeSelfPermissionsOnKill(checkPermission);
        }

2.无需申请权限的相册选择器

我们通过新的API,可以直接访问相册,而无需申请任何权限,并且支持多选功能。

选择单张:

Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES);
startActivityForResult(intent, PHOTO_PICKER_REQUEST_CODE);

选择多张:

final int maxNumPhotosAndVideos = 10;
Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES);
intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxNumPhotosAndVideos);
startActivityForResult(intent, PHOTO_PICKER_MULTI_SELECT_REQUEST_CODE);

还可以通过type区分视频还是图片,这样以后就不用自己去搞

intent.setType("video/*");

其实和原来的使用方式差别不大,但是多了一个选择数量的功能,以及不需要申请权限。

3.APP单独设置语言偏好

13之前,APP的语言设置都是跟随系统的,系统如果设置的是默认应用,那么APP也会自动的切换成英语模式。13开始,支持应用单独设置优先语言,不需要跟着系统语言设定走了。

首先,创建支持语言配置文件:

然后,在AndroidManifest.xml中进行使用配置。

 

要注意的时,locales_config.xml配置中文的话,是zh,而不是zh-rCH。具体大陆/香港/台湾省语言,是没办法选择的。

4.带主题的应用图标

其实就是让桌面快捷图标支持白天黑夜模式,但是实际上这个功能有可能不是我们本来设想的那样。这个功能是让某一张单色应用图标支持白天/黑夜模式的切换,而不是支持两张不同的图片分别在白天黑夜模式下进行显示,所以实际效果并没有那么的理想。

首先,我们需要创建一张VectorDrawable类型的资源图片,battery.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
    <group
        android:name="rotationGroup"
        android:pivotX="10.0"
        android:pivotY="10.0"
        android:rotation="15.0">
        <path
            android:name="vect"
            android:fillAlpha=".3"
            android:fillColor="#FF000000"
            android:pathData="M15.67,4H14V2h-4v2H8.33C7.6,4 7,4.6 7,5.33V9h4.93L13,7v2h4V5.33C17,4.6 16.4,4 15.67,4z" />
        <path
            android:name="draw"
            android:fillColor="#FF000000"
            android:pathData="M13,12.5h2L11,20v-5.5H9L11.93,9H7v11.67C7,21.4 7.6,22 8.33,22h7.33c0.74,0 1.34,-0.6 1.34,-1.33V9h-4v3.5z" />
    </group>
</vector>

然后配置主题图标:launcher.xml

<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@drawable/icon_background" />
    <foreground android:drawable="@drawable/icon_light" />
    <monochrome android:drawable="@drawable/battery" />
</adaptive-icon>

其中monochrome就是那张主题图标,最终变化的也是这一张图片。

最后AndroidManifest.xml中进行配置:

最终效果图如下:

 白天模式/黑夜模式:

 原本图标效果:

需要注意的是,必须在设置中打开才可以使用该功能:

 3.附近WI-FI设备的新运行时权限

介绍:

扫描附近WI-FI设备时,之前需要申请的权限时ACCESS_FINE_LOCATION定位权限,这其实是不合适的。Android13修正了这个问题,新添加NEARBY_WIFI_DEVICES权限来解决这问题。

这项新权限会影响几个不同的 Wi-Fi 用例,包括以下用例:

  • 查找或连接到附近的设备,如打印机或媒体投射设备。通过该工作流,您的应用可以完成以下类型的任务:
    • 通过带外方式(例如通过 BLE)接收 AP 信息。
    • 使用仅限本地使用的热点,通过 Wi-Fi 感知和连接功能发现并连接到设备。
    • 通过 Wi-Fi 直连发现和连接到设备。
  • 发起与已知 SSID(例如汽车或智能家居设备)的连接。
  • 开启仅限本地使用的热点。
  • 连接到附近的 Wi-Fi 感知设备。

使用案例:

manifest中进行申明:

<manifest ...>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
                     android:maxSdkVersion="32" />
    <application ...>
        ...
    </application>
</manifest>

代码中进行版本判断:

         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            checkPermission.add(Manifest.permission.NEARBY_WIFI_DEVICES);
        }else{
            checkPermission.add(Manifest.permission.ACCESS_FINE_LOCATION);
        }

四.备注

有关android新版本适配-android13最全适配方案的更多相关文章

  1. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  2. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  3. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  4. ruby-on-rails - 如果我将 ruby​​ 版本 2.5.1 与 rails 版本 2.3.18 一起使用会怎样? - 2

    如果我使用ruby​​版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby​​1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更

  5. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  6. ruby-on-rails - 如何在发布新的 Ruby 或 Rails 版本时收到通知? - 2

    有人知道在发布新版本的Ruby和Rails时收到电子邮件的方法吗?他们有邮件列表,RubyonRails有一个推特,但我不想听到那些随之而来的喧嚣,我只想知道什么时候发布新版本,尤其是那些有安全修复的版本。 最佳答案 从therailsblog获取提要.http://weblog.rubyonrails.org/feed/atom.xml 关于ruby-on-rails-如何在发布新的Ruby或Rails版本时收到通知?,我们在StackOverflow上找到一个类似的问题:

  7. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  8. ruby - 安装libv8(3.11.8.13)出错,Bundler无法继续 - 2

    运行bundleinstall后出现此错误:Gem::Package::FormatError:nometadatafoundin/Users/jeanosorio/.rvm/gems/ruby-1.9.3-p286/cache/libv8-3.11.8.13-x86_64-darwin-12.gemAnerroroccurredwhileinstallinglibv8(3.11.8.13),andBundlercannotcontinue.Makesurethat`geminstalllibv8-v'3.11.8.13'`succeedsbeforebundling.我试试gemin

  9. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  10. ruby-on-rails - 安装多个版本的 Rails 会覆盖以前的安装吗? - 2

    如果我一直输入geminstallrails使用不同版本的Rails会怎样?例如,我可以输入:geminstallrails--verson3.2.10或geminstallrails这给了我版本3.2.12。问题每次安装都会覆盖之前的吗?它会删除所有旧文件并添加我正在安装的新版本吗?或者如果我运行它两次,它会保留一些文件吗?我正在使用Ubuntu。 最佳答案 它将安装两个独立的gem。实际的可执行文件rails将调用最新版本。你可以覆盖它__例如,rails_3.2.10_将执行Rails3.2.10。bundler顺便说一下,如

随机推荐