List of Android 13 runtime permission changes

This article is simultaneously published on my WeChat official account. You can follow by scanning the QR code at the bottom of the article or searching for Guo Lin on WeChat. Articles are updated every working day.

It won't be long before the official version of Android 13 will be released.

In fact, just a few months ago, I wrote a comprehensive introduction to the first developer experience version of Android 13. For details, please refer to the list of Android 13 Developer Preview .

So compared to the first developer experience version, Android 13 has entered the stage of platform stability, which means that the API has basically been fixed, and there will be no major changes.

So I reviewed the important new features and behavior changes of Android 13 again, and found that there is a major change that was hardly mentioned in the first developer experience version, that is, the runtime permission change of Android 13.

Therefore, today I will write another overview of Android 13's runtime permission changes, giving you a comprehensive understanding of all Android 13 runtime permission changes.


Granular Media Rights

Google has further refined local data access permissions on Android 13.

It can only be said that Google has spared no effort to protect user privacy, and today's move has actually been planned for a long time in advance.

You should know that as early as in the Android 10 system, Google disabled the form of direct access to local files through absolute paths, but to access them through the MediaStore API. We call this feature Scoped Storage.

Regarding Scoped Storage, I wrote an article two years ago to introduce it. For details, please refer to Android 10 Adaptation Key Points, Scoped Storage .

In this article, there is such a description:

The Android 10 system classifies file types. Three types of files, pictures, audio, and video, can be accessed through the MediaStore API, while other types of files need to be accessed using the system's file selector.

In addition, the pictures, audio or video contributed by our application to the media library will automatically have its read and write permissions, and there is no need to apply for READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions. And if you want to read pictures, audio or video contributed by other applications to the media library, you must apply for the READ_EXTERNAL_STORAGE permission. The WRITE_EXTERNAL_STORAGE permission will be deprecated in a future Android release.

This part of the description looks basically correct before Android 13. Although the WRITE_EXTERNAL_STORAGE permission has not been abandoned, it is almost impossible for us to use it in various scenarios.

However, in Android 13, in order to allow users to manage media permissions more finely, Google first started with the READ_EXTERNAL_STORAGE permission.

Starting from Android 13, if your application targetSdk is specified to 33 or above, then the READ_EXTERNAL_STORAGE permission is completely useless, and applying for it will have no effect.

Correspondingly, Google has added three runtime permissions, READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, and READ_MEDIA_AUDIO, which are used to manage photos, videos, and audio files of the mobile phone.

In other words, in the past, you only need to apply for a READ_EXTERNAL_STORAGE permission. It is no longer possible, you have to apply on demand, so that users can understand more precisely which media permissions your app has applied for.

As for the code for applying for runtime permissions, it is the same template, and there is nothing special about it. Here is a version for you to apply for using the Activity Result API. Since I haven't adapted PermissionX to Android 13, I can't demonstrate it to you for the time being. I will write another article after the adaptation is completed.

class MainActivity : AppCompatActivity() {
    
    

    private val requestPermissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestPermission()) {
    
     granted ->
        if (granted) {
    
    
            // User allow the permission.
        } else {
    
    
            // User deny the permission.
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val requestBtn = findViewById<Button>(R.id.request_btn)
        requestBtn.setOnClickListener {
    
    
            if (Build.VERSION.SDK_INT >= 33) {
    
    
                requestPermissionLauncher.launch(Manifest.permission.READ_MEDIA_IMAGES)
            }
        }
    }
}

As you can see, the ActivityResult API is used to apply for the READ_MEDIA_IMAGES permission. If you haven't learned about the Activity Result API, you can refer to this article Activity Result API Detailed Explanation, it's time to give up startActivityForResult .

The running effect is shown in the figure below:

insert image description here

The strange thing is that here I only applied for the permission to read photos in the code, but the screenshot shows that we are applying for permission to read photos and videos. And I verified locally that these two permissions will indeed be granted together. Audio permissions will not be granted together with them and need to be applied for separately.

My guess is that both permissions belong to the same permission group, so as soon as one is granted, the other is automatically granted. But I didn't find any explanation for this in the official documentation, so please don't do any business logic based on this behavior when writing code, because the permission group Google may adjust at any time, we should still follow our own business needs , apply for permission on demand.

In addition, in order to consider backward compatibility, we should write this when declaring permissions in AndroidManifest.xml:

<manifest ...>
    <!-- Required only if your app targets Android 13. -->
    <!-- Declare one or more the following permissions only if your app needs
    to access data that's protected by them. -->
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />

    <!-- Required to maintain app compatibility. -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
                     android:maxSdkVersion="32" />
    <application ...>
        ...
    </application>
</manifest>

It can be seen that API 32 is Android 12 and below, and we still declare the READ_EXTERNAL_STORAGE permission. Starting from Android 13, we will use READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_AUDIO instead.

The same logical processing should be done when applying for permissions in the code, so I won’t post it here.


Notification runtime permissions

Notification runtime permissions can be said to be one of the blockbuster features of Android 13. After all these years, Google has finally incorporated notifications into runtime permission management.

In fact, I am relatively indifferent to notifications, mainly because Google likes to make fuss about notifications too much. Almost every year at the I/O conference, there must be a theme dedicated to new features of notifications. After a long time, I have basically been immune to changes in notifications, and I really can’t learn them anymore.

However, this year's changes have to be learned, because if you don't learn, your notice will not be sent out.

The notification bar is really a thing that people love and hate. I believe that this sentence does not need to be explained. People who use Android phones should understand it.

In the previous Android system, any application that wants to send a notification does not need the user's consent, and can send it if it wants to. This makes the notification bar of our mobile phone often occupied by some junk notifications, and the really important notifications may be difficult to find.

insert image description here

In order to solve this problem, Google has made many changes and adjustments. For example, the notification channel added in Android 8.0 is to help users better filter useful notifications and junk notifications. For details, please refer to this article Android notification bar tips, notification bar adaptation in 8.0 system .

However, the addition of notification channels only makes it easier for users to filter out useless notifications and spam notifications that are not of interest and block them. Essentially every app is still free to send notifications without the user's consent at all.

This time, Android 13 incorporates notifications into runtime permission management, that is to say, if you want to send notifications in the future, you must first obtain the user's consent and authorization.

Let me talk about how to apply for permission to send notifications on Android 13. In fact, it is no different from general runtime permissions. First declare the permission to send notifications in AndroidManifest.xml:

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

Then we use the Activity Result API again to request permission:

class MainActivity : AppCompatActivity() {
    
    

    private val requestPermissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestPermission()) {
    
     granted ->
        if (granted) {
    
    
            // User allow the permission.
        } else {
    
    
            // User deny the permission.
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val requestBtn = findViewById<Button>(R.id.request_btn)
        requestBtn.setOnClickListener {
    
    
            if (Build.VERSION.SDK_INT >= 33) {
    
    
                requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
            }
        }
    }
}

The running effect is shown in the figure below:

insert image description here

In terms of usage, there is no difference between applying for permission to send notifications and other runtime permissions, but there are still many details that deserve our attention.

One of the points that must be noted, the POST_NOTIFICATIONS permission is only useful when the targetSdk of the application is specified as 33 or higher.

When the targetSdk is 32 or below, the system will think that you have not done the adaptation work for Android 13, and applying for the POST_NOTIFICATIONS permission at this time will not have any effect. Correspondingly, it will pop up a dialog box as shown above when you first create a notification channel.

And if the user chooses Don't allow at this time, there will be no chance to see this dialog box again, that is, the user has permanently rejected our permission to send notifications. until the following two situations occur:

  • The user uninstalled and reinstalled our app.
  • We upgraded targetSdk to 33 or higher.

In addition, when the user's mobile phone is upgraded from Android 12 to Android 13, the ability to send notifications for installed applications will not change.

In other words, if the user blocks the notifications of our app on Android 12, when the device is upgraded to Android 13, our app will not have the permission to send notifications.

But as long as the user does not explicitly block the notifications of our app on Android 12, after the device is upgraded to Android 13, our app will automatically be granted permission to send notifications.

Finally, if you want to judge whether a runtime permission is authorized, you can usually write like this:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
    == PackageManager.PERMISSION_GRANTED) {
    
    
    // Permission granted
} else {
    
    
    // Permission not granted
}

But this way of writing has an obvious disadvantage in judging the permission to send notifications, because it can only be used on Android 13, and systems below Android 13 do not have the POST_NOTIFICATIONS permission.

So if it is just to judge whether our application has the ability to send notifications for users to see, we can use the following writing method, which will ensure that it can work normally on all system versions:

val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
if (notificationManager.areNotificationsEnabled()) {
    
    
    // Permission granted
} else {
    
    
    // Permission not granted
}

So what should we do if we detect that sending notifications is not authorized and the user has permanently denied this permission?

I plan to save this topic until PermissionX upgrades to support Android 13, and I will write another article to introduce it.


Other new permissions

The new permissions that most need our attention on Android 13 are the above, but they are not all.

There are also some relatively small new permissions that you may rarely use, so let’s briefly summarize them here.

Last year, Google added several Bluetooth-related runtime permissions to Android 12. The reason is that when developers access some Bluetooth-related interfaces, they need to apply for geographic location permissions, which makes some privacy-sensitive users very disgusted.

This is a problem left over from history. In order to better protect user privacy, Google added BLUETOOTH_SCAN, BLUETOOTH_ADVERTISE, BLUETOOTH_CONNECT, these three runtime permissions to Android 12. In this way, when developers need to access Bluetooth-related interfaces, they only need to request these Bluetooth permissions.

In this year's Android 13, Google extended the protection of user privacy to the WIFI field.

Similar to Bluetooth, when developers access some WIFI-related interfaces, such as hotspots, WIFI direct connection, WIFI RTT, etc., they also need to apply for geographic location permissions.

This is actually a problem left over from history. Users must not understand why they need to authorize geographic location permissions when using some WIFI functions.

For this reason, a new NEARBY_WIFI_DEVICES permission has been added in Android 13. When using the WIFI API related to the above scenarios, we only need to apply for the NEARBY_WIFI_DEVICES permission, which better protects the user's privacy.

Another change is motion sensor permissions.

Before, if we wanted to read the data of the mobile phone's motion sensor, we needed to apply for the BODY_SENSORS permission. In Android 13, Google added a restriction to the BODY_SENSORS permission that can only be used in the foreground.

insert image description here

It can be seen that when applying for the BODY_SENSORS permission on Android 13, the user can only be authorized to use it in the foreground.

So what if our application is to get motion sensor data in the background? Don't worry, Android 13 has added a BODY_SENSORS_BACKGROUND permission, just apply for this permission.

It should be noted that before applying for BODY_SENSORS_BACKGROUND permission, you must first obtain BODY_SENSORS authorization, otherwise the application will be invalid. This setting is a bit like the setting that Android 10 added in the background to obtain geographic location permissions.

Well, the above is a list of Android 13 runtime permission changes, I hope it will be helpful to everyone.


If you want to learn Kotlin and the latest Android knowledge, you can refer to my new book "The First Line of Code 3rd Edition" , click here to view details .


Pay attention to my technical public account, and high-quality technical articles will be pushed every day.

Scan the QR code below on WeChat to follow:

Guess you like

Origin blog.csdn.net/sinyu890807/article/details/126334526