标签: android-external-storage

Android的READ_EXTERNAL_STORAGE权限

我正在尝试访问用户设备上的媒体文件(音乐)来播放它们; 一个简单的"你好世界" - 音乐播放器应用程序.

我已经按照一些教程,他们基本上给出了相同的代码.但它不起作用; 它一直在崩溃并告诉我:

error.....
Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/audio/media from pid=27696, uid=10059 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
....
Run Code Online (Sandbox Code Playgroud)

现在,这是我的清单文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="slimsimapps.troff" >

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


<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>
</manifest>
Run Code Online (Sandbox Code Playgroud)

这是我的Java方法:

public void initialize() {
    ContentResolver contentResolver = getContentResolver();
    Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    Cursor cursor = contentResolver.query(uri, null, null, null, null); …
Run Code Online (Sandbox Code Playgroud)

java android audio-player android-music-player android-external-storage

73
推荐指数
5
解决办法
12万
查看次数

在Android上写入外部SD卡的通用方式

在我的应用程序中,我需要在设备存储中存储大量图像.这些文件往往满足设备存储,我想让用户能够选择外部SD卡作为目标文件夹.

我到处读到Android不允许用户写入外部SD卡,SD卡是指外部和可安装的SD卡而不是外部存储器,但文件管理器应用程序设法在所有Android版本上写入外部SD.

在不同的API级别(Pre-KitKat,KitKat,Lollipop +)上授予对外部SD卡的读/写访问权限的更好方法是什么?

更新1

我从Doomknight的答案中尝试了方法1,但没有结果:正如您所看到的那样,我在尝试在SD上写入之前在运行时检查权限:

HashSet<String> extDirs = getStorageDirectories();
for(String dir: extDirs) {
    Log.e("SD",dir);
    File f = new File(new File(dir),"TEST.TXT");
    try {
        if(ActivityCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)==PackageManager.PERMISSION_GRANTED) {
            f.createNewFile();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我在两个不同的设备上尝试了访问错误:HTC10和Shield K1.

10-22 14:52:57.329 30280-30280/? E/SD: /mnt/media_rw/F38E-14F8
10-22 14:52:57.329 30280-30280/? W/System.err: java.io.IOException: open failed: EACCES (Permission denied)
10-22 14:52:57.329 30280-30280/? W/System.err:     at java.io.File.createNewFile(File.java:939)
10-22 14:52:57.329 30280-30280/? W/System.err:     at com.myapp.activities.TestActivity.onResume(TestActivity.java:167)
10-22 14:52:57.329 30280-30280/? W/System.err:     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1326)
10-22 14:52:57.330 30280-30280/? W/System.err:     at android.app.Activity.performResume(Activity.java:6338)
10-22 14:52:57.330 …
Run Code Online (Sandbox Code Playgroud)

java android android-sdcard android-external-storage

71
推荐指数
2
解决办法
4万
查看次数

Android 6上的存储访问如何变化?

背景

Android在如何处理SD卡和存储方面有很多变化:

  • API 3 - 您获得所有访问权限,无需权限
  • API 4-15 - 您需要使用WRITE_EXTERNAL_STORAGE,并获得所有访问权限.
  • API 16-18 - 如果您只想阅读,请使用READ_EXTERNAL_STORAGE
  • API 19-20 - 您无法读取或写入辅助外部存储(SD卡),除非您的应用程序是系统应用程序,或者您拥有root用户.
  • API 21-22 - 为了访问SD卡,您需要请求用户许可,并使用DocumentFile API而不是File API.正如我在这里,这里这里所写的那样,这引发了许多问题.

从API 23(Android 6)开始,事情似乎再次发生变化......

问题

对于API 23,至少有两件新东西与存储相关:

  • " 可采用的存储设备 " - 用户可以选择将SD卡作为主要外部存储器.
  • 作为新权限机制(在运行时请求权限)的一部分,存储似乎也是用户需要确认的权限.这适用于READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE

由于没有配备SD卡的Android 6设备,并且因为模拟器本身并不能真正使用SD卡,所以仍然无法知道发生了什么.

问题

  1. SD卡是否可以使用File-API而不是DocumentFile获取访问权限?

  2. 如果我想访问所有外部存储路径(包括SD卡),这是否意味着我需要两次请求此权限:一个用于主外部存储,一个用于SD卡?

  3. 在手动授予许可之前,SD卡上的文件是否可以以任何方式访问?

  4. 假设用户选择使用"Adoptable Storage Devices",这对于检索应用程序文件路径的各种函数意味着什么?例如:getFilesDir,getExternalFilesDir,...?getExternalFilesDirs的oder会因为它而改变吗?

  5. 当用户将应用程序从SD卡移动到SD卡时(使用"可采用的存储设备"),应用程序的文件会发生什么变化?SD卡上的应用程序文件怎么样?他们会留下来吗?或者他们会搬到某个地方?

    例如,如果应用程序在SD卡上有"file1.txt",则在路径"/ storage/extSdCard/Android/data/appPackageName"上,它有一个文件"file2.txt"(或者甚至是同一个名字)在路径"/ storage/emulated/0/Android/data/appPackageName"上的主外部存储上.切换后,这些文件会发生什么?如果有的话,他们将如何合并到一个文件夹中?

  6. 将应用程序移动到SD卡(使用"Adoptable Storage Devices")时,是否意味着不会使用内部存储?

android sd-card android-permissions android-external-storage android-6.0-marshmallow

47
推荐指数
1
解决办法
3万
查看次数

用于存储文件的Android Open External Storage目录(sdcard)

我想打开外部存储目录路径以编程方式保存文件.我试过但没有获得SD卡路径.我怎么能这样做?有什么解决方案吗?

private File path = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "");
Run Code Online (Sandbox Code Playgroud)

要么

private File path = new File(Environment.getExternalStorageDirectory() + "");
Run Code Online (Sandbox Code Playgroud)

我尝试从两个方法上面获取路径,但两者都指向内部存储器.

当我们打开存储器时,如果sdcard没有,它将显示如下 - 在此输入图像描述

设备存储和SD存储卡.

我想通过编码获得sd内存路径.我已经在清单中给予了许可 -

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Run Code Online (Sandbox Code Playgroud)

android sd-card android-sdcard android-external-storage

36
推荐指数
3
解决办法
23万
查看次数

Android:外部存储上的mkdirs()/ mkdir()返回false

我为此感到疯狂:

Log.d("STATE", Environment.getExternalStorageState());
File f = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "work_data");
Log.d("PATH", f.getAbsolutePath());
if (!f.exists()) {
    Log.d("MAKE DIR", f.mkdirs() + "");
}
Run Code Online (Sandbox Code Playgroud)

输出日志如下所示:

STATE     mounted
PATH      /mnt/sdcard/DCIM/work_data
MAKE DIR  false
Run Code Online (Sandbox Code Playgroud)

我确保添加正确的权限:

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
Run Code Online (Sandbox Code Playgroud)

但我不知道为什么它无法创建该文件夹.我也mkdir()一步一步地使用,但结果是一样的.请帮我.我用Google搜索了这么多,并且在这个愚蠢的事情上花了至少两天时间.谢谢你的帮助!!

编辑:

大家好!我添加<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><application>标签.这是我的错!但是谢谢大家的回复.

android android-file android-external-storage

32
推荐指数
7
解决办法
3万
查看次数

应用程序如何在没有root的情况下访问Android 6.0(API级别23)中的USB OTG存储上的文件?

Android 6.0开发人员预览版(API级别23)可以本机安装外置的可移动USB OTG存储,无需任何其他应用程序(有关详细信息,请参阅:https://www.androidpolice.com/2015/05/28/android-m-feature-spotlight-external-storage-can-be-as-true-internal-storage-or-access-normal-with-no-additional-apps /).

当用户连接USB OTG存储时,它会显示在系统存储菜单中,并可通过内置文件管理器访问.用户可以使用没有root权限的新内置文件管理器访问USB OTG外部存储器上的所有文件.

当我将USB OTG存储连接到我的Android设备时,它会安装/storage/A03E-1DF5/mnt/media_rw/A03E-1DF5,但也会安装,但访问此文件夹需要root权限.

我正在研究Android媒体播放器应用.

是否有可能以及如何在我的应用程序中访问Android 6.0上的USB OTG存储上的文件,如没有root权限的内置文件管理器?

PS我已经使用checkSelfPermission,并requestPermissions在我的应用程序的功能和我的应用程序已经有android.permission.READ_EXTERNAL_STORAGEandroid.permission.WRITE_EXTERNAL_STORAGE(更多信息请参阅:https://www.androidpolice.com/2015/07/15/android-m-feature-spotlight-apps-now-需要你的权限读取和写入外部存储/),但看起来这些权限只影响内部存储(MicroSD),而对于USB OTG则没有这样的细化权限.

file-io android usb-otg android-external-storage android-6.0-marshmallow

20
推荐指数
1
解决办法
3万
查看次数

清除数据后,getExternalCacheDir()返回null

我有一个简单的应用程序,可以访问和写入外部存储的数据.一切正常,直到我进入设置 - >应用程序 - >应用程序信息并通过"清除数据"按钮清除数据,然后每次调用getExternalCacheDir()开始返回null.

我一直在开发运行Android 4.2.2的Nexus 7.

我的清单看起来像:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.package"
    android:versionCode="5"
    android:versionName="1.3"
    xmlns:tools="http://schemas.android.com/tools">

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="17" />

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

<application
...
Run Code Online (Sandbox Code Playgroud)

不起作用的代码段:

    Log.d(TAG, "getExternalStorageState() = " + Environment.getExternalStorageState());
    Log.d(TAG, "getExternalCacheDir() = " + c.getExternalCacheDir());
    Log.d(TAG, "getExternalFilesDir(null) = " + c.getExternalFilesDir(null));
    Log.d(TAG, "getExternalFilesDir(Environment.DIRECTORY_MOVIES) = " + c.getExternalFilesDir(Environment.DIRECTORY_MOVIES));
Run Code Online (Sandbox Code Playgroud)

安装并执行应用程序后的LogCat:

05-15 11:26:45.948: DEBUG/HelperUtils(5541): getExternalStorageState() = mounted
05-15 11:26:45.948: DEBUG/HelperUtils(5541): getExternalCacheDir() =     /storage/emulated/0/Android/data/com.example.package/cache
05-15 11:26:45.948: DEBUG/HelperUtils(5541): getExternalFilesDir(null) = /storage/emulated/0/Android/data/com.example.package/files
05-15 11:26:45.948: DEBUG/HelperUtils(5541): getExternalFilesDir(Environment.DIRECTORY_MOVIES) …
Run Code Online (Sandbox Code Playgroud)

java android caching android-external-storage

19
推荐指数
2
解决办法
1万
查看次数

SecurityException:Permission Denial:读取(仅在模拟器上)

我的应用程序中有两个活动,MainActivity调用ImagePicker,它有一个GridView布局电话库中的所有图像,我使用ContentResolver来获取光标.

当我测试它时,它在我的手机上工作正常,但每次在模拟器上立即崩溃.

这是错误日志:

java.lang.SecurityException:Permission Denial:从pid = 5934读取com.android.providers.media.MediaProvider uri content:// media/external/images/media,uid = 10060需要android.permission.READ_EXTERNAL_STORAGE或grantUriPermission()

我确实有使用manifest写的权限,如下所示:

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

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

    <activity android:name=".ImagePicker" />
</application>
Run Code Online (Sandbox Code Playgroud)

permissions android android-emulator android-external-storage android-developer-api

19
推荐指数
2
解决办法
4万
查看次数

为什么我没有权限在外部存储上写入app dir?

TL; DR问题摘要:我的Android应用程序尝试写入 SD卡上应用程序的外部存储目录.它失败并出现权限错误.但是,提取到最小测试应用程序中的相同代码(方法)成功了!

由于我们的目标API级别包括KitKat及更高版本(以及JellyBean),并且KitKat限制应用程序在SD卡上的任何位置写入(应用程序指定的外部存储目录除外),应用程序会尝试写入该指定目录/path/to/sdcard/Android/data/com.example.myapp/files.我通过获取目录列表Activity.getExternalFilesDirs(null);并找到一个目录来验证此目录的路径isRemovable().即我们不是硬编码SD卡的路径,因为它因制造商和设备而异.以下是演示此问题的代码:

// Attempt to create a test file in dir.
private void testCreateFile(File dir) {
    Log.d(TAG, ">> Testing dir " + dir.getAbsolutePath());

    if (!checkDir(dir)) { return; }

    // Now actually try to create a file in this dir.
    File f = new File(dir, "foo.txt");
    try {
        boolean result = f.createNewFile();
        Log.d(TAG, String.format("Attempted to create file. No errors. Result: %b. Now exists: %b",
                result, f.exists()));
    } catch …
Run Code Online (Sandbox Code Playgroud)

android file-permissions android-sdcard android-external-storage

19
推荐指数
2
解决办法
1955
查看次数

如何使用adb将文件复制到可从PC访问的android目录

如果您将Android设备连接到PC,您可以浏览文件和目录.可以使用此目录Environment.getExternalStorage().您可以在应用程序中使用它并创建可访问的文件和目录.它工作正常.

在我的设备上这条路径看起来像/storage/emulated/0,如果我尝试adb push这个目录,我将获得访问被拒绝错误.是否可以将文件复制adb到与Windows资源管理器相同的文件夹中?

D:\...\tools>adb push ACCOUNTS.DB /storage/emulated/0
failed to copy 'ACCOUNTS.DB' to '/storage/emulated/0': Permission denied
58969 KB/s (606505 bytes in 0.010s)
Run Code Online (Sandbox Code Playgroud)

我正在实现自动导入/导出,我希望可以访问文件adb shell,万一不会出现任何问题.

目前使用变量$EXTERNAL_STORAGE作为变通方法,它适用于两者adb和应用程序.

设备:华硕Fonepad 7,Android 5.0,尝试了Genymotion Custom Tablet 6.0 - 工作.

android adb android-external-storage

18
推荐指数
1
解决办法
8214
查看次数