【问题标题】:android getting local image path as https, how to get local phone path?android获取本地图像路径为https,如何获取本地电话路径?
【发布时间】:2015-12-26 18:33:44
【问题描述】:

我从图库中获取了用户选择的图像并希望在图像视图中显示它

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
        "Select Picture"), SELECT_PICTURE);

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        if (requestCode == SELECT_PICTURE) {
            Uri selectedImageUri = data.getData();
            selectedImagePath = getPath(selectedImageUri);

            imageView.setImageBitmap(BitmapFactory
                        .decodeFile(selectedImagePath));

            Log.i("SELECTED IMAGE: ", selectedImagePath);
        }
    }
}

/**
 * helper to retrieve the path of an image URI
 */
public String getPath(Uri uri) {
    // just some safety built in
    if( uri == null ) {
        // TODO perform some logging or show user feedback
        return null;
    }
    // try to retrieve the image from the media store first
    // this will only work for images selected from gallery
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    if( cursor != null ){
        int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

    // for other file managers
    return uri.getPath();
}

有些图片的路径为:/storage/sdcard0/WhatsApp/Media/WhatsApp Images/IMG-20150407-WA0013.jpg 可以正常显示

还有一些图片提供了谷歌下载链接的路径。示例:https://lh3.googleusercontent.com/-9VYhxxxmZs/VdQnxxxo5I/AAAAxxxCpM/4B3s-xxoeI/I/2015-08-08.jpg(出于隐私原因,帖子中的路径已更改)

这些图像不会显示。

我就是这样一种情况,

我将 Uri 作为 content://com.sec.android.gallery3d.provider/picasa/item/5913341278276321746

并且 selectedImagePath 为 https://lh3.googleusercontent.com/-9VYhxxxmZs/VdQnxxxo5I/AAAAxxxCpM/4B3s-xxoeI/I/2015-08-08.jpg

如何将这些图像的 selectedImagePath 获取为手机中的路径而不是 Web 位置?

【问题讨论】:

  • 您是否考虑使用第三方库,例如 Picasso (square.github.io/picasso) 或 Glide (github.com/bumptech/glide)?
  • @GuilhE 我认为它可以由android库本身处理
  • 你可以,但它需要更多的代码。使用其中一个库(通常我使用 Picasso),这样做非常简单快捷,并且您已经实现了缓存系统等。试一试;)
  • @GuilhE 我会尝试这样做,但现在如何在现有代码中完成?
  • @GuilhE 需要对现有代码进行哪些更改?

标签: android android-imageview android-image android-bitmap bitmapfactory


【解决方案1】:

我解决了这个问题:

Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");

startActivityForResult(Intent.createChooser(intent,
        "Share Photo"), SELECT_PICTURE);


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        if (requestCode == SELECT_PICTURE) {
            Uri selectedImageUri = data.getData();
            String selectedImagePath = getPath(selectedImageUri);  

            selectedImageUri = selectedImageUri .replace("com.android.gallery3d","com.google.android.gallery3d");

            if (selectedImageUri .startsWith("content://com.google.android.gallery3d")
                || selectedImageUri .startsWith("content://com.sec.android.gallery3d.provider") ) {

                selectedImagePath = PicasaImage(selectedImageUri);
            }
            else
                selectedImagePath = getPath(selectedImageUri);
            }

            imageView.setImageBitmap(BitmapFactory
                            .decodeFile(selectedImagePath));

            Log.i("SELECTED IMAGE PATH: ", selectedImagePath);
    }
}

private String PicasaImage(Uri imageUri) {

    File cacheDir;
    // if the device has an SD card
    if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
        cacheDir = new File(android.os.Environment.getExternalStorageDirectory(),".OCFL311");
    } else {
        // it does not have an SD card
        cacheDir = getCacheDir();
    }

    if(!cacheDir.exists()) cacheDir.mkdirs();

    File f = new File(cacheDir, "tempPicasa");

    try {

        InputStream is = null;
        if (imageUri.toString().startsWith("content://com.google.android.gallery3d")
                || imageUri.toString().startsWith("content://com.sec.android.gallery3d.provider")) {

            is = getContentResolver().openInputStream(imageUri);
        } else {
            is = new URL(imageUri.toString()).openStream();
        }

        OutputStream os = new FileOutputStream(f);

        //Utils.InputToOutputStream(is, os);

        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }

        return f.getAbsolutePath();
    } catch (Exception ex) {
        Log.i(this.getClass().getName(), "Exception: " + ex.getMessage());
        // something went wrong
        ex.printStackTrace();
        return null;
    }
}

public String getPath(Uri uri) {
    // just some safety built in
    if( uri == null ) {
        // TODO perform some logging or show user feedback
        return null;
    }
    // try to retrieve the image from the media store first
    // this will only work for images selected from gallery
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    if( cursor != null ){
        int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

    // for other file managers
    return uri.getPath();
}

【讨论】:

    【解决方案2】:

    正如我在 cmets 中所说,您应该使用 Picasso 或 Glide 等库,因为在它们的实现中解决了许多角落案例,例如缓存系统、网络故障处理、图像效果和转换、内存性能等。

    如果您想以更简单的方式“手动”执行此操作,则应考虑以下事项:

    private class NetworkImageAsyncTask extends AsyncTask<String, Void, Bitmap> {
        @Override
        protected Void doInBackground(String... params) {
           try {
                InputStream in = new URL(params[0]).openStream();
                bitmap = BitmapFactory.decodeStream(in);
            } catch (Exception e) {
                return null;
            }
           return bitmap;
        }
    
        @Override
        protected void onPostExecute(Bitmap result) {
             if (result != null)
                  mImageView.setImageBitmap(result);
             }
        }
    }
    

    只需致电:new NetworkImageAsyncTask("url").execute();
    你应该使用AsyncTask,因为这个“网络方法”不应该在主线程中完成。

    注意:此解决方案不包括内存泄漏安全代码,它只是一个示例方法

    编辑(cmets 回复)
    试试这个:

    Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    intent.setType("image/jpg");
    

    ...

    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
    cursor.moveToFirst();
    String path = cursor.getString(cursor.getColumnIndex(projection[0]));
    cursor.close();
    return path;
    

    【讨论】:

    • Google 云照片(来自照片应用程序)显示在图库中,而不是在手机中。检查您的路径是否类似于:“content://com.google.android....”
    【解决方案3】:

    试试这个下载位图:

    URL url = new URL(sUrl);
    HttpURLConnection connection  = (HttpURLConnection) url.openConnection();
    
    InputStream is = connection.getInputStream();
    Bitmap img = BitmapFactory.decodeStream(is);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-26
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      • 2020-09-06
      • 2018-04-24
      • 1970-01-01
      相关资源
      最近更新 更多