我正进入(状态
开放失败:
EACCES (Permission denied)
在线上 OutputStream myOutput = new FileOutputStream(outFileName);
我检查了根,我试过了android.permission.WRITE_EXTERNAL_STORAGE.
我该如何解决这个问题?
try {
InputStream myInput;
myInput = getAssets().open("XXX.db");
// Path to the just created empty db
String outFileName = "/data/data/XX/databases/"
+ "XXX.db";
// Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
// Transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
// Close the …Run Code Online (Sandbox Code Playgroud) android android-permissions android-5.0-lollipop android-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卡.
此应用程序的一个关键要求是允许用户在任何地方创建新文件夹.像这样的功能对应用程序非常有用.但是,该File#mkdir()方法在SD卡目录中根本不起作用.
我为清单文件添加了适当的权限.我还写了一个测试,看看哪些目录(我的Lollipop 5.0设备上都存在)允许创建一个新文件夹.根据我的观察,File#mkdir()只有在内部闪存目录中才有效.
注意:请不要Environment#getExternalStorageDirectory()与SD卡位置混淆,如本文所述.同样在Lollipop 5.0上,我相信/storage/emulated/0/并/storage/sdcard0/参考内部闪存存储,/storage/emulated/1/并/storage/sdcard1/参考SD卡(至少对我正在测试的设备是真的).
如何在非root用户Android设备上的外部存储路径之外的区域中创建新文件和文件夹?
表现:
...
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
Run Code Online (Sandbox Code Playgroud)
测试:
...
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final String NEW_FOLDER_NAME = "TestFolder";
testPath(new File(Environment.getExternalStorageDirectory(), NEW_FOLDER_NAME));
testPath(new File("/storage/emulated/0/", NEW_FOLDER_NAME));
testPath(new File("/storage/emulated/1/", NEW_FOLDER_NAME));
testPath(new File("/storage/sdcard0/Download/", NEW_FOLDER_NAME));
testPath(new File("/storage/sdcard1/Pictures/", NEW_FOLDER_NAME));
}
private void testPath(File path) {
String TAG = …Run Code Online (Sandbox Code Playgroud) 从Lollipop开始,应用程序可以访问真正的SD卡(在Kitkat上无法访问之后,并且在之前的版本中尚未获得官方支持),正如我在此处所述.
因为看到支持SD卡的Lollipop设备变得非常罕见,并且因为模拟器实际上没有能力(或者它?)来模拟SD卡支持,所以我花了很长时间来测试它.
无论如何,似乎不是使用普通的File类来访问SD卡(一旦获得了它的许可),你需要使用Uris来使用它,使用DocumentFile.
这限制了对正常路径的访问,因为我找不到将Uris转换为路径的方法,反之亦然(加上它非常烦人).这也意味着我不知道如何检查当前的SD卡是否可访问,因此我不知道何时要求用户允许读取/写入(或向他们).
目前,这就是我获取所有SD卡的路径:
/**
* returns a list of all available sd cards paths, or null if not found.
*
* @param includePrimaryExternalStorage set to true if you wish to also include the path of the primary external storage
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static List<String> getExternalStoragePaths(final Context context,final boolean includePrimaryExternalStorage)
{
final File primaryExternalStorageDirectory=Environment.getExternalStorageDirectory();
final List<String> result=new ArrayList<>();
final File[] externalCacheDirs=ContextCompat.getExternalCacheDirs(context);
if(externalCacheDirs==null||externalCacheDirs.length==0)
return result;
if(externalCacheDirs.length==1)
{
if(externalCacheDirs[0]==null)
return result;
final String storageState=EnvironmentCompat.getStorageState(externalCacheDirs[0]);
if(!Environment.MEDIA_MOUNTED.equals(storageState))
return …Run Code Online (Sandbox Code Playgroud) 我有一个压缩密码保护在Android模拟器上的SD卡上保存的视频文件.现在我想通过代码在SD卡上解压缩该视频文件.我怎样才能实现这一目标?任何帮助或代码?提前致谢
我有
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Run Code Online (Sandbox Code Playgroud)
在我的清单文件中,但是在尝试创建目录时失败了
Log.d(LOG_STRING, android.os.Environment.getExternalStorageState() );
java.io.File folder = new java.io.File(Environment.getExternalStorageDirectory() + java.io.File.separator + "test");
boolean success = true;
if (!folder.exists()) {
success = folder.mkdir();
}
if (success) {
Log.d(LOG_STRING, "Created directory");
} else {
Log.d(LOG_STRING, "FAILED WHILE CREATING DIRECTORY");
}
Run Code Online (Sandbox Code Playgroud)
外部存储的状态是"已挂载",但test无法创建目录并且输出为"FAILED WHILE CREATING DIRECTORY".
在手机中浏览"应用信息",标记为我的应用程序激活"修改或删除USB存储器内容"的权限.
可能是什么原因造成的?手机的一些特殊设置?这是搭载Android 4.3(API18)的三星GT-I9506.需要注意的是,getExternalStorageDirectory它不在SD卡上,而是在内部存储器(/storage/emulated/0/)上.
在与同事谈话时,似乎这个设备在被植根之后经历了几次调整(允许特定应用程序直接在SD卡上写入).可能不值得进一步调查,我只需切换到另一台设备.我会保留设备一段时间,如果有人会出现答案,我会快速测试它是否解决了问题.
问题仍然没有解决,但如前所述,这很可能是这个设备非常具体的.不可能在任何路径上写入,无论是外部存储还是内部存储,甚至不能在返回的路径中写入getExternalCacheDir().
我正在使用三星A3,Android 5.0.2.我正在使用此设置来编译应用程序,即Android 4.1 Jelly Bean(API 16)目标.
我确切地知道了外部可移动microSD卡的路径/mnt/extSdCard/(参见下面的注释#7).
问题:我注意到了
File myDir = new File("/mnt/extSdCard/test");
myDir.mkdirs();
Run Code Online (Sandbox Code Playgroud)
不起作用:没有创建目录.
也:
File file = new File("/mnt/extSdCard/books/test.txt"); // the folder "books" already exists on the external microSD card, has been created from computer with USB connection
FileOutputStream fos = new FileOutputStream(file);
Run Code Online (Sandbox Code Playgroud)
产生此错误:
java.io.FileNotFoundException:/mnt/extSdCard/books/test.txt:open failed:libcore.io.IoBridge.open中的EACCES(权限被拒绝)(...
如何强制读取+写入外部可移动microSD卡?
笔记:
Environment.getExternalStorageDirectory().toString()给出了/storage/emulated/0我的手机内部存储,即不是我想要的.
getExternalFilesDir(null)给出/storage/emulated/0/Android/data/com.blahblah.appname/files/即不是我想要的东西.请注意,我不能getExternalFilesDirs在决赛中使用,s因为这在API16中不可用.此外,API16中也没有运行时权限.
我已经拥有了<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />,而且READ_EXTERNAL_STORAGE.
我读了很多喜欢的话题这一个或这一个,其实大概20类似的问题,但最后似乎很复杂,一切都和它的相反之说.那是我的我正在寻找特定于这种情况的解决方案.
我不想ACTION_OPEN_DOCUMENT …
我试图通过我的应用程序删除音乐文件,但无法实现.我查过了
boolean exists = temp.exists();
boolean isFile = temp.isFile();
Run Code Online (Sandbox Code Playgroud)
如果有,那是的.这些方法让我回归真实.但是当我来到删除方法时:
boolean deleted = temp.delete();
Run Code Online (Sandbox Code Playgroud)
它返回False,文件没有被删除.没有Exception会抛出一个错误的返回我已删除的变量.
我也使用这些权限:
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.ACTION_HEADSET_PLUG"/>
Run Code Online (Sandbox Code Playgroud)
有人想出一个解决方案吗?(或者我可以使用的其他课程?)
编辑:这是我的完整代码
File temp = new File(str_path);
boolean exists = temp.exists();
boolean isFile = temp.isFile();
if (exists)) {
boolean deleted = temp.delete();
if (deleted) {
Toast.makeText(context, "Successful deleted " + Title_Artist, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Not able to delete file " + Title_Artist, Toast.LENGTH_SHORT).show();
}
}
Run Code Online (Sandbox Code Playgroud)
(我在调试时检查对象是否有自己的路径并且有它)
我有DocumentFile以下两种定义:
DocumentFile documentFile;
Uri documentFileUri;
Run Code Online (Sandbox Code Playgroud)
我可以通过以下方法从SD卡中删除文档文件:
documentFile.delete();DocumentsContract.deleteDocument(contentResolver, documentFileUri);但以上方法均不能从中删除相应的条目MediaStore。
处理该问题的正确方法是什么?如果我使用ContentProvider删除本地文件,它将File从数据库(contentResolver.delete(localFileUri, null, null);)中删除AND行。我希望如果使用,也会发生相同的情况,DocumentsContract但不会发生...
我想要的是
我想了解一下更新MediaStore。通常我会打电话给我,contentResolver.delete(documentFileUri, null, null);但这会失败,但有一个例外,说uri不支持删除...
题
是否有比我的解决方法更有效的方法?
解决方法
目前,我在删除a后使用以下功能立即更新媒体存储DocumentFile:
public static boolean updateAfterChangeBlocking(String path, int timeToWaitToRecheckMediaScanner)
{
final AtomicBoolean changed = new AtomicBoolean(false);
MediaScannerConnection.scanFile(StorageManager.get().getContext(),
new String[]{path}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
changed.set(true);
}
});
while (!changed.get()) {
try {
Thread.sleep(timeToWaitToRecheckMediaScanner);
} catch (InterruptedException e) …Run Code Online (Sandbox Code Playgroud)