怎么获取android系统服务,如Uri,intent参数等,或者说去哪里查看

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么获取android系统服务,如Uri,intent参数等,或者说去哪里查看相关的知识,希望对你有一定的参考价值。

android系统服务,如Uri,intent参数
可以在Intent中指定程序要执行的动作(比如:view,edit,dial),以及程序执行到该动作时所需要的资料。都指定好后,只要调用startActivity(),Android系统会自动寻找最符合你指定要求的应用程序,并执行该程序。

★intent大全:

1.从google搜索内容

Intent intent = new Intent();

intent.setAction(Intent.ACTION_WEB_SEARCH);

intent.putExtra(SearchManager.QUERY,"searchString")

startActivity(intent);

2.浏览网页

Uri uri =Uri.parse("htt。。。。。。。。om");

Intent it = new Intent(Intent.ACTION_VIEW,uri);

startActivity(it);

3.显示地图

Uri uri = Uri.parse("geo:38.899533,-77.036476");

Intent it = newIntent(Intent.Action_VIEW,uri);

startActivity(it);

4.路径规划

Uri uri =Uri.parse("http。。。。。。。。。。/maps?
f=dsaddr=startLat%20startLng&daddr=endLat%20endLng&hl=en");

Intent it = newIntent(Intent.ACTION_VIEW,URI);

startActivity(it);

5.拨打电话

Uri uri =Uri.parse("tel:xxxxxx");

Intent it = new Intent(Intent.ACTION_DIAL,uri);

startActivity(it);

6.调用发短信的程序

Intent it = newIntent(Intent.ACTION_VIEW);

it.putExtra("sms_body", "TheSMS text");

it.setType("vnd.android-dir/mms-sms");

startActivity(it);

7.发送短信

Uri uri =Uri.parse("smsto:0800000123");

Intent it = newIntent(Intent.ACTION_SENDTO, uri);

it.putExtra("sms_body", "TheSMS text");

startActivity(it);

String body="this is sms demo";

Intent mmsintent = newIntent(Intent.ACTION_SENDTO, Uri.fromParts("smsto",
number, null));

mmsintent.putExtra(Messaging.KEY_ACTION_SENDTO_MESSAGE_BODY,body);

mmsintent.putExtra(Messaging.KEY_ACTION_SENDTO_COMPOSE_MODE,true);

mmsintent.putExtra(Messaging.KEY_ACTION_SENDTO_EXIT_ON_SENT,true);

startActivity(mmsintent);

8.发送彩信

Uri uri =Uri.parse("content://media/external/images/media/23");

Intent it = newIntent(Intent.ACTION_SEND);

it.putExtra("sms_body","some text");

it.putExtra(Intent.EXTRA_STREAM, uri);

it.setType("image/png");

startActivity(it);

StringBuilder sb = new StringBuilder();

sb.append("file://");

sb.append(fd.getAbsoluteFile());

Intent intent = newIntent(Intent.ACTION_SENDTO, Uri.fromParts("mmsto",
number, null));

// Below extra datas are all optional.

intent.putExtra(Messaging.KEY_ACTION_SENDTO_MESSAGE_SUBJECT,subject);

intent.putExtra(Messaging.KEY_ACTION_SENDTO_MESSAGE_BODY,body);

intent.putExtra(Messaging.KEY_ACTION_SENDTO_CONTENT_URI,sb.toString());

intent.putExtra(Messaging.KEY_ACTION_SENDTO_COMPOSE_MODE,composeMode);

intent.putExtra(Messaging.KEY_ACTION_SENDTO_EXIT_ON_SENT,exitOnSent);

startActivity(intent);

9.发送Email

Uri uri =Uri.parse("mailto:xxx@abc.com");

Intent it = newIntent(Intent.ACTION_SENDTO, uri);

startActivity(it);

Intent it = new Intent(Intent.ACTION_SEND);

it.putExtra(Intent.EXTRA_EMAIL,"me@abc.com");

it.putExtra(Intent.EXTRA_TEXT, "Theemail body text");

it.setType("text/plain");

startActivity(Intent.createChooser(it,"Choose Email Client"));

Intent it=new Intent(Intent.ACTION_SEND);

String[] tos="me@abc.com";

String[]ccs="you@abc.com";

it.putExtra(Intent.EXTRA_EMAIL, tos);

it.putExtra(Intent.EXTRA_CC, ccs);

it.putExtra(Intent.EXTRA_TEXT, "Theemail body text");

it.putExtra(Intent.EXTRA_SUBJECT, "Theemail subject text");

it.setType("message/rfc822");

startActivity(Intent.createChooser(it,"Choose Email Client"));

Intent it = newIntent(Intent.ACTION_SEND);

it.putExtra(Intent.EXTRA_SUBJECT, "Theemail subject text");

it.putExtra(Intent.EXTRA_STREAM,"file:///sdcard/mysong.mp3");

sendIntent.setType("audio/mp3");

startActivity(Intent.createChooser(it,"Choose Email Client"));

10.播放多媒体

Intent it = new Intent(Intent.ACTION_VIEW);

Uri uri =Uri.parse("file:///sdcard/song.mp3");

it.setDataAndType(uri,"audio/mp3");

startActivity(it);

Uri uri
=Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"1");

Intent it = new Intent(Intent.ACTION_VIEW,uri);

startActivity(it);

11.uninstall apk

Uri uri =Uri.fromParts("package", strPackageName, null);

Intent it = newIntent(Intent.ACTION_DELETE, uri);

startActivity(it);

12.install apk

Uri installUri = Uri.fromParts("package","xxx", null);

returnIt = newIntent(Intent.ACTION_PACKAGE_ADDED, installUri);

打开照相机

<1>Intent i = new Intent(Intent.ACTION_CAMERA_BUTTON, null);

this.sendBroadcast(i);

<2>long dateTaken = System.currentTimeMillis();

String name = createName(dateTaken) + ".jpg";

fileName = folder + name;

ContentValues values = new ContentValues();

values.put(Images.Media.TITLE, fileName);

values.put("_data", fileName);

values.put(Images.Media.PICASA_ID, fileName);

values.put(Images.Media.DISPLAY_NAME, fileName);

values.put(Images.Media.DESCRIPTION, fileName);

values.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, fileName);

Uri photoUri = getContentResolver().insert(

MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values);

Intent inttPhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

inttPhoto.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);

startActivityForResult(inttPhoto, 10);

14.从gallery选取图片

Intent i = new Intent();

i.setType("image/*");

i.setAction(Intent.ACTION_GET_CONTENT);

startActivityForResult(i, 11);

打开录音机

Intent mi = new Intent(Media.RECORD_SOUND_ACTION);

startActivity(mi);

16.显示应用详细列表

Uri uri =Uri.parse("market://details?id=app_id");

Intent it = new Intent(Intent.ACTION_VIEW,uri);

startActivity(it);

//where app_id is the application ID, findthe ID

//by clicking on your application on Markethome

//page, and notice the ID from the addressbar

刚才找app id未果,结果发现用package name也可以

Uri uri =Uri.parse("market://details?id=");

这个简单多了

17寻找应用

Uri uri =Uri.parse("market://search?q=pname:pkg_name");

Intent it = new Intent(Intent.ACTION_VIEW,uri);

startActivity(it);

//where pkg_name is the full package pathfor an application

18打开联系人列表

<1>

Intent i = new Intent();

i.setAction(Intent.ACTION_GET_CONTENT);

i.setType("vnd.android.cursor.item/phone");

startActivityForResult(i, REQUEST_TEXT);

<2>

Uri uri = Uri.parse("content://contacts/people");

Intent it = new Intent(Intent.ACTION_PICK, uri);

startActivityForResult(it, REQUEST_TEXT);

19 打开另一程序

Intent i = new Intent();

ComponentName cn = newComponentName("com.yellowbook.android2",

"com.yellowbook.android2.AndroidSearch");

i.setComponent(cn);

i.setAction("android.intent.action.MAIN");

startActivityForResult(i, RESULT_OK);

20.调用系统编辑添加联系人(高版本SDK有效):

Intent it = newIntent(Intent.ACTION_INSERT_OR_EDIT);

it.setType("vnd.android.cursor.item/contact");

//it.setType(Contacts.CONTENT_ITEM_TYPE);

it.putExtra("name","myName");

it.putExtra(android.provider.Contacts.Intents.Insert.COMPANY,
"organization");

it.putExtra(android.provider.Contacts.Intents.Insert.EMAIL,"email");

it.putExtra(android.provider.Contacts.Intents.Insert.PHONE,"homePhone");

it.putExtra(android.provider.Contacts.Intents.Insert.SECONDARY_PHONE,

"mobilePhone");

it.putExtra( android.provider.Contacts.Intents.Insert.TERTIARY_PHONE,

"workPhone");

it.putExtra(android.provider.Contacts.Intents.Insert.JOB_TITLE,"title");

startActivity(it);

21.调用系统编辑添加联系人(全有效):

Intent intent = newIntent(Intent.ACTION_INSERT_OR_EDIT);

intent.setType(People.CONTENT_ITEM_TYPE);

intent.putExtra(Contacts.Intents.Insert.NAME, "My Name");

intent.putExtra(Contacts.Intents.Insert.PHONE, "+1234567890");

intent.putExtra(Contacts.Intents.Insert.PHONE_TYPE,Contacts.PhonesColumns.TYPE_MOBILE);

intent.putExtra(Contacts.Intents.Insert.EMAIL, "com@com.com");

intent.putExtra(Contacts.Intents.Insert.EMAIL_TYPE,
Contacts.ContactMethodsColumns.TYPE_WORK);

startActivity(intent);

★intent action大全:

android.intent.action.ALL_APPS

android.intent.action.ANSWER

android.intent.action.ATTACH_DATA

android.intent.action.BUG_REPORT

android.intent.action.CALL

android.intent.action.CALL_BUTTON

android.intent.action.CHOOSER

android.intent.action.CREATE_LIVE_FOLDER

android.intent.action.CREATE_SHORTCUT

android.intent.action.DELETE

android.intent.action.DIAL

android.intent.action.EDIT

android.intent.action.GET_CONTENT

android.intent.action.INSERT

android.intent.action.INSERT_OR_EDIT

android.intent.action.MAIN

android.intent.action.MEDIA_SEARCH

android.intent.action.PICK

android.intent.action.PICK_ACTIVITY

android.intent.action.RINGTONE_PICKER

android.intent.action.RUN

android.intent.action.SEARCH

android.intent.action.SEARCH_LONG_PRESS

android.intent.action.SEND

android.intent.action.SENDTO

android.intent.action.SET_WALLPAPER

android.intent.action.SYNC

android.intent.action.SYSTEM_TUTORIAL

android.intent.action.VIEW

android.intent.action.VOICE_COMMAND

android.intent.action.WEB_SEARCH

android.net.wifi.PICK_WIFI_NETWORK

android.settings.AIRPLANE_MODE_SETTINGS

android.settings.APN_SETTINGS

android.settings.APPLICATION_DEVELOPMENT_SETTINGS

android.settings.APPLICATION_SETTINGS

android.settings.BLUETOOTH_SETTINGS

android.settings.DATA_ROAMING_SETTINGS

android.settings.DATE_SETTINGS

android.settings.DISPLAY_SETTINGS

android.settings.INPUT_METHOD_SETTINGS

android.settings.INTERNAL_STORAGE_SETTINGS

android.settings.LOCALE_SETTINGS

android.settings.LOCATION_SOURCE_SETTINGS

android.settings.MANAGE_APPLICATIONS_SETTINGS

android.settings.MEMORY_CARD_SETTINGS

android.settings.NETWORK_OPERATOR_SETTINGS

android.settings.QUICK_LAUNCH_SETTINGS

android.settings.SECURITY_SETTINGS

android.settings.SETTINGS

android.settings.SOUND_SETTINGS

android.settings.SYNC_SETTINGS

android.settings.USER_DICTIONARY_SETTINGS

android.settings.WIFI_IP_SETTINGS

android.settings.WIFI_SETTINGS

android.settings.WIRELESS_SETTINGS
参考技术A

1、首先下载工程模式

2、安装成功后会扫描系统暗码

3、里面有手机所有的信息,注意不要随意更改参数以免手机异常。

参考技术B 系统的Uri Intent 在 activity class里的@ 有个 getresult 啥的 就可以获取了

当你启动一个系统的activity 后 就会打开相关的服务,结果返回在 之前的acitivity class 的
结果里
参考技术C 例如调用照相机
Intent intent = new Intent();
intent.setAction("android.media.action.STILL_IMAGE_CAMERA");
startActivity(intent);
需要加权限本回答被提问者和网友采纳
参考技术D http://developer.android.com/reference/android/content/Intent.html
可以去android developer官方看的。

获取 Uri Android 的真实路径

【中文标题】获取 Uri Android 的真实路径【英文标题】:Get Real Path For Uri Android 【发布时间】:2013-07-06 22:25:23 【问题描述】:

我正在开发VideoPlayer。我将启动意图的URI 转换为字符串,它给了我content://media/external.....。但我需要找到真正的路径。

例如: /storage/extSdcard....

我该怎么做?

如果需要,这是我的代码:

videoURI = getIntent().getData();
vv.setVideoURI(videoURI);

videoName = videoURI.toString();

tvTitle.setText(videoName);

【问题讨论】:

【参考方案1】:

使用此代码。这适用于所有 android 版本。这是经过测试的代码。这支持所有设备

public static String getPathFromUri(final Context context, final Uri uri) 

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) 
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) 
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) 
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                

                // TODO handle non-primary volumes
            
            // DownloadsProvider
            else 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(context, contentUri, null, null);
            
            // MediaProvider
            else if (isMediaDocument(uri)) 
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) 
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                 else if ("video".equals(type)) 
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                 else if ("audio".equals(type)) 
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                

                final String selection = "_id=?";
                final String[] selectionArgs = new String[] 
                        split[1]
                ;

                return getDataColumn(context, contentUri, selection, selectionArgs);
            
        
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) 

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) 
            return uri.getPath();
        

        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 index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            
         finally 
            if (cursor != null)
                cursor.close();
        
        return null;
    


    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) 
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) 
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) 
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) 
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());

【讨论】:

DocumentsContract 本身仅在 API 级别 19 KitKat 之后可用时,这如何在所有 Android 版本上运行? developer.android.com/reference/android/provider/… 应该已经提到了原答案:***.com/a/27271131/1567541 @SANJAYGUPTA getPathFromUri() 将为外部 sdcard 文件返回 null。有什么解决方案吗?? 如果存储是存储卡会怎样?如果在 Android L 中使用此方法,非主 get 为 null 它不能在 android 7 上运行。停止并出现此错误:列 '_data' 不存在【参考方案2】:

您可以将此代码用于选定的视频路径。

Uri uri = data.getData();
String[] filePathColumn = MediaStore.Images.Media.DATA;
Cursor cursor = getContentResolver().query(uri, filePathColumn, null, null, null); 
if(cursor.moveToFirst())
   int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
   String yourRealPath = cursor.getString(columnIndex);
 else 
   //boooo, cursor doesn't have rows ...

cursor.close();

您可以参考以下链接寻求帮助。

Get filename and path from URI from mediastore

最新的文件提供程序 (API 29):

请点击链接:

博客:https://blogs.datanapps.com/media-picker Github:https://github.com/datanapps/MediaPicker

我希望你会成功。

【讨论】:

试试这个可能对你有帮助。否则我明天会更新我的ans。 journaldev.com/23219/… @PriyankaSingh 请尝试此链接,希望它对您有所帮助。 github.com/datanapps/MediaPicker【参考方案3】:

在 Kotlin 中通过使用这个函数我们可以从 URI 中获取真实路径:

这里是getRealPathFromURI的代码

fun getRealPathFromURI(context: Context, uri: Uri): String? 
    when 
        // DocumentProvider
        DocumentsContract.isDocumentUri(context, uri) -> 
            when 
                // ExternalStorageProvider
                isExternalStorageDocument(uri) -> 
                    val docId = DocumentsContract.getDocumentId(uri)
                    val split = docId.split(":").toTypedArray()
                    val type = split[0]
                    // This is for checking Main Memory
                    return if ("primary".equals(type, ignoreCase = true)) 
                        if (split.size > 1) 
                            Environment.getExternalStorageDirectory().toString() + "/" + split[1]
                         else 
                            Environment.getExternalStorageDirectory().toString() + "/"
                        
                        // This is for checking SD Card
                     else 
                        "storage" + "/" + docId.replace(":", "/")
                    
                
                isDownloadsDocument(uri) -> 
                    val fileName = getFilePath(context, uri)
                    if (fileName != null) 
                        return Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName
                    
                    var id = DocumentsContract.getDocumentId(uri)
                    if (id.startsWith("raw:")) 
                        id = id.replaceFirst("raw:".toRegex(), "")
                        val file = File(id)
                        if (file.exists()) return id
                    
                    val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id))
                    return getDataColumn(context, contentUri, null, null)
                
                isMediaDocument(uri) -> 
                    val docId = DocumentsContract.getDocumentId(uri)
                    val split = docId.split(":").toTypedArray()
                    val type = split[0]
                    var contentUri: Uri? = null
                    when (type) 
                        "image" -> 
                            contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
                        
                        "video" -> 
                            contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
                        
                        "audio" -> 
                            contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
                        
                    
                    val selection = "_id=?"
                    val selectionArgs = arrayOf(split[1])
                    return getDataColumn(context, contentUri, selection, selectionArgs)
                
            
        
        "content".equals(uri.scheme, ignoreCase = true) -> 
            // Return the remote address
            return if (isGooglePhotosUri(uri)) uri.lastPathSegment else getDataColumn(context, uri, null, null)
        
        "file".equals(uri.scheme, ignoreCase = true) -> 
            return uri.path
        
    
    return null


fun getDataColumn(context: Context, uri: Uri?, selection: String?,
                  selectionArgs: Array<String>?): String? 
    var cursor: Cursor? = null
    val column = "_data"
    val projection = arrayOf(
            column
    )
    try 
        if (uri == null) return null
        cursor = context.contentResolver.query(uri, projection, selection, selectionArgs,
                null)
        if (cursor != null && cursor.moveToFirst()) 
            val index = cursor.getColumnIndexOrThrow(column)
            return cursor.getString(index)
        
     finally 
        cursor?.close()
    
    return null



fun getFilePath(context: Context, uri: Uri?): String? 
    var cursor: Cursor? = null
    val projection = arrayOf(
            MediaStore.MediaColumns.DISPLAY_NAME
    )
    try 
        if (uri == null) return null
        cursor = context.contentResolver.query(uri, projection, null, null,
                null)
        if (cursor != null && cursor.moveToFirst()) 
            val index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME)
            return cursor.getString(index)
        
     finally 
        cursor?.close()
    
    return null


/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is ExternalStorageProvider.
 */
fun isExternalStorageDocument(uri: Uri): Boolean 
    return "com.android.externalstorage.documents" == uri.authority


/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is DownloadsProvider.
 */
fun isDownloadsDocument(uri: Uri): Boolean 
    return "com.android.providers.downloads.documents" == uri.authority


/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is MediaProvider.
 */
fun isMediaDocument(uri: Uri): Boolean 
    return "com.android.providers.media.documents" == uri.authority


/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is Google Photos.
 */
fun isGooglePhotosUri(uri: Uri): Boolean 
    return "com.google.android.apps.photos.content" == uri.authority

在您的活动或片段中获取绕过 URI 到 getRealPathFromURI 函数的真实路径:

val fileRealPath = getRealPathFromURI(context!!, fileURI) ?: ""

【讨论】:

你好,在我的例子中,它进入 isDownloadDocument 路径,但 _id 是 msf:24,而不是 raw: & 不是数字。你能帮忙吗? @SanskarDahiya 如果id.startsWith("msf:") ***.com/a/62154537/2462531 试试这个方法 您好,我已经检查过了,但是内存有问题。因此,从 Andorid 文档中创建一些解决方案: if (isAndroid10 && id.startsWith("msf:")) final String[] split = id.split(":");最终字符串选择 = "_id=?"; final String[] selectionArgs = new String[] split[1] ;返回 getDataColumn(context, MediaStore.Downloads.EXTERNAL_CONTENT_URI, selection, selectionArgs); 【参考方案4】:

这是我以前用过的东西:

public String getRealPathFromURI (Uri contentUri) 
    String path = null;
    String[] proj =  MediaStore.MediaColumns.DATA ;
    Cursor cursor = getContentResolver().query(contentUri, proj, null, null, null);
    if (cursor.moveToFirst()) 
       int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
       path = cursor.getString(column_index);
    
    cursor.close();
    return path;

【讨论】:

光标为空。 这适用于媒体内容(来自媒体内容提供商),但不适用于存储访问框架文件。 @PriyankaSingh 你已经接受了一个答案。如果您已经走得更远了,现在遇到了稍微不同的问题,请发布一个新的具体问题 @KenWolf 接受的答案不适用于所有版本。【参考方案5】:

大多数答案不适用于图库和相机图像。这对我有用。

public static String getPath(final Context context, final Uri uri) 
    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    Log.i("URI",uri+"");
    String result = uri+"";
    // DocumentProvider 
    //  if (isKitKat && DocumentsContract.isDocumentUri(context, uri))  
    if (isKitKat && (result.contains("media.documents"))) 
        String[] ary = result.split("/");
        int length = ary.length;
        String imgary = ary[length-1];
        final String[] dat = imgary.split("%3A");
        final String docId = dat[1];
        final String type = dat[0];
        Uri contentUri = null;
        if ("image".equals(type)) 
            contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
         else if ("video".equals(type)) 
         else if ("audio".equals(type)) 
         
        final String selection = "_id=?";
        final String[] selectionArgs = new String[] 
            dat[1]
        ; 
        return getDataColumn(context, contentUri, selection, selectionArgs);
     else if ("content".equalsIgnoreCase(uri.getScheme())) 
        return getDataColumn(context, uri, null, null);
     
    // File 
    else if ("file".equalsIgnoreCase(uri.getScheme())) 
        return uri.getPath();
     
    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; 
 

【讨论】:

【参考方案6】:

试试这个:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) 
            Uri selectedImage = data.getData();
            String[] filePathColumn =  MediaStore.Images.Media.DATA ;

            Cursor cursor = getContentResolver().query(selectedImage,filePathColumn, null, null, null);
            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String picturePath = cursor.getString(columnIndex);

            cursor.close();
            System.out.println("picturePath +"+ picturePath );  //path of sdcard

            
        

【讨论】:

【参考方案7】:

在这里我从 onActivityResult() 获取 uri

Uri selectedImageURI = data.getData();
String realPath = getRealPathFromURI(selectedImageURI);

1) 在片段中你可以像这样使用函数..

private String getRealPathFromURI(Uri contentURI) 
        String filePath;
        Cursor cursor = getActivity().getContentResolver().query(contentURI, null, null, null, null);
        if (cursor == null)  
            filePath = contentURI.getPath();
         else 
            cursor.moveToFirst();
            int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            filePath = cursor.getString(idx);
            cursor.close();
        
        return filePath;
    

2) 你可以使用这样的功能。

private String getRealPathFromURI(Uri contentURI) 
        String filePath;
        Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
        if (cursor == null)  
            filePath = contentURI.getPath();
         else 
            cursor.moveToFirst();
            int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            filePath = cursor.getString(idx);
            cursor.close();
        
        return filePath;
    

【讨论】:

【参考方案8】:

这里是如何通过 MediaStore 从 Uri 获取文件的真实路径::

private String getRealPathFromURI(Context context, Uri contentUri) 
    Cursor cursor = null;
    try 
        String[] proj =  MediaStore.Images.Media.DATA ;
        cursor = context.getContentResolver().query(contentUri,  proj, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
     catch (Exception e) 
        Log.e(TAG, "getRealPathFromURI Exception : " + e.toString());
        return "";
     finally 
        if (cursor != null) 
            cursor.close();
        
    

【讨论】:

这不适用于 Android 10 或更高版本,因为无法再访问 DATA。它在早期版本的 Android 上不可靠。 这是否适用于其他文件类型,例如音频?正如@CommonsWare 所说,DATA 已被弃用 MediaStore.Images.Media.DATA 已弃用【参考方案9】:

这样称呼

 Uri selectedImageURI = data.getData(); //where data is intent return by onActivityResult

imageFile = new File(getRealPathFromURI(selectedImageURI));

以及获取路径的代码..

private String getRealPathFromURI(Uri contentURI) 

    String result = null;

    Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);

    if (cursor == null) 
     // Source is Dropbox or other similar local file path
        result = contentURI.getPath();
    
    else 
     
        if(cursor.moveToFirst())
        
            int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
            result = cursor.getString(idx);
        
        cursor.close();
    
    return result;

【讨论】:

java.lang.IllegalStateException: 无法从 CursorWindow 读取第 0 行 col -1。确保在从光标访问数据之前正确初始化光标。【参考方案10】:

我找到了更优雅的解决方案:

Uri file_uri = Uri.parse(videoURI); // parse to Uri if your videoURI is string
String real_path = file_uri.getPath(); // will return real file path

【讨论】:

【参考方案11】:

对于 Kotlin 人来说,这段代码对我有用

fun getPath(context: Context, uri: Uri): String? 
    val isKitKatorAbove = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT

    // DocumentProvider
    if (isKitKatorAbove && DocumentsContract.isDocumentUri(context, uri)) 
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) 
            val docId = DocumentsContract.getDocumentId(uri)
            val split = docId.split(":".toRegex()).toTypedArray()
            val type = split[0]
            if ("primary".equals(type, ignoreCase = true)) 
                return Environment.getExternalStorageDirectory().toString() + "/" + split[1]
            

         else if (isDownloadsDocument(uri)) 
            val id = DocumentsContract.getDocumentId(uri)
            val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id))
            return getDataColumn(context, contentUri, null, null)
         else if (isMediaDocument(uri)) 
            val docId = DocumentsContract.getDocumentId(uri)
            val split = docId.split(":".toRegex()).toTypedArray()
            val type = split[0]
            var contentUri: Uri? = null
            if ("image" == type) 
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
             else if ("video" == type) 
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
             else if ("audio" == type) 
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
            
            val selection = "_id=?"
            val selectionArgs = arrayOf(split[1])
            return getDataColumn(context, contentUri, selection, selectionArgs)
        
     else if ("content".equals(uri.scheme, ignoreCase = true)) 
        return getDataColumn(context, uri, null, null)
     else if ("file".equals(uri.scheme, ignoreCase = true)) 
        return uri.path
    
    return null


fun getDataColumn(context: Context, uri: Uri?, selection: String?, selectionArgs: Array<String>?): String? 
    var cursor: Cursor? = null
    val column = "_data"
    val projection = arrayOf(column)
    try 
        cursor = context.getContentResolver().query(uri!!, projection, selection, selectionArgs,null)
        if (cursor != null && cursor.moveToFirst()) 
            val column_index: Int = cursor.getColumnIndexOrThrow(column)
            return cursor.getString(column_index)
        
     finally 
        if (cursor != null) cursor.close()
    
    return null


fun isExternalStorageDocument(uri: Uri): Boolean 
    return "com.android.externalstorage.documents" == uri.authority


fun isDownloadsDocument(uri: Uri): Boolean 
    return "com.android.providers.downloads.documents" == uri.authority


fun isMediaDocument(uri: Uri): Boolean 
    return "com.android.providers.media.documents" == uri.authority

您可以在 utils 类中添加这些方法

【讨论】:

【参考方案12】:

我试图解决这个问题 2/3 天,但我找到的所有可能的解决方案都没有帮助。我不断收到空游标和类似错误。

我需要文件路径的原因是为了获取 Exif 数据,以便我可以以正确的方向显示图像。 (见A final answer on how to get Exif data from URI)

我找到了这个开源项目-

https://github.com/ArthurHub/Android-Image-Cropper/blob/master/cropper/src/main/java/com/theartofdev/edmodo/cropper/BitmapUtils.java

有一种方法可以从 InputStream 中获取 Exif 数据,这解决了我的问题 -

ExifInterface ei = null;
try 

    InputStream is = context.getContentResolver().openInputStream(uri);
    if (is != null) 
    
        ei = new ExifInterface(is);
        is.close();
    
 
catch (Exception ignored) 


我知道这不是直接回答问题,但由于我通过尝试解决这个问题找到了这个帖子,我认为我的回答可能对其他人有所帮助。

【讨论】:

【参考方案13】:
package com.satya.filemangerdemo.common;

import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.List;

public class FileUtils 
    private static Uri contentUri = null;

    /**
     * Get a file path from a Uri. This will get the the path for Storage Access
     * Framework Documents, as well as the _data field for the MediaStore and
     * other file-based ContentProviders.<br>
     * <br>
     * Callers should check whether the path is local before assuming it
     * represents a local file.
     *
     * @param context The context.
     * @param uri     The Uri to query.
     */
    @SuppressLint("NewApi")
    public static String getPath(final Context context, final Uri uri) 
        // check here to KITKAT or new version
        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
        String selection = null;
        String[] selectionArgs = null;
        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) 
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) 
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                String fullPath = getPathFromExtSD(split);
                if (fullPath != "") 
                    return fullPath;
                 else 
                    return null;
                
            

            // DownloadsProvider
            else if (isDownloadsDocument(uri)) 
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
                    final String id;
                    Cursor cursor = null;
                    try 
                        cursor = context.getContentResolver().query(uri, new String[]MediaStore.MediaColumns.DISPLAY_NAME, null, null, null);
                        if (cursor != null && cursor.moveToFirst()) 
                            String fileName = cursor.getString(0);
                            String path = Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName;
                            if (!TextUtils.isEmpty(path)) 
                                return path;
                            
                        
                     finally 
                        if (cursor != null)
                            cursor.close();
                    
                    id = DocumentsContract.getDocumentId(uri);
                    if (!TextUtils.isEmpty(id)) 
                        if (id.startsWith("raw:")) 
                            return id.replaceFirst("raw:", "");
                        
                        String[] contentUriPrefixesToTry = new String[]
                                "content://downloads/public_downloads",
                                "content://downloads/my_downloads"
                        ;
                        for (String contentUriPrefix : contentUriPrefixesToTry) 
                            try 
                                final Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id));

                         /*   final Uri contentUri = ContentUris.withAppendedId(
                                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));*/

                                return getDataColumn(context, contentUri, null, null);
                             catch (NumberFormatException e) 
                                //In Android 8 and Android P the id is not a number
                                return uri.getPath().replaceFirst("^/document/raw:", "").replaceFirst("^raw:", "");
                            
                        


                    

                 else 
                    final String id = DocumentsContract.getDocumentId(uri);
                    final boolean isOreo = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
                    if (id.startsWith("raw:")) 
                        return id.replaceFirst("raw:", "");
                    
                    try 
                        contentUri = ContentUris.withAppendedId(
                                Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

                     catch (NumberFormatException e) 
                        e.printStackTrace();
                    
                    if (contentUri != null) 
                        return getDataColumn(context, contentUri, null, null);
                    
                


            
            // MediaProvider
            else if (isMediaDocument(uri)) 
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;

                if ("image".equals(type)) 
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                 else if ("video".equals(type)) 
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                 else if ("audio".equals(type)) 
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                
                selection = "_id=?";
                selectionArgs = new String[]split[1];


                return getDataColumn(context, contentUri, selection,
                        selectionArgs);
             else if (isGoogleDriveUri(uri)) 
                return getDriveFilePath(uri, context);
            
        


        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) 

            if (isGooglePhotosUri(uri)) 
                return uri.getLastPathSegment();
            

            if (isGoogleDriveUri(uri)) 
                return getDriveFilePath(uri, context);
            
            if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N) 
                // return getFilePathFromURI(context,uri);
                return getMediaFilePathForN(uri, context);
                // return getRealPathFromURI(context,uri);
             else 

                return getDataColumn(context, uri, null, null);
            


        
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) 
            return uri.getPath();
        

        return null;
    

    /**
     * Check if a file exists on device
     *
     * @param filePath The absolute file path
     */
    private static boolean fileExists(String filePath) 
        File file = new File(filePath);

        return file.exists();
    


    /**
     * Get full file path from external storage
     *
     * @param pathData The storage type and the relative path
     */
    private static String getPathFromExtSD(String[] pathData) 
        final String type = pathData[0];
        final String relativePath = "/" + pathData[1];
        String fullPath = "";

        // on my Sony devices (4.4.4 & 5.1.1), `type` is a dynamic string
        // something like "71F8-2C0A", some kind of unique id per storage
        // don't know any API that can get the root path of that storage based on its id.
        //
        // so no "primary" type, but let the check here for other devices
        if ("primary".equalsIgnoreCase(type)) 
            fullPath = Environment.getExternalStorageDirectory() + relativePath;
            if (fileExists(fullPath)) 
                return fullPath;
            
        

        // Environment.isExternalStorageRemovable() is `true` for external and internal storage
        // so we cannot relay on it.
        //
        // instead, for each possible path, check if file exists
        // we'll start with secondary storage as this could be our (physically) removable sd card
        fullPath = System.getenv("SECONDARY_STORAGE") + relativePath;
        if (fileExists(fullPath)) 
            return fullPath;
        

        fullPath = System.getenv("EXTERNAL_STORAGE") + relativePath;
        if (fileExists(fullPath)) 
            return fullPath;
        

        return fullPath;
    

    private static String getDriveFilePath(Uri uri, Context context) 
        Uri returnUri = uri;
        Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null);
        /*
         * Get the column indexes of the data in the Cursor,
         *     * move to the first row in the Cursor, get the data,
         *     * and display it.
         * */
        int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
        int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
        returnCursor.moveToFirst();
        String name = (returnCursor.getString(nameIndex));
        String size = (Long.toString(returnCursor.getLong(sizeIndex)));
        File file = new File(context.getCacheDir(), name);
        try 
            InputStream inputStream = context.getContentResolver().openInputStream(uri);
            FileOutputStream outputStream = new FileOutputStream(file);
            int read = 0;
            int maxBufferSize = 1 * 1024 * 1024;
            int bytesAvailable = inputStream.available();

            //int bufferSize = 1024;
            int bufferSize = Math.min(bytesAvailable, maxBufferSize);

            final byte[] buffers = new byte[bufferSize];
            while ((read = inputStream.read(buffers)) != -1) 
                outputStream.write(buffers, 0, read);
            
            Log.e("File Size", "Size " + file.length());
            inputStream.close();
            outputStream.close();
            Log.e("File Path", "Path " + file.getPath());
            Log.e("File Size", "Size " + file.length());
         catch (Exception e) 
            Log.e("Exception", e.getMessage());
        
        return file.getPath();
    

    private static String getMediaFilePathForN(Uri uri, Context context) 
        Uri returnUri = uri;
        Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null);
        /*
         * Get the column indexes of the data in the Cursor,
         *     * move to the first row in the Cursor, get the data,
         *     * and display it.
         * */
        int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
        int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
        returnCursor.moveToFirst();
        String name = (returnCursor.getString(nameIndex));
        String size = (Long.toString(returnCursor.getLong(sizeIndex)));
        File file = new File(context.getFilesDir(), name);
        try 
            InputStream inputStream = context.getContentResolver().openInputStream(uri);
            FileOutputStream outputStream = new FileOutputStream(file);
            int read = 0;
            int maxBufferSize = 1 * 1024 * 1024;
            int bytesAvailable = inputStream.available();

            //int bufferSize = 1024;
            int bufferSize = Math.min(bytesAvailable, maxBufferSize);

            final byte[] buffers = new byte[bufferSize];
            while ((read = inputStream.read(buffers)) != -1) 
                outputStream.write(buffers, 0, read);
            
            Log.e("File Size", "Size " + file.length());
            inputStream.close();
            outputStream.close();
            Log.e("File Path", "Path " + file.getPath());
            Log.e("File Size", "Size " + file.length());
         catch (Exception e) 
            Log.e("Exception", e.getMessage());
        
        return file.getPath();
    


    private 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 index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            
         finally 
            if (cursor != null)
                cursor.close();
        

        return null;
    

    /**
     * @param uri - The Uri to check.
     * @return - Whether the Uri authority is ExternalStorageProvider.
     */
    private static boolean isExternalStorageDocument(Uri uri) 
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    

    /**
     * @param uri - The Uri to check.
     * @return - Whether the Uri authority is DownloadsProvider.
     */
    private static boolean isDownloadsDocument(Uri uri) 
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    

    /**
     * @param uri - The Uri to check.
     * @return - Whether the Uri authority is MediaProvider.
     */
    private static boolean isMediaDocument(Uri uri) 
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    

    /**
     * @param uri - The Uri to check.
     * @return - Whether the Uri authority is Google Photos.
     */
    private static boolean isGooglePhotosUri(Uri uri) 
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    


    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Drive.
     */
    private static boolean isGoogleDriveUri(Uri uri) 
        return "com.google.android.apps.docs.storage".equals(uri.getAuthority()) || "com.google.android.apps.docs.storage.legacy".equals(uri.getAuthority());
    



【讨论】:

以上代码在 android 所有设备以及所有类型的文件路径都可以在内部和外部打开,谷歌驱动器,gallery 等。请注意,请记住在 android 清单中添加文件提供程序。 它在来自设备外部存储的文件的情况下提供 NPE,uriStringcontent://media/external/file...。我已经修复了它以获取 pdf 文档。【参考方案14】:

适用于 Android 的 Real Path Utility 类,适用于所有 API

import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import androidx.loader.content.CursorLoader;

public class RealPathUtil 

    public static String getRealPath(Context context, Uri fileUri) 
        String realPath;
        // SDK < API11
        if (Build.VERSION.SDK_INT < 11) 
            realPath = RealPathUtil.getRealPathFromURI_BelowAPI11(context, fileUri);
        
        // SDK >= 11 && SDK < 19
        else if (Build.VERSION.SDK_INT < 19) 
            realPath = RealPathUtil.getRealPathFromURI_API11to18(context, fileUri);
        
        // SDK > 19 (Android 4.4) and up
        else 
            realPath = RealPathUtil.getRealPathFromURI_API19(context, fileUri);
        
        return realPath;
    


    @SuppressLint("NewApi")
    public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) 
        String[] proj = MediaStore.Images.Media.DATA;
        String result = null;

        CursorLoader cursorLoader = new CursorLoader(context, contentUri, proj, null, null, null);
        Cursor cursor = cursorLoader.loadInBackground();

        if (cursor != null) 
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            result = cursor.getString(column_index);
            cursor.close();
        
        return result;
    

    public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri) 
        String[] proj = MediaStore.Images.Media.DATA;
        Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
        int column_index = 0;
        String result = "";
        if (cursor != null) 
            column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            result = cursor.getString(column_index);
            cursor.close();
            return result;
        
        return result;
    

    /**
     * Get a file path from a Uri. This will get the the path for Storage Access
     * Framework Documents, as well as the _data field for the MediaStore and
     * other file-based ContentProviders.
     *
     * @param context The context.
     * @param uri     The Uri to query.
     * @author paulburke
     */
    @SuppressLint("NewApi")
    public static String getRealPathFromURI_API19(final Context context, final Uri uri) 

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) 
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) 
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) 
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                

                // TODO handle non-primary volumes
            
            // DownloadsProvider
            else 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(context, contentUri, null, null);
            
            // MediaProvider
            else if (isMediaDocument(uri)) 
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) 
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                 else if ("video".equals(type)) 
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                 else if ("audio".equals(type)) 
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]
                        split[1]
                ;

                return getDataColumn(context, contentUri, selection, selectionArgs);
            
        
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) 

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) 
            return uri.getPath();
        

        return null;
    

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context       The context.
     * @param uri           The Uri to query.
     * @param selection     (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     */
    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 index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            
         finally 
            if (cursor != null)
                cursor.close();
        
        return null;
    


    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) 
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) 
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) 
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) 
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    


【讨论】:

您好,在我的情况下,它进入 isDownloadDocument 路径,但 _id 是 msf:24,而不是原始:& 不是数字。因此在使用 Long.valueOf 时会抛出错误,您能帮忙吗?【参考方案15】:

我在 Android 10 中遇到了同样的问题, 因为我的文件 URI 包含 msf: 格式。 大多数解决方案都说将文件复制到缓存路径中,然后使用该路径。

因此,这里是获取路径的解决方案,无需复制。

 if (isAndroid10 && id.startsWith("msf:")) 
     final String[] split = id.split(":");
     final String selection = "_id=?";
     final String[] selectionArgs = new String[]  split[1] ;
     return getDataColumn(context, MediaStore.Downloads.EXTERNAL_CONTENT_URI, selection, selectionArgs);

尝试实现这一点。

MediaStore.Downloads.EXTERNAL_CONTENT_URI -- ONLY PRESENT FROM ANDROID 10

【讨论】:

这行不通。 您好,由于我不是 Android 开发人员,这适用于我的应用程序。这就是我在此处发布此解决方案的原因。

以上是关于怎么获取android系统服务,如Uri,intent参数等,或者说去哪里查看的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中获取图像资源的uri

Android 通过uri获取文件路径path

获取 Uri Android 的真实路径

Android获取数据库图片uri路径并用imageView显示

Android获取本地相册图片拍照获取图片

android 中的uri到底是啥?