GVKun编程网logo

Android SAF(存储访问框架):从TreeUri获取特定文件Uri(android获取存储路径)

10

如果您对AndroidSAF(存储访问框架):从TreeUri获取特定文件Uri和android获取存储路径感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解AndroidSAF(存储访问框架):

如果您对Android SAF(存储访问框架):从TreeUri获取特定文件Uriandroid获取存储路径感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解Android SAF(存储访问框架):从TreeUri获取特定文件Uri的各种细节,并对android获取存储路径进行深入的分析,此外还有关于Android 11 存储访问框架 - 如何使用文件?、Android Keystore存储访问令牌、Android Oreo如何从uri获得真正的路径?、Android Uri获取真实路径以及文件名的方法的实用技巧。

本文目录一览:

Android SAF(存储访问框架):从TreeUri获取特定文件Uri(android获取存储路径)

Android SAF(存储访问框架):从TreeUri获取特定文件Uri(android获取存储路径)

我正在使用外部SD卡的PersistableuriPermission并将其存储以供进一步使用.
现在我希望当用户向我提供文件路径时,从我的应用程序中的文件列表中,我想编辑文档并重命名它.

所以我有要编辑的文件的文件路径.

我的问题是如何从我的TreeUri获取该文件的Uri以及编辑文件.

解决方法:

访问Sd-Card的文件

使用DOCUMENT_TREE对话框获取SD卡的Uri.

告知用户如何在对话框中选择SD卡. (带图片或gif动画)

// call for document tree dialog
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE);

在onActivityResult上,您将拥有所选的目录Uri. (sdCardUri)

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case REQUEST_CODE_OPEN_DOCUMENT_TREE:
            if (resultCode == Activity.RESULT_OK) {
                sdCardUri = data.getData();
             }
             break;
     }
  }

现在必须检查用户是否,

一种.选择了SD卡

湾选择我们的文件所在的SD卡(某些设备可能有多个SD卡).

我们通过层次结构查找文件来检查a和b,从sd root到我们的文件.如果找到文件,则获取a和b条件.

//First we get `DocumentFile` from the `TreeUri` which in our case is `sdCardUri`.
DocumentFile documentFile = DocumentFile.fromTreeUri(this, sdCardUri);

//Then we split file path into array of strings.
//ex: parts:{"", "storage", "extSdCard", "MyFolder", "MyFolder", "myImage.jpg"}
// There is a reason for having two similar names "MyFolder" in 
//my exmple file path to show you similarity in names in a path will not 
//distract our hiarchy search that is provided below.
String[] parts = (file.getPath()).split("\\/");

// findFile method will search documentFile for the first file 
// with the expected `displayName`

// We skip first three items because we are already on it.(sdCardUri = /storage/extSdCard)
for (int i = 3; i < parts.length; i++) {
    if (documentFile != null) {
        documentFile = documentFile.findFile(parts[i]);
    }
  }

if (documentFile == null) {

    // File not found on tree search
    // User selected a wrong directory as the sd-card
    // Here must inform user about how to get the correct sd-card
    // and invoke file chooser dialog again.

 } else {

    // File found on sd-card and it is a correct sd-card directory
    // save this path as a root for sd-card on your database(sqlite, XML, txt,...)

    // Now do whatever you like to do with documentFile.
    // Here I do deletion to provide an example.


    if (documentFile.delete()) {// if delete file succeed 
        // Remove information related to your media from ContentResolver,
        // which documentFile.delete() didn't do the trick for me. 
        // Must do it otherwise you will end up with showing an empty
        // ImageView if you are getting your URLs from MediaStore.
        // 
        Uri mediaContentUri = ContentUris.withAppendedId(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                longMediaId);
        getContentResolver().delete(mediaContentUri , null, null);
    }


 }

注意:

您必须为清单中的外部存储以及应用内的os> = Marshmallow提供访问权限.
https://stackoverflow.com/a/32175771/2123400

编辑SD卡的文件

要编辑SD卡上的现有图像,如果要调用其他应用程序来执行此操作,则不需要执行上述任何步骤.

在这里,我们调用所有活动(来自所有已安装的应用程序),并具有编辑图像的功能. (程序员在清单中标记他们的应用程序,以便提供其他应用程序(活动)的可访问性).

在您的editButton点击事件:

String mimeType = getMimeTypeFromMediaContentUri(mediaContentUri);
startActivityForResult(Intent.createChooser(new Intent(Intent.ACTION_EDIT).setDataAndType(mediaContentUri, mimeType).putExtra(Intent.EXTRA_STREAM, mediaContentUri).addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION), "Edit"), REQUEST_CODE_SHARE_EDIT_SET_AS_INTENT);

这是如何获取mimeType:

public String getMimeTypeFromMediaContentUri(Uri uri) {
    String mimeType;
    if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
        ContentResolver cr = getContentResolver();
        mimeType = cr.getType(uri);
    } else {
        String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri
                .toString());
        mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                fileExtension.toLowerCase());
    }
    return mimeType;
}

注意:

在Android KitKat(4.4)上不要求用户选择SD卡,因为在此版本的Android DocumentProvideris上不适用,因此我们没有机会使用这种方法访问SD卡.
查看DocumentProvider的API级别
https://developer.android.com/reference/android/provider/DocumentsProvider.html
我在Android KitKat(4.4)上找不到任何可用的东西.如果您发现KitKat有用,请与我们分享.

在以下版本中,OS已经提供了对SD卡的访问权限.

Android 11 存储访问框架 - 如何使用文件?

Android 11 存储访问框架 - 如何使用文件?

这个 API 使用了一个 Java.IO.File-Object,我们从一个“.map”文件的路径中获得,这个文件几乎有 2GB 大。

幸运的是,Mapsforge 将来会提供更灵活的 API。您可能希望就他们的建议与他们联系。

有什么方法可以使用 SAF 来获取我可以在代码中使用的 Java.IO.File-Object?

没有。毕竟,用户可能会选择 Google Drive 或其他云存储提供商上的内容,而不是本地文件。或者,他们可能会选择您的应用无法访问的文件。或者,他们可能会选择存储在加密文件中的内容,该文件需要由文档提供者解密。等等。

Android Keystore存储访问令牌

Android Keystore存储访问令牌

在我的应用程序中,当用户使用OAuth成功进行身份验证时,我需要存储REST API返回的访问令牌.我正在考虑使用密钥库来存储此令牌,以便在应用程序中进一步使用.但到目前为止,我还没有看到使用android密钥库API存储已生成密钥的实现.是否有任何存储已生成令牌的示例或代码段.

此外,如果我使用密钥库来存储访问令牌,那么有根电话的用户是否可以访问这些令牌?

谢谢.

最佳答案
以下博客文章提供了有关如何执行此操作的非常好的解释.

http://nelenkov.blogspot.com/2012/05/storing-application-secrets-in-androids.html

如果有根电话的用户可以获得对这些令牌的访问权限(如果它们是加密的话)也无关紧要.幸运的是,Android的系统密钥库守护程序使用AES加密密钥.

Android Oreo如何从uri获得真正的路径?

Android Oreo如何从uri获得真正的路径?

我正在使用此代码从URI获取真实路径.它正在努力
棉花糖但不在奥利奥:

private String getPathNew(Activity activity, Uri uri) { 
    if (isDownloadsDocument(uri)) {
        final String id = DocumentsContract.getDocumentId(uri);
        final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
        return getDataColumn(activity, contentUri, null, null);
    }
    return null;
}

public static String getDataColumn(Context context, Uri uri, String 
selection, String[] selectionArgs) {
    Cursor cursor = null;
    final String column = "_data";
    final String[] projection = {column};
    try {
        cursor = context.getContentResolver().query(uri, projection, selection, 
selectionArgs, null);
        if (cursor != null && cursor.movetoFirst()) {
            final int column_index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(column_index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}

我究竟做错了什么?

解决方法:

 public static String getRealPathFromURI(Context context, Uri contentUri) {
    String[] proj = {MediaStore.Images.Media.DATA};
    Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, 
                                                                               null);
    if (cursor != null) {
        int column_index = 
        cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.movetoFirst();
        return cursor.getString(column_index);
    }
    return null;
}

Android Uri获取真实路径以及文件名的方法

Android Uri获取真实路径以及文件名的方法

在Android 编程中经常会用到uri转化为文件路径 
下面是4.4后通过Uri获取路径以及文件名一种方法

 public static String getRealFilePath( final Context context, final Uri uri ) {
        if ( null == uri ) return null;
        final String scheme = uri.getScheme();
        String data = null;
        if ( scheme == null )
            data = uri.getPath();
        else if ( ContentResolver.SCHEME_FILE.equals( scheme ) ) {
            data = uri.getPath();
        } else if ( ContentResolver.SCHEME_CONTENT.equals( scheme ) ) {
            Cursor cursor = context.getContentResolver().query( uri, new String[] { MediaStore.Images.ImageColumns.DATA }, null, null, null );
            if ( null != cursor ) {
                if ( cursor.moveToFirst() ) {
                    int index = cursor.getColumnIndex( MediaStore.Images.ImageColumns.DATA );
                    if ( index > -1 ) {
                        data = cursor.getString( index );
                    }
                }
                cursor.close();
            }
        }
        return data;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

等到的路径 /storage/emulated/0/图片/浪费-林宥嘉.mp3

怎么获取文件名呢?

 String path="/storage/emulated/0/图片/浪费-林宥嘉.mp3";
                String b = path.substring(path.lastIndexOf("/") + 1, path.length());
  • 1
  • 2
  • 1
  • 2

通过索引最后一个/就可以在String中截取了

今天关于Android SAF(存储访问框架):从TreeUri获取特定文件Uriandroid获取存储路径的讲解已经结束,谢谢您的阅读,如果想了解更多关于Android 11 存储访问框架 - 如何使用文件?、Android Keystore存储访问令牌、Android Oreo如何从uri获得真正的路径?、Android Uri获取真实路径以及文件名的方法的相关知识,请在本站搜索。

本文标签: