Updating to the new version of the Android API as instructed by Google

Android 12 is coming soon, but this August, starting from version 11, developers will have to use new standards for accessing applications to external files. If earlier you could just put a flag that your application does not support innovations, then soon they will become mandatory for everyone. The main focus is on improving safety.





API — , . . 





, — .





Android Internal Storage (IS) External Storage (ES). SD-, ES , . — IS, ES , , . ES , , , .





IS, . . ES , , (, ).





. IS, ES — , .





Android 10- , 11- .





Google Scoped Storage (SS) ES. , — . IS 10- .





Android 11 Google SS — - SDK 30- API, SS, , . Android , . , 11, , , . , Android 11, . 





SS ( 10- ), . Media Content, Storage Access Framework , 11- Android, Datasets . , . , . — . , , . , , .





Media Content, SAF Datasets Shared Storage (ShS). . , .





SS — FileProvider . , .





— , . best practice ( , ), - , . , . 





. , , , , .





— , , . — , .





.





iFunny . , .





, API. 





interface FilesManipulator {
    fun createVideoFile(fileName: String, copy: Copier): Uri
    fun createImageFile(fileName: String, copy: Copier): Uri
    fun createFile(fileName: String, copy: Copier): Uri
    fun getPath(uri: Uri): String
    fun deleteFile(uri: Uri)
}
      
      



FilesManipulator , , API . Copier — , , . , , , . 10- Android FilesManipulator File API, 10- ( ) — MediaStore API.





.





fun getContentValuesForImageCreating(fileName: String): ContentValues {
    return ContentValues().apply {
        put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
        put(MediaStore.Images.Media.IS_PENDING, FILE_WRITING_IN_PENDING)
        put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + File.separator + appFolderName)
    }
}

fun createImageFile(fileName: String, copy: Copier): Uri {
    val contentUri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
    val contentValues = getContentValuesForImageCreating(fileName)
    val uri = contentResolver.insert(contentUri, contentValues)
              ?: throw IllegalStateException("New image file insert error")
    downloadContent(uri, copy)
    return uri

}

fun downloadContent(uri: Uri, copy: Copier) {
    try {
        contentResolver.openFileDescriptor(uri, FILE_WRITE_MODE)
                .use { pfd ->
                    if (pfd == null) {
                        throw IllegalStateException("Got nullable file descriptor")
                    }
                    copy.copyTo(FileOutputStream(pfd.fileDescriptor))
                }
        contentResolver.update(uri, getWriteDoneContentValues(), null, null)
    } catch (e: Throwable) {
        deleteFile(uri)
        throw e
    }
}

fun getWriteDoneContentValues(): ContentValues {
    return ContentValues().apply {
        put(MediaStore.Images.Media.IS_PENDING, FILE_WRITING_DONE)
    }
}
      
      



, MediaStore.Images.Media.IS_PENDING



, 0 , . 





, . URI . SDK, File API . External Storage FileProvider API.





, 30- API, . iFunny , . , query, , SDK.





, , . , .





<manifest … >
<queries>
<intent>
    <action android:name="android.intent.action.SENDTO" />
    <data android:scheme="smsto, mailto" />
</intent>
…
    <package android:name="com.twitter.android" />
    <package android:name="com.snapchat.android" />
    <package android:name="com.whatsapp" />
    <package android:name="com.facebook.katana" />
    <package android:name="com.instagram.android" />
    <package android:name="com.facebook.orca" />
    <package android:name="com.discord" />
    <package android:name="com.linkedin.android" />
</queries>
</manifest>
      
      



UI- API 29-30 , .





LogCat , Orchestrator java.lang.RuntimeException: Cannot connect to androidx.test.orchestrator.OrchestratorService.







, <package android:name="androidx.test.orchestrator" />



.





, — Allure , .





- Scoped Storage , , . , , , .





, . ShellCommandExecutor, adb shell appops set --uid PACKAGE_NAME MANAGE_EXTERNAL_STORAGE allow



.





Android 11 . 





10- Android , Allure . issue Allure, , , 11- . adb shell appops set --uid PACKAGE_NAME LEGACY_STORAGE allow



. , . 





— . , WRITE_EXTERNAL_STORAGE



28 API, . (, debug) Allure . 





debug-.





<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="29"
    tools:node="replace" />
      
      



, targetSdkVersion 30, Google Play , .








All Articles