Sim*_*mon 6 android file save sd-card
我想将文件保存在SD卡文件夹中.
我不能在我的项目上使用V4支持.
所以我打电话给:
Intent itent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
itent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
itent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(itent, requestCodeTree);
Run Code Online (Sandbox Code Playgroud)
然后在onActivityResult上,我有:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (resultCode == RESULT_OK) {
switch(requestCode) {
case requestCodeTree:
saveFile(intent.getData());
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
而saveFile的代码是:
private void saveFile(Uri data) {
ContentResolver contentResolver = context.getContentResolver();
InputStream in = null;
OutputStream out = null;
try {
// Problems start here ************************
Uri toUriFile= getUriBackupFile(context, data);
// ********************************************
if (toUriFile==null) {
Uri toUriFolder = DocumentsContract.buildDocumentUriUsingTree(data, DocumentsContract.getTreeDocumentId(data));
toUriFile = DocumentsContract.createDocument(contentResolver, toUriFolder, "", backupName);
}
out = contentResolver.openOutputStream(toUriFile);
in = new FileInputStream(fromFile);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
// write the output file (the file is now copied)
out.flush();
out.close();
} catch (FileNotFoundException e) {
Log.e(TAG, "Failed", e);
} catch (Exception e) {
Log.e(TAG, "Failed", e);
}
}
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.
当我调用getUriBackupFile来获取目标文件的uri 时,问题就开始了.
要做到这一点,我查询ContentResolver的与buildChildDocumentsUriUsingTree并试图筛选,其中结果DocumentsContract.Document.COLUMN_DISPLAY_NAME符合我的文件的显示名称,就像这样:
private static Uri getUriBackupFile(Context context, Uri treeUri) {
final ContentResolver resolver = context.getContentResolver();
final Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(
treeUri,
DocumentsContract.getTreeDocumentId(treeUri));
Cursor c = null;
try {
String[] projections = new String[] {
DocumentsContract.Document.COLUMN_DOCUMENT_ID,
DocumentsContract.Document.COLUMN_DISPLAY_NAME};
// this line doesn't seem to have any effect !
String selection = DocumentsContract.Document.COLUMN_DISPLAY_NAME + " = '" + backupName + "' ";
// *************************************************************************
c = resolver.query(childrenUri, projections, selection, null, null);
if (c!=null && c.moveToFirst()) {
// Here I expect to have c.getCount() == 1 or == 0
// But actually c.getCount() == [Number of children in the treeUri] regardless of the selection
String documentId = c.getString(0);
Uri documentUri = DocumentsContract.buildDocumentUriUsingTree(treeUri,
documentId);
return documentUri;
}
} catch (Exception e) {
Log.w(TAG, "Failed query: " + e);
} finally {
if (c!=null) c.close();
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
但是无论选择什么,查询总是返回treeUri的所有子节点.所以,似乎选择没有效果.
我总是可以循环遍历所有结果,但如果所选文件夹中包含大量文件,则对性能不利.
所以我的问题是:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />Run Code Online (Sandbox Code Playgroud)
如果您的应用程序在 Android 6 或更高版本的设备上运行。您需要先请求许可,然后才能写入 SD 卡/外部存储。请遵循有关在运行时检查权限的文档。
使用Environment.getExternalStorageDirectory()获取外部目录。这将返回外部目录。
另请参阅本文档(https://developer.android.com/training/data-storage/files)和这个问题。
| 归档时间: |
|
| 查看次数: |
186 次 |
| 最近记录: |