Android 从另一个应用程序获取路径(WhatsApp)

Android 从另一个应用程序获取路径(WhatsApp),android,path,uri,whatsapp,Android,Path,Uri,Whatsapp,我没有从我从whatsApp收到的uri中获取图像或视频的路径 Uri如下所示:content://com.whatsapp.provider.media/item/16695 媒体来自画廊,下载和其他都可以 有人知道怎么走这条路吗?这是我正在使用的代码: public String getMediaPath(Context context, Uri uri) { if (DEBUG) Log.d(TAG + " File -", "Au

我没有从我从whatsApp收到的uri中获取图像或视频的路径

Uri如下所示:content://com.whatsapp.provider.media/item/16695

媒体来自画廊,下载和其他都可以

有人知道怎么走这条路吗?这是我正在使用的代码:

public String getMediaPath(Context context, Uri uri) {

    if (DEBUG)
        Log.d(TAG + " File -",
                "Authority: " + uri.getAuthority() +
                        ", Fragment: " + uri.getFragment() +
                        ", Port: " + uri.getPort() +
                        ", Query: " + uri.getQuery() +
                        ", Scheme: " + uri.getScheme() +
                        ", Host: " + uri.getHost() +
                        ", Segments: " + uri.getPathSegments().toString()
        );

    // DocumentProvider
    if (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];
            }


        }
        // 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 String getDataColumn(Context context, Uri uri, String selection,
                            String[] selectionArgs) {

    Cursor cursor = null;
    final String[] column = { MediaStore.Images.Media.DATA };
    final String[] projection = {
            column[0]
    };

    try {
        cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                null);
        if (cursor != null && cursor.moveToFirst()) {
            if (DEBUG)
                DatabaseUtils.dumpCursor(cursor);

            final int index = cursor.getColumnIndexOrThrow(column[0]);
            return cursor.getString(index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}

public static boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri.getAuthority());
}

public static boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

public static boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri.getAuthority());
}

public static boolean isGooglePhotosUri(Uri uri) {
    return "com.google.android.apps.photos.contentprovider".equals(uri.getAuthority());
}
此日志的结果:

    if (DEBUG)
    Log.d(TAG + " File -",
            "Authority: " + uri.getAuthority() +
                    ", Fragment: " + uri.getFragment() +
                    ", Port: " + uri.getPort() +
                    ", Query: " + uri.getQuery() +
                    ", Scheme: " + uri.getScheme() +
                    ", Host: " + uri.getHost() +
                    ", Segments: " + uri.getPathSegments().toString()
    );
这是:

Authority: com.whatsapp.provider.media, Fragment: null, Port: -1, Query: null, Scheme: content, Host: com.whatsapp.provider.media, Segments: [item, 16348]
getDataColumn上的光标如下所示:

>>>>> Dumping cursor 
android.content.ContentResolver$CursorWrapperInner@1fc81ac
I/System.out: 0 {
I/System.out: }
I/System.out: <<<<<
>>>>>>转储光标
android.content.ContentResolver$CursorWrapperInner@1fc81ac
I/System.out:0{
I/System.out:}

I/System.out:您可以尝试这样做,然后获得所选图像的位图,然后您可以从设备默认库轻松找到它的本机路径

Bitmap roughBitmap= null;
    try {
    // Works with content://, file://, or android.resource:// URIs
    InputStream inputStream =
    getContentResolver().openInputStream(uri);
    roughBitmap= BitmapFactory.decodeStream(inputStream);

    // calc exact destination size
    Matrix m = new Matrix();
    RectF inRect = new RectF(0, 0, roughBitmap.Width, roughBitmap.Height);
    RectF outRect = new RectF(0, 0, dstWidth, dstHeight);
    m.SetRectToRect(inRect, outRect, Matrix.ScaleToFit.Center);
    float[] values = new float[9];
    m.GetValues(values);


    // resize bitmap if needed
    Bitmap resizedBitmap = Bitmap.CreateScaledBitmap(roughBitmap, (int) (roughBitmap.Width * values[0]), (int) (roughBitmap.Height * values[4]), true);

    string name = "IMG_" + new Java.Text.SimpleDateFormat("yyyyMMdd_HHmmss").Format(new Java.Util.Date()) + ".png";
    var sdCardPath= Environment.GetExternalStoragePublicDirectory("DCIM").AbsolutePath;
    Java.IO.File file = new Java.IO.File(sdCardPath);
    if (!file.Exists())
    {
        file.Mkdir();
    }
    var filePath = System.IO.Path.Combine(sdCardPath, name);
    } catch (FileNotFoundException e) {
    // Inform the user that things have gone horribly wrong
    }

您无法从WhatsApp获取文件的路径。他们现在不暴露它。您只能得到
InputStream

InputStream is = getContentResolver().openInputStream(Uri.parse("content://com.whatsapp.provider.media/item/16695"));

使用
is
可以在应用程序中显示WhatsApp中的图片。

如果要将照片上载到服务器,还可以将URI转换为文件,然后再转换为字节。

退房:


使用下面的代码示例将返回位图:

BitmapFactory.decodeStream(getContentResolver().openInputStream(Uri.parse("content://com.whatsapp.provider.media/item/128752")))

在那之后,你们都知道你们必须做什么。

打开小文本文件对我来说很有用。。。我没有在其他文件中尝试

protected void viewhelper(Intent intent) {
    Uri a = intent.getData();
    if (!a.toString().startsWith("content:")) {
        return;
    }
    //Ok Let's do it
    String content = readUri(a);
    //do something with this content
}
下面是readUri(Uri)方法

我从这个存储库中获得了它
我修改了一些代码以使其正常工作

清单文件:

    <activity android:name=".MainActivity">
        <intent-filter >
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="*/*" />
        </intent-filter>
    </activity>

您可以尝试此方法,它将对您有所帮助。您无法直接从WhatsApp获取路径。如果您需要文件路径,请先复制文件并发送新的文件路径。 使用下面的代码

 public static String getFilePathFromURI(Context context, Uri contentUri) {
    String fileName = getFileName(contentUri);
    if (!TextUtils.isEmpty(fileName)) {
        File copyFile = new File(TEMP_DIR_PATH  + fileName+".jpg");
        copy(context, contentUri, copyFile);
        return copyFile.getAbsolutePath();
    }
    return null;
}

public static String getFileName(Uri uri) {
    if (uri == null) return null;
    String fileName = null;
    String path = uri.getPath();
    int cut = path.lastIndexOf('/');
    if (cut != -1) {
        fileName = path.substring(cut + 1);
    }
    return fileName;
}

public static void copy(Context context, Uri srcUri, File dstFile) {
    try {
        InputStream inputStream = context.getContentResolver().openInputStream(srcUri);
        if (inputStream == null) return;
        OutputStream outputStream = new FileOutputStream(dstFile);
        IOUtils.copy(inputStream, outputStream);
        inputStream.close();
        outputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
然后IOUtils类如下所示

public class IOUtils {



private static final int BUFFER_SIZE = 1024 * 2;

private IOUtils() {
    // Utility class.
}

public static int copy(InputStream input, OutputStream output) throws Exception, IOException {
    byte[] buffer = new byte[BUFFER_SIZE];

    BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE);
    BufferedOutputStream out = new BufferedOutputStream(output, BUFFER_SIZE);
    int count = 0, n = 0;
    try {
        while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
            out.write(buffer, 0, n);
            count += n;
        }
        out.flush();
    } finally {
        try {
            out.close();
        } catch (IOException e) {
            Log.e(e.getMessage(), e.toString());
        }
        try {
            in.close();
        } catch (IOException e) {
            Log.e(e.getMessage(), e.toString());
        }
    }
    return count;
}


}
创建时受保护的void(Bundle savedInstanceState){ /* *你的OnCreate */ Intent=getIntent(); String action=intent.getAction(); 字符串类型=intent.getType()


我得到了位图,但是我怎样才能得到路径表呢it@EduardoBonfa,在获得位图后,您可以将其转换为文件并获取该文件的路径。我被编辑回答这适用于图像,是否也适用于其他媒体?这不起作用。
getContentResolver().openInputStream(uri);
引发异常。请检查问题。@Atul,哪种类型的异常引发?这不起作用。
OpenInputStream
引发异常。请检查问题。我已经在我的LG手写笔3(Android 7.0)上检查了这一点这就解决了问题。你在手机上试过了吗?在棉花糖上试过了。请注意,自从WhatsApp推出最新的更新版本以来,出现了这个异常。以前它工作正常(我认为他们只是在共享图像文件路径
文件://
)但是现在他们使用
内容进行共享://
我不确定WhatsApp的最新版本,但我检查了Uri是否有一个scheme
内容
——它是一个
”content://com.whatsapp.provider.media/item/xxxxx"
。我会在棉花糖上检查它。好的,我发现了问题。我们需要从初始活动本身调用
openInputStream
,该活动在我们共享WhatsApp的图像后启动。我在初始活动中存储URI,并从另一个活动调用
openInputStream
。这会引发异常。您能描述一下原因吗这段代码是解决方案,而不是仅仅发布代码?问题是从Uri获取文件路径,而不是将文件路径转换为Uri
 public static String getFilePathFromURI(Context context, Uri contentUri) {
    String fileName = getFileName(contentUri);
    if (!TextUtils.isEmpty(fileName)) {
        File copyFile = new File(TEMP_DIR_PATH  + fileName+".jpg");
        copy(context, contentUri, copyFile);
        return copyFile.getAbsolutePath();
    }
    return null;
}

public static String getFileName(Uri uri) {
    if (uri == null) return null;
    String fileName = null;
    String path = uri.getPath();
    int cut = path.lastIndexOf('/');
    if (cut != -1) {
        fileName = path.substring(cut + 1);
    }
    return fileName;
}

public static void copy(Context context, Uri srcUri, File dstFile) {
    try {
        InputStream inputStream = context.getContentResolver().openInputStream(srcUri);
        if (inputStream == null) return;
        OutputStream outputStream = new FileOutputStream(dstFile);
        IOUtils.copy(inputStream, outputStream);
        inputStream.close();
        outputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public class IOUtils {



private static final int BUFFER_SIZE = 1024 * 2;

private IOUtils() {
    // Utility class.
}

public static int copy(InputStream input, OutputStream output) throws Exception, IOException {
    byte[] buffer = new byte[BUFFER_SIZE];

    BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE);
    BufferedOutputStream out = new BufferedOutputStream(output, BUFFER_SIZE);
    int count = 0, n = 0;
    try {
        while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
            out.write(buffer, 0, n);
            count += n;
        }
        out.flush();
    } finally {
        try {
            out.close();
        } catch (IOException e) {
            Log.e(e.getMessage(), e.toString());
        }
        try {
            in.close();
        } catch (IOException e) {
            Log.e(e.getMessage(), e.toString());
        }
    }
    return count;
}


}
//VIEW"
if (Intent.ACTION_VIEW.equals(action) && type != null) {viewhekper(intent);//Handle text being sent}