2016-02-19 85 views
1

我正在处理应用程序,其中用户可以拍摄照片并将其放入recyclerview networkImageview,如下所示。我正在拍照,但这张照片没有分配给networkImage。未找到拍摄的图像,FileNotFoundException

下面一行抛出一个异常

InputStream is = context.getContentResolver().openInputStream(uri); 

java.io.FileNotFoundException:没有内容提供商: /storage/emulated/0/Pictures/JPEG_20160219_113457_-713510024.jpg

MainActivity类

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

    if (requestCode == 100 && resultCode == Activity.RESULT_OK) { 
     String path = ImageUtil.camPicturePath; 
     mCurrentItem.setPath(path); 
     mAdapter.notifyDataSetChanged(); 
     mCurrentItem = null; 
     mCurrentPosition = -1; 
    } 
} 

RecylerViewAdapter

@Override 
    public void onBindViewHolder(final ListViewHolder holder, int position) { 
     PostProductImageLIst item = mItems.get(position); 
     ImageUtil.getInstance().setSelectedPic(holder.imgViewIcon, item.getPath()); 
    } 

ImageUtilClass

public static String camPicturePath; 

public static void captureImage(Activity activity) { 
     File photoFile = null; 
     Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
     // Ensure that there's a camera activity to handle the intent 
     if (takePictureIntent.resolveActivity(activity.getPackageManager()) != null) { 
      // Create the File where the photo should go 
      try { 
       photoFile = createImageFile(); 
      } catch (IOException ex) { 
       // Error occurred while creating the File 
       ex.printStackTrace(); 
      } 
      // Continue only if the File was successfully created 
      if (photoFile != null) { 
       takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, 
         Uri.fromFile(photoFile)); 
       activity.startActivityForResult(takePictureIntent, 100); 
      } 
     } 
     camPicturePath = (photoFile != null) ? photoFile.getAbsolutePath() : null; 
    } 


private LruCache<String, Bitmap> mMemoryCache; 

public void setSelectedPic(CustomNetworkImageView view, String url) { 
    Context context = view.getContext(); 
    if (!TextUtils.isEmpty(url)) { 
     if (url.startsWith("http")) { 
      view.setImageUrl(url, CustomVolleyRequest.getInstance(context).getImageLoader()); 
     } else { 
      try { 
       Uri uri = Uri.parse(url); 
       Bitmap bitmap = mMemoryCache.get(url); 
       if (bitmap == null) { 
        InputStream is = context.getContentResolver().openInputStream(uri); 
        bitmap = BitmapFactory.decodeStream(is); 
        Bitmap scaled = ImageUtil.getInstance().scaleBitmap(bitmap); 
        mMemoryCache.put(url, scaled); 
        if (is!=null) { 
         is.close(); 
        } 
       } 
       view.setLocalImageBitmap(bitmap); 
      } catch (Exception ex) { 
       Log.e("Image", ex.getMessage(), ex); 
      } 
     } 
    } else { 
     view.setImageUrl("", CustomVolleyRequest.getInstance(view.getContext()).getImageLoader()); 
    } 
} 
public Bitmap scaleBitmap(Bitmap bitmap) { 
    int width = WIDTH; 
    int height = (WIDTH * bitmap.getHeight())/bitmap.getWidth(); 
    return Bitmap.createScaledBitmap(bitmap, width, height, false); 
} 
+0

首先,重要的是要考虑'onActivityResult'的实现方式与从相机拍摄的照片以及从照片库拍摄照片的情况下不同。对于Android 6设备(如果您的目标是API 23),还要小心权限管理。从相机拍照意味着你需要存储它。如果您不明确处理权限,则总是会得到“权限被拒绝”。 – thetonrifles

回答

2

你需要从两个摄像头和画廊拍照时要小心。首先你需要妥善处理Intent来拍照。下面我报告了构建它的一个可能的实现。

如果您需要同时从相机和画廊获取照片。

public Intent buildPicturePickerIntent(PackageManager packageManager) { 
    // Camera 
    final List<Intent> cameraIntents = new ArrayList<>(); 
    final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
    final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0); 
    for (ResolveInfo res : listCam) { 
     final String packageName = res.activityInfo.packageName; 
     final Intent intent = new Intent(captureIntent); 
     intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name)); 
     intent.setPackage(packageName); 
     cameraIntents.add(intent); 
    } 
    // Filesystem 
    final Intent galleryIntent = new Intent(); 
    galleryIntent.setType("image/*"); 
    galleryIntent.setAction(Intent.ACTION_GET_CONTENT); 
    // Chooser of filesystem options 
    final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source"); 
    // Add the camera options 
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, 
      cameraIntents.toArray(new Parcelable[cameraIntents.size()])); 
    // returning intent 
    return chooserIntent; 
} 

什么重要的是,实施onActivityResult必须处理来自相机和照片库以不同的方式拍摄合影留念。下面你可以看到示例代码:

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    if (requestCode == PICK_IMAGE_CODE && resultCode == RESULT_OK) { 
     Uri uri = data.getData(); 
     // photo from gallery? 
     if (uri != null) { 
      // yes, photo from gallery 
      String path = uri.toString(); 
      // use path here 
      // ... 
     } else { 
      // no, photo from camera 
      Bitmap photo = (Bitmap) data.getExtras().get("data"); 
      // store bitmap (eventually scaling it before) 
      // in filesystem here and get absolute path 
      // ...     
     } 
     // do your common work here (e.g. notify UI) 
    } 
} 

要小心在文件系统上存储位图两件事情:

  • 当存储新位图,你将拥有绝对路径。当然,您可以使用它,但是如果您想以相同的方式管理来自相机的照片和来自相册的照片,则需要进行从绝对路径到内容URI的转换。你可以在这里找到很多关于这个问题的答案。
  • 如果您的目标是API 23,则需要明确处理存储权限。否则,当您尝试在存储器上保存从Android 6设备上的相机拍摄的位图时,您将收到“权限被拒绝”错误。

Here你可以找到示例代码从画廊/相应的摄像头和更新回收视图项采摘图像。

2

似乎要传递URI,而非网址。

InputStream is = (InputStream) new URL(encodedurl).getContent(); 
      Bitmap d = BitmapFactory.decodeStream(is); 

Android BitmapFactory.decodeStream(...) doesn't load HTTPS URL on emulator

File file = new File(url); 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
      o.inJustDecodeBounds = true; 
      FileInputStream fis = new FileInputStream(f); 
      Bitmap b= BitmapFactory.decodeStream(fis, null, o); 
      fis.close(); 


public void showCamera() { 
    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); 
    File photo = new File(Environment.getExternalStorageDirectory(), 
      Calendar.getInstance().getTimeInMillis() + ".jpg"); 
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo)); 
    imageUri = Uri.fromFile(photo); 
    startActivityForResult(intent, CAMERA_INTENT_CALLED); 
} 

if (requestCode == CAMERA_INTENT_CALLED) { 

       Uri selectedImage = imageUri; 
       try { 
        if (selectedImage != null) { 
         getContentResolver().notifyChange(selectedImage, null); 
         String path = getRealPathFromURI(selectedImage); 
         Log.e("Imagepath Camera", path); 
         imageUri = null; 
        } 
      } catch (Exception e) { 

       Log.e("Camera", e.toString()); 

      } 

     } 

private String getRealPathFromURI(Uri contentURI) { 
    Cursor cursor = getContentResolver().query(contentURI, null, null, 
      null, null); 
    if (cursor == null) { // Source is Dropbox or other similar local file 
          // path 
     return contentURI.getPath(); 
    } else { 
     cursor.moveToFirst(); 
     int idx = cursor 
       .getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
     return cursor.getString(idx); 
    } 
} 
+0

什么是o和文件?文件是uri吗? – casillas

+0

对不起,我以为你正在从文件加载图像。更新。 –

+0

我想知道如何处理这个代码从图库中选择图像并拍摄图像。我发布的代码是为了从图库中选取图像而完成的,如果我将当前代码更改为InputStream,它可能无法用于图库图像选择。 – casillas