Android Q

Android Q

前言

感觉还没怎么见过Android 9.0,10 都已经出来了,虽然只是测试版,但是提前了解下也是很有必要的,尤其对于我们开发者而言。新版本出来意味着适配工作又要搞起了,之前的华为开发者平台已经要求上架的应用目标版本适配到Q
https://developer.huawei.com/consumer/cn/notice/20190328
下面主要介绍下Q的适配。
官网:https://developer.android.google.cn/

正文

首先是下载Q所需要的工具及模拟器,我用AS看了一下,需要4.5G,算了,你们搞吧。本文完。
需要注意的是,如果要编译Q,需要在应用的bulid.gradle中声明:

  • compileSdkVersion “android-Q”
  • buildToolsVersion “29.0.0 rc1”
  • targetSdkVersion “Q”

官方提到的重大隐私变更包括一下几点:

  1. SCOPED STORAGE
    简单的说Q又修改了存储文件权限,现在Q上的每个应用都有自己一个独立的沙盒(存储区域),这个区域只有自己的应用可以访问,这个沙盒里面的文件随着应用被卸载而删除.

我们可以直接访问而 不 再 需 要 申 请 \color{red}{不再需要申请} READ_EXTERNAL_STRAGE和WRITE权限。

官方推荐我们在外部存储文件的位置是Context.getExternalFilesDir(String type),type可以传Environment.DIRECTORY_IMAGES等类型,如果应用中没有这个文件夹,会自动创建,路径为/storage/emulated/0/Android/data/包名/files/Music,我们可以根据传入不同的type类型保存不同类型的文件。

如果我们希望应用卸载的时候也保存这些文件,那么最好保存到公共文件夹下,如公共的照片,音乐,下载等。

如果我们希望访问公共文件夹照片,视频,音乐中其他应用的文件,需要READ_MEDIA_IMAGES ,READ_MEDIA_VIDEO,READ_MEDIA_AUDIO 权限,具体根据文件类型定。

如果希望访问公共文件夹下载中其他应用的文件,则必须通过系统的文件选择器来选择。通过ContentResolver.openFileDescriptor()之类的API来读取数据。

  1. DEVICE LOCATION
    Q限制了应用处于后台时获取位置信息的能力,这项行为在Q上是默认开启的。
    我们现在如果在Q上请求获取位置信息,会弹出选项:
    在使用中(仅限前台)
    始终(前台和后台)
    Android Q_第1张图片

Q中新增了ACCESS_BACKGROUND_LOCATION权限,这个权限只是用来在后台运行时访问,除非应用的某个 Activity 可见或应用正在运行前台服务,否则应用将被视为在后台运行。

	
      
	
	
	
	
      
    

因此,要获取后台位置信息需要以下操作:
开启前台服务。类型为 l o c a t i o n \color{red}{location} location

	 
        ...
    

我们在获取位置信息之前需要判断是否已经开启了权限:

val permissionAccessCoarseLocationApproved = ActivityCompat
        .checkSelfPermission(this, permission.ACCESS_COARSE_LOCATION) ==
        PackageManager.PERMISSION_GRANTED

    if (permissionAccessCoarseLocationApproved) {
       val backgroundLocationPermissionApproved = ActivityCompat
           .checkSelfPermission(this, permission.ACCESS_BACKGROUND_LOCATION) ==
           PackageManager.PERMISSION_GRANTED

       if (backgroundLocationPermissionApproved) {
       //前后台都可以获取位置信息,因此不需要开启前台服务
           // App can access location both in the foreground and in the background.
           // Start your service that doesn't have a foreground service type
           // defined.
       } else {
       //只能获取前台位置,展示对话框告诉用户必须始终获取位置信息才能正常工作,然后请求后台位置信息
           // App can only access location in the foreground. Display a dialog
           // warning the user that your app must have all-the-time access to
           // location in order to function properly. Then, request background
           // location.
           ActivityCompat.requestPermissions(this,
               arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION),
               your-permission-request-code
           )
       }
    } else {
    //没有任何位置信息权限,申请一下
       // App doesn't have access to the user's location at all. Make full request
       // for permission.
       ActivityCompat.requestPermissions(this,
           arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION,
                   Manifest.permission.ACCESS_BACKGROUND_LOCATION),
           your-permission-request-code
       )
    }
    
  1. BACKGROUND APP STARTS
    Q针对从后台启动Activity做了限制,如果在没有和用户互动情况下启动Activity,则很可能会影响您的应用,比如一般App都用2s的启动页,如果在2s内切换到后台,此时就可认为是后台启动Activity,目前仅仅会toast提示,这项行为变更是只要安装在Q设备上都会生效。
This background activity start from package-name will be blocked in future Q builds.

目前限制为只有满足以下一个或多个条件才可以启动Activity:
a.该应用具有可见窗口,例如在前台运行的 Activity。
b.在前台运行的另一个应用会发送属于该应用的 PendingIntent。
c.系统发送属于该应用的 PendingIntent
d.系统向应用发送广播
因此,为了避免这种情况发生,官方推荐我们通过创建通知提示用户,而不是直接打开Activity,当然,某些功能可能确实需要,比如来电,解决办法如下:

-> 创建高优先级通知,使用全屏PendingIntent.如果使用全屏Intent,则 需 要 申 请 U S E F U L L S C R E E N I N T E N T 权 限 \color{red}{需要申请USE_FULL_SCREEN_INTENT权限} USEFULLSCREENINTENT
->通过 开 启 前 台 服 务 \color{red}{开启前台服务} 与通知相关联
该功能默认是关闭的,如果要开启,需要到设置里面修改。

val fullScreenIntent = Intent(this, CallActivity::class.java)
    val fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
        fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT)

    val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("Incoming call")
        .setContentText("(919) 555-1234")
        .setPriority(NotificationCompat.PRIORITY_HIGH)
        .setCategory(NotificationCompat.CATEGORY_CALL)

        // Use a full-screen intent only for the highest-priority alerts where you
        // have an associated activity that you would like to launch after the user
        // interacts with the notification. Also, if your app targets Android Q, you
        // need to request the USE_FULL_SCREEN_INTENT permission in order for the
        // platform to invoke this notification.
        .setFullScreenIntent(fullScreenPendingIntent, true)

    val incomingCallNotification = notificationBuilder.build()

注意:应用无法通过前台服务让应用处于前台豁免该管控
4. HARDWARE IDENTIFIES
这项变更主要是对系统标识增加的几项限制,有助于保护用户的隐私。
只要运行在Q上的应用:
获取随机的MAC地址,通过调用getRandomizedMacAddress()获取特定网络的随机MAC地址。
获取系统的MAC地址,通过调用getWifiMacAddress()检索实际硬件的MAC地址。
如果需要访问设备网络状态,使用NetworkStatsManager 和 ConnectivityManager 类。
获取IMEI和设备序列号:Q需要READ_PRIVILEGED_PHONE_STATE权限,低版本需要READ_PHONE_STATE,否则发生异常。
5. LOCATION AND NETWORK
这就用的不多了,但是依然是在Q 上运行的所有应用会产生影响。如:
Q 上运行的应用无法启用或停用 WLAN,需要到设置面板。
以Q为目标平台影响:
应用无法使用 WLAN API、WLAN Aware API 或 Bluetooth API 中的多种方法,除非应用具有 ACCESS_FINE_LOCATION 权限。

折叠屏

除此之外,Q一个极为重要的变更就是支持可折叠屏,怕了怕了,这个适配对我们开发者而言感觉是相当困难啊。为了更好的适配可折叠屏,官网建议:

  1. 为了保证屏幕的展开和收缩时应用的连续性,我们应该及时的保存当前的状态和位置。
  2. 如果应用屏幕可支持大小调整,需要增加Activity属性resizeableActivity=true,这个好像在8.0就有了,如果设置false,则代表应用不支持屏幕大小调整,但是展开的情况下系统会调整到展开的合适位置。
  3. 这是目前Q的屏幕比例,如果不支持某些比率,可以通过 maxAspectRatio和minAspectRatio来指示应用可以处理的最高和最低比率,屏幕超出这些限制,则可能会处于兼容模式。Android Q_第2张图片
  4. 在Q中,新增了 onTopResumedActivityChanged() 方法,可以监听当前Activity获取或者是失去topmost resumed position(最顶部显示的位置),我们可以在这个方法里对一些公用的资源进行处理。
protected void onTopResumedActivityChanged(boolean topResumed) {
    if (topResumed) {
        // Top resumed activity
        // Can be a signal to re-acquire exclusive resources
    } else {
        // No longer the top resumed activity
    }
}

你可能感兴趣的:(Android笔记)