我正在尝试访问用户设备上的媒体文件(音乐)来播放它们; 一个简单的"你好世界" - 音乐播放器应用程序.
我已经按照一些教程,他们基本上给出了相同的代码.但它不起作用; 它一直在崩溃并告诉我:
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
在我的应用程序中,我需要在设备存储中存储大量图像.这些文件往往满足设备存储,我想让用户能够选择外部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) Android在如何处理SD卡和存储方面有很多变化:
从API 23(Android 6)开始,事情似乎再次发生变化......
对于API 23,至少有两件新东西与存储相关:
由于没有配备SD卡的Android 6设备,并且因为模拟器本身并不能真正使用SD卡,所以仍然无法知道发生了什么.
SD卡是否可以使用File-API而不是DocumentFile获取访问权限?
如果我想访问所有外部存储路径(包括SD卡),这是否意味着我需要两次请求此权限:一个用于主外部存储,一个用于SD卡?
在手动授予许可之前,SD卡上的文件是否可以以任何方式访问?
假设用户选择使用"Adoptable Storage Devices",这对于检索应用程序文件路径的各种函数意味着什么?例如:getFilesDir,getExternalFilesDir,...?getExternalFilesDirs的oder会因为它而改变吗?
当用户将应用程序从SD卡移动到SD卡时(使用"可采用的存储设备"),应用程序的文件会发生什么变化?SD卡上的应用程序文件怎么样?他们会留下来吗?或者他们会搬到某个地方?
例如,如果应用程序在SD卡上有"file1.txt",则在路径"/ storage/extSdCard/Android/data/appPackageName"上,它有一个文件"file2.txt"(或者甚至是同一个名字)在路径"/ storage/emulated/0/Android/data/appPackageName"上的主外部存储上.切换后,这些文件会发生什么?如果有的话,他们将如何合并到一个文件夹中?
将应用程序移动到SD卡(使用"Adoptable Storage Devices")时,是否意味着不会使用内部存储?
android sd-card android-permissions android-external-storage android-6.0-marshmallow
我想打开外部存储目录路径以编程方式保存文件.我试过但没有获得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) 我为此感到疯狂:
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 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_STORAGE和android.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
我有一个简单的应用程序,可以访问和写入外部存储的数据.一切正常,直到我进入设置 - >应用程序 - >应用程序信息并通过"清除数据"按钮清除数据,然后每次调用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) 我的应用程序中有两个活动,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
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
如果您将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 ×10
java ×3
sd-card ×2
adb ×1
android-file ×1
audio-player ×1
caching ×1
file-io ×1
permissions ×1
usb-otg ×1