2016-02-19 54 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