简体   繁体   English

为什么 android:requestLegacyExternalStorage=“true” 在 Android 10 - API 29 中不起作用

[英]Why android:requestLegacyExternalStorage=“true” not working in Android 10 - API 29

I have migrated my project compileSdkVersion from 28 to 29 and add android:requestLegacyExternalStorage="true" in my manifest, but file operations like downloading and file opening not working as it is in SDK 28我已将我的项目 compileSdkVersion 从 28 迁移到 29,并在我的清单中添加 android:requestLegacyExternalStorage="true" ,但下载和文件打开等文件操作无法像在 SDK 28 中那样工作

gradle file gradle 文件

compileSdkVersion 29

defaultConfig {
    applicationId "in.example.app"
    minSdkVersion 21
    targetSdkVersion 29
    versionCode 90
    versionName "1.8.3"

    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

Manifest file清单文件

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="in.example.app">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.SMS_FINANCIAL_TRANSACTIONS" />

<application
    android:name=".MyApp"
    android:allowBackup="true"
    android:hardwareAccelerated="true"
    android:icon="@mipmap/ic_launcher"
    android:largeHeap="true"
    android:networkSecurityConfig="@xml/network_security_config"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    tools:replace="android:theme,android:allowBackup"
    tools:targetApi="n"
    android:requestLegacyExternalStorage="true">

    <activity android:name=".ui.main.MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>

    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="in.example.app.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
    </provider>

</application>

file downloading code文件下载代码

fun startDownloading(path: String, url: String): Long {
    return try {
        val downFileName = re.replace(url.substringAfterLast("/"), "")

        val downloadManager = context.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
        val request = DownloadManager.Request(Uri.parse(url))
            request.setTitle(downFileName)
                .setDestinationInExternalPublicDir(path, downFileName)
                .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
        downloadManager.enqueue(request)
    } catch (e: Exception){
        0
    }
}
  • path should be a folder location in internal storage "/myapp/study materials/"路径应该是内部存储“/myapp/study materials/”中的文件夹位置
  • url should be a file location url from the server url 应该是来自服务器的文件位置 url

opening a file打开文件

fun openFile(title: String, path: String){
    try {
        val newFile = File(Environment.getExternalStorageDirectory().absolutePath + path, title)

        val uri = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M)
        {
            FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileprovider", newFile)
        } else{
            Uri.fromFile(newFile)
        }

        val intent = Intent(Intent.ACTION_VIEW, uri)
        intent.setDataAndType(uri, context.contentResolver.getType(uri))
        intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        val activities: List<ResolveInfo> = context.packageManager.queryIntentActivities(intent, 0)
        val isIntentSafe: Boolean = activities.isNotEmpty()

        // Start an activity if it's safe
        if (isIntentSafe) {
            context.startActivity(Intent.createChooser(intent, "Open With"))
        } else{
            MDToast.makeText(context, "No Application Found For Opening This File", MDToast.TYPE_INFO).show()
        }
    } catch (e : Exception){
        println("=============== ${e.message}")
    }

}
  • path should be a folder location in internal storage "/myapp/study materials/"路径应该是内部存储“/myapp/study materials/”中的文件夹位置
  • title should be the file name标题应该是文件名

file existance checking文件存在性检查

override fun checkFileExistence(title: String, path: String): Boolean {
    var flag = false
    try {
        val direct = File(
            Environment.getExternalStorageDirectory().toString()
                    + path + title)
        flag = direct.exists()
    } catch (e: Exception) {
    }

    return flag
}
  • path should be a folder location in internal storage "/myapp/study materials/"路径应该是内部存储“/myapp/study materials/”中的文件夹位置
  • title should be the file name标题应该是文件名

I have added all code that is not working while updating to SDK 29, I want to download a file from the server and save it to an app-specific folder in internal storage also need to check if the file is already downloaded or not before downloading it.我添加了所有在更新到 SDK 29 时不起作用的代码,我想从服务器下载文件并将其保存到内部存储中的应用程序特定文件夹中还需要在下载之前检查文件是否已经下载它。 if it is already downloaded I need to open that file如果已经下载,我需要打开该文件

I had similar issues to those mentioned here.我有与这里提到的类似的问题。 I found out that on Android 10, I have to check WRITE_EXTERNAL_STORAGE even when file is already downloaded and I just need to open it.我发现在 Android 10 上,即使文件已经下载并且我只需要打开它,我也必须检查WRITE_EXTERNAL_STORAGE

if (ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, arrayOf(WRITE_EXTERNAL_STORAGE), 100)
}

Adding the check before any manipulation with the file fixed the "There was a problem parsing the package" error when opening the APK file.在对文件进行任何操作之前添加检查修复了打开 APK 文件时出现的“解析包时出现问题”错误。

EDIT:编辑:

I also found another (probably better) solution.我还找到了另一个(可能更好)的解决方案。 Instead of using external public storage , I switched to external storage of the app:我没有使用外部公共存储,而是切换到应用程序的外部存储

downloadRequest.setDestinationInExternalFilesDir(...)

and to access the file use并访问文件使用

new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), mFileName);

instead of now deprecated Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)而不是现在弃用Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)

As a bonus there's no need to use android:requestLegacyExternalStorage="true" in AndroidManifest.作为奖励,无需在 AndroidManifest 中使用android:requestLegacyExternalStorage="true"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 AndroidManifest 中使用 requestLegacyExternalStorage = true 删除 Android API 29 和 30 上的文件时出现 RecoverableSecurityException - Getting RecoverableSecurityException while deleting file on Android API 29 and 30 with requestLegacyExternalStorage = true in AndroidManifest requestLegacyExternalStorage 在 Android 11 - API 30 中不起作用 - requestLegacyExternalStorage is not working in Android 11 - API 30 为什么文件访问方法 getExternalStorageDirectory() 在 Android 10 (API 29) 上不起作用 - why file accessing method getExternalStorageDirectory() is not working on Android 10 (API 29) Webrtc Android:屏幕共享在 API 29 (Android 10) 上停止工作 - Webrtc Android: Screen Sharing stopped working on API 29 (Android 10) 迁移到 Android Api 级别 29 时,出现此错误,找不到 requestLegacyExternalStorage,处理清单失败 - While migrating to Android Api level 29, I am getting this error, requestLegacyExternalStorage not found, failed processing manifest Android 10 (API 29) 升级后 setColor 不起作用 - setColor not working after Android 10 (API 29) upgrade boot_completed 不工作 Android 10 Q API 级别 29 - boot_completed not working on Android 10 Q API level 29 Android 10 API 29 上的 CallScreeningService getExtras NULL - CallScreeningService getExtras NULL on Android 10 API 29 使用 Android 10 (API 29) 在模拟器上查询 ContentProvider - Query ContentProvider on Emulator with Android 10 (API 29) Android 10(api-29)文件写入 - Android 10 (api-29) file writing
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM