2016-09-04 59 views
9

從圖庫和相機中挑選圖像,它在Android 7.0以下完成,但是在Android中沒有它在相機中崩潰。我使用fileprovider但不起作用。如何在Android 7.0中從照相機或圖庫中爲作物選擇圖像?

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener { 

private Button mBtn; 
private Context context; 
private static final int SELECT_PICTURE_CAMARA = 101, SELECT_PICTURE = 201, CROP_IMAGE = 301; 
private Uri outputFileUri; 
String mCurrentPhotoPath; 
private Uri selectedImageUri; 
private File finalFile = null; 
private ImageView imageView; 
private PermissionUtil permissionUtil; 
Uri fileUri; 
File file = null; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    mBtn = (Button) findViewById(R.id.btn_img); 
    imageView = (ImageView) findViewById(R.id.img_photo); 
    permissionUtil = new PermissionUtil(); 
    mBtn.setOnClickListener(this); 
    context = this; 
} 

@Override 
public void onClick(View view) { 
    selectImageOption(); 
} 

private void selectImageOption() { 
    final CharSequence[] items = {"Capture Photo", "Choose from Gallery", "Cancel"}; 

    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); 
    builder.setTitle("Add Photo!"); 
    builder.setItems(items, new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int item) { 
      if (items[item].equals("Capture Photo")) { 
       if (permissionUtil.checkMarshMellowPermission()) { 
        if (permissionUtil.verifyPermissions(MainActivity.this, permissionUtil.getCameraPermissions())) 
         onClickCamera(); 
        else 
         ActivityCompat.requestPermissions(MainActivity.this, permissionUtil.getCameraPermissions(), SELECT_PICTURE_CAMARA); 
       } else 
        onClickCamera(); 
      } else if (items[item].equals("Choose from Gallery")) { 
       if (permissionUtil.checkMarshMellowPermission()) { 
        if (permissionUtil.verifyPermissions(MainActivity.this, permissionUtil.getGalleryPermissions())) 
         onClickGallery(); 
        else 
         ActivityCompat.requestPermissions(MainActivity.this, permissionUtil.getGalleryPermissions(), SELECT_PICTURE); 
       } else 
        onClickGallery(); 
      } else if (items[item].equals("Cancel")) { 
       dialog.dismiss(); 
      } 
     } 
    }); 
    builder.show(); 
} 

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

    if (resultCode == RESULT_OK) { 
     if (requestCode == SELECT_PICTURE) { 
      selectedImageUri = data.getData(); 
      cropImage(selectedImageUri); 

     } else if (requestCode == CROP_IMAGE) { 

      Uri imageUri = Uri.parse(mCurrentPhotoPath); 
      File file = new File(imageUri.getPath()); 
      try { 
       InputStream ims = new FileInputStream(file); 
       imageView.setImageBitmap(BitmapFactory.decodeStream(ims)); 
      } catch (FileNotFoundException e) { 
       return; 
      } 

     } else if (requestCode == SELECT_PICTURE_CAMARA && resultCode == Activity.RESULT_OK) { 
      cropImage1(); 
     } 
    } 
} 

private void onClickCamera() { 
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 

    if (takePictureIntent.resolveActivity(context.getPackageManager()) != null) { 
     /* File photoFile = null; 
     try { 
      photoFile = createImageFile(); 
     } catch (IOException ex) { 
     } 
     if (photoFile != null) { 

      Uri photoURI; 
      if (Build.VERSION.SDK_INT >= 24) { 
       photoURI = FileProvider.getUriForFile(MainActivity.this, 
         BuildConfig.APPLICATION_ID + ".fileprovider", photoFile); 
      } else { 
       photoURI = Uri.fromFile(photoFile); 
      } 
      takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); 
      startActivityForResult(takePictureIntent, SELECT_PICTURE_CAMARA); 

     }*/ 

     ContentValues values = new ContentValues(1); 
     values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpg"); 
     fileUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); 
     takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); 
     takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 
     startActivityForResult(takePictureIntent, SELECT_PICTURE_CAMARA); 

    } else { 
     Toast.makeText(this, getString(R.string.error_no_camera), Toast.LENGTH_LONG).show(); 
    } 
} 

private void onClickGallery() { 
    List<Intent> targets = new ArrayList<>(); 
    Intent intent = new Intent(); 
    intent.setType("image/*"); 
    intent.setAction(Intent.ACTION_PICK); 
    intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true); 
    List<ResolveInfo> candidates = getApplicationContext().getPackageManager().queryIntentActivities(intent, 0); 

    for (ResolveInfo candidate : candidates) { 
     String packageName = candidate.activityInfo.packageName; 
     if (!packageName.equals("com.google.android.apps.photos") && !packageName.equals("com.google.android.apps.plus") && !packageName.equals("com.android.documentsui")) { 
      Intent iWantThis = new Intent(); 
      iWantThis.setType("image/*"); 
      iWantThis.setAction(Intent.ACTION_PICK); 
      iWantThis.putExtra(Intent.EXTRA_LOCAL_ONLY, true); 
      iWantThis.setPackage(packageName); 
      targets.add(iWantThis); 
     } 
    } 
    if (targets.size() > 0) { 
     Intent chooser = Intent.createChooser(targets.remove(0), "Select Picture"); 
     chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targets.toArray(new Parcelable[targets.size()])); 
     startActivityForResult(chooser, SELECT_PICTURE); 
    } else { 
     Intent intent1 = new Intent(Intent.ACTION_PICK); 
     intent1.setType("image/*"); 
     startActivityForResult(Intent.createChooser(intent1, "Select Picture"), SELECT_PICTURE); 
    } 
} 

private File createImageFile() throws IOException { 
    // Create an image file name 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    String imageFileName = "JPEG_" + timeStamp + "_"; 

    File storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES); 
    File image = File.createTempFile(
      imageFileName, /* prefix */ 
      ".jpg",   /* suffix */ 
      storageDir  /* directory */ 
    ); 

    // Save a file: path for use with ACTION_VIEW intents 
    if (Build.VERSION.SDK_INT >= 24) { 
     mCurrentPhotoPath = String.valueOf(FileProvider.getUriForFile(MainActivity.this, 
       BuildConfig.APPLICATION_ID + ".provider", image)); 
    } else { 
     mCurrentPhotoPath = String.valueOf(Uri.fromFile(image)); 
    } 

    return image; 
} 

/*private Uri createImageUri(){ 
    ContentResolver contentResolver=getContentResolver(); 
    ContentValues cv=new ContentValues(); 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    cv.put(MediaStore.Images.Media.TITLE,timeStamp); 
    return contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,cv); 
}*/ 

private void cropImage(Uri selectedImageUri) { 
    Intent cropIntent = new Intent("com.android.camera.action.CROP"); 
    cropIntent.setDataAndType(selectedImageUri, "image/*"); 
    cropIntent.putExtra("crop", "true"); 
    cropIntent.putExtra("aspectX", 1); 
    cropIntent.putExtra("aspectY", 1.5); 
    cropIntent.putExtra("return-data", true); 

    outputFileUri = Uri.fromFile(createCropFile()); 
    cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); 
    startActivityForResult(cropIntent, CROP_IMAGE); 
} 

private void cropImage1() { 
    Intent cropIntent = new Intent("com.android.camera.action.CROP"); 
    cropIntent.setDataAndType(fileUri, "image/*"); 
    cropIntent.putExtra("crop", "true"); 
    cropIntent.putExtra("aspectX", 1); 
    cropIntent.putExtra("aspectY", 1.5); 
    cropIntent.putExtra("return-data", true); 

    if (Build.VERSION.SDK_INT >= 24) { 
     outputFileUri = FileProvider.getUriForFile(MainActivity.this, 
       BuildConfig.APPLICATION_ID + ".provider", createCropFile()); 

    } else 
     outputFileUri = Uri.fromFile(createCropFile()); 

    cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); 
    startActivityForResult(cropIntent, CROP_IMAGE); 

    /* ContentValues values = new ContentValues(1); 
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpg"); 
    outputFileUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); 
    cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); 
    cropIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 
    cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); 
    startActivityForResult(cropIntent, CROP_IMAGE);*/ 
} 

private File createCropFile() { 
    File storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES); 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    // path = path + (timeStamp + "1jpg"); 

    try { 
     file = File.createTempFile(timeStamp, ".jpg", storageDir); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    /*if (Build.VERSION.SDK_INT >= 24) 
     mCurrentPhotoPath = String.valueOf(FileProvider.getUriForFile(MainActivity.this, 
       BuildConfig.APPLICATION_ID + ".provider", file)); 
    else*/ 
    mCurrentPhotoPath = String.valueOf(Uri.fromFile(file)); 
    return file; 
} 
} 

這項工作中的所有設備,但是不能在> = 7.0的Android設備化爲烏有

+0

您能否提供logcat和[mcve]? –

+1

請不要轉發問題。您可以編輯前一頁以將其撞到首頁 –

+0

即使您沒有轉貼,也沒有足夠的信息來幫助您。另一個問題是好得多 –

回答

7

我得到了解決方案。發佈我的答案。

在MainActivity.java

public class MainActivity extends AppCompatActivity { 

@BindView(R.id.img_camera) 
CircleImageView mImgCamera; 

private ChoosePhoto choosePhoto=null; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    ButterKnife.bind(this); 
} 

@OnClick(R.id.img_camera) 
public void onViewClicked() { 
    choosePhoto = new ChoosePhoto(this); 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    if (resultCode == Activity.RESULT_OK) { 
     if (requestCode == ChoosePhoto.CHOOSE_PHOTO_INTENT) { 
      if (data != null && data.getData() != null) { 
       choosePhoto.handleGalleryResult(data); 
      } else { 
       choosePhoto.handleCameraResult(choosePhoto.getCameraUri()); 
      } 
     }else if (requestCode == ChoosePhoto.SELECTED_IMG_CROP) { 
      mImgCamera.setImageURI(choosePhoto.getCropImageUrl()); 
     } 
    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
    super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
    if (requestCode == ChoosePhoto.SELECT_PICTURE_CAMERA) { 
     if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) 
      choosePhoto.showAlertDialog(); 
    } 
} 
} 

ChoosePhoto.java

public class ChoosePhoto { 

public static int CHOOSE_PHOTO_INTENT = 101; 
public static int SELECTED_IMG_CROP = 102; 
public static int SELECT_PICTURE_CAMERA = 103; 
public static int currentAndroidDeviceVersion = Build.VERSION.SDK_INT; 

private int ASPECT_X = 1; 
private int ASPECT_Y = 1; 
private int OUT_PUT_X = 300; 
private int OUT_PUT_Y = 300; 
private boolean SCALE = true; 

private Uri cropPictureUrl, selectedImageUri = null, cameraUrl = null; 
private Context mContext; 

public ChoosePhoto(Context context) { 
    mContext = context; 
    init(); 
} 

private void init() { 
    PermissionUtil permissionUtil = new PermissionUtil(); 

    if (permissionUtil.checkMarshMellowPermission()) { 
     if (permissionUtil.verifyPermissions(mContext, permissionUtil.getCameraPermissions()) && permissionUtil.verifyPermissions(mContext, permissionUtil.getGalleryPermissions())) 
      showAlertDialog(); 
     else { 
      ActivityCompat.requestPermissions((Activity) mContext, permissionUtil.getCameraPermissions(), SELECT_PICTURE_CAMERA); 
     } 
    } else { 
     showAlertDialog(); 
    } 
} 

public void showAlertDialog() { 
    final Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 
    galleryIntent.setType("image/*"); 

    cameraUrl = FileUtil.getInstance(mContext).createImageUri(); 
    //Create any other intents you want 
    final Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    cameraIntent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUrl); 


    //Add them to an intent array 
    Intent[] intents = new Intent[]{cameraIntent}; 

    //Create a choose from your first intent then pass in the intent array 
    final Intent chooserIntent = Intent.createChooser(galleryIntent, mContext.getString(R.string.choose_photo_title)); 
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents); 

    ((Activity) mContext).startActivityForResult(chooserIntent, CHOOSE_PHOTO_INTENT); 
} 

// Change this method(edited) 
public void handleGalleryResult(Intent data) { 
    try { 
     cropPictureUrl = Uri.fromFile(FileUtil.getInstance(mContext) 
       .createImageTempFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES))); 
     String realPathFromURI = FileUtil.getRealPathFromURI(mContext, data.getData()); 
     File file = new File(realPathFromURI == null ? getImageUrlWithAuthority(mContext, data.getData()) : realPathFromURI); 
     if (file.exists()) { 
      if (currentAndroidDeviceVersion > 23) { 
       cropImage(FileProvider.getUriForFile(mContext, mContext.getApplicationContext().getPackageName() + ".provider", file), cropPictureUrl); 

      } else { 
       cropImage(Uri.fromFile(file), cropPictureUrl); 
      } 

     } else { 
      cropImage(data.getData(), cropPictureUrl); 
     } 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

public static String getImageUrlWithAuthority(Context context, Uri uri) { 
    InputStream is = null; 
    if (uri.getAuthority() != null) { 
     try { 
      is = context.getContentResolver().openInputStream(uri); 
      Bitmap bmp = BitmapFactory.decodeStream(is); 
      return writeToTempImageAndGetPathUri(context, bmp).toString(); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       is.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
    return null; 
} 

public static Uri writeToTempImageAndGetPathUri(Context inContext, Bitmap inImage) { 
    ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 
    inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes); 
    String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null); 
    return Uri.parse(path); 
} 


public void handleCameraResult(Uri cameraPictureUrl) { 
    try { 
     cropPictureUrl = Uri.fromFile(FileUtil.getInstance(mContext) 
       .createImageTempFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES))); 

     cropImage(cameraPictureUrl, cropPictureUrl); 
    } catch (IOException e) { 
     e.printStackTrace(); 

    } 

} 

public Uri getCameraUri() { 
    return cameraUrl; 
} 

public Uri getCropImageUrl() { 
    return selectedImageUri; 
} 

private void cropImage(final Uri sourceImage, Uri destinationImage) { 
    Intent intent = new Intent("com.android.camera.action.CROP"); 
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
    intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 

    intent.setType("image/*"); 

    List<ResolveInfo> list = mContext.getPackageManager().queryIntentActivities(intent, 0); 
    int size = list.size(); 
    if (size == 0) { 
     //Utils.showToast(mContext, mContext.getString(R.string.error_cant_select_cropping_app)); 
     selectedImageUri = sourceImage; 
     intent.putExtra(MediaStore.EXTRA_OUTPUT, sourceImage); 
     ((Activity) mContext).startActivityForResult(intent, SELECTED_IMG_CROP); 
     return; 
    } else { 
     intent.setDataAndType(sourceImage, "image/*"); 
     intent.putExtra("aspectX", ASPECT_X); 
     intent.putExtra("aspectY", ASPECT_Y); 
     intent.putExtra("outputY", OUT_PUT_Y); 
     intent.putExtra("outputX", OUT_PUT_X); 
     intent.putExtra("scale", SCALE); 

     //intent.putExtra("return-data", true); 
     intent.putExtra(MediaStore.EXTRA_OUTPUT, destinationImage); 
     selectedImageUri = destinationImage; 
     if (size == 1) { 
      Intent i = new Intent(intent); 
      ResolveInfo res = list.get(0); 
      i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name)); 
      ((Activity) mContext).startActivityForResult(intent, SELECTED_IMG_CROP); 
     } else { 
      Intent i = new Intent(intent); 
      i.putExtra(Intent.EXTRA_INITIAL_INTENTS, list.toArray(new Parcelable[list.size()])); 
      ((Activity) mContext).startActivityForResult(intent, SELECTED_IMG_CROP); 
     } 
    } 
} 
} 

FileUtil.java

public class FileUtil { 
private static FileUtil sSingleton; 
private Context context; 

private FileUtil(Context ctx) { 
    context = ctx; 
} 

/** 
* Gets instance. 
* 
* @param ctx the ctx 
* @return the instance 
*/ 
public static FileUtil getInstance(Context ctx) { 
    if (sSingleton == null) { 
     synchronized (FileUtil.class) { 
      sSingleton = new FileUtil(ctx); 
     } 
    } 
    return sSingleton; 
} 

public Uri createImageUri() { 
    ContentResolver contentResolver = context.getContentResolver(); 
    ContentValues cv = new ContentValues(); 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); 
    cv.put(MediaStore.Images.Media.TITLE, timeStamp); 
    return contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, cv); 
} 

/** 
* Create image temp file file. 
* 
* @param filePathDir the file path dir 
* @return the file 
* @throws IOException the io exception 
*/ 
@SuppressLint("SimpleDateFormat") 
public File createImageTempFile(File filePathDir) throws IOException { 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 

    String imageFileName = "JPEG_" + timeStamp + "_"; 
    return File.createTempFile(
      imageFileName, /* prefix */ 
      ".jpg",   /* suffix */ 
      filePathDir  /* directory */ 
    ); 
} 

public static String getUploadFileName() { 
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US); 
    Date date = new Date(); 
    return String.format("profile_%s.png", sdf.format(date)); 
} 

//add this code(edited) 
//get Path 
    @TargetApi(Build.VERSION_CODES.KITKAT) 
    public static String getRealPathFromURI(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]; 
      } 
     } 
     // 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(); 
    } else 
     return getRealPathFromURIDB(uri); 

    return null; 
} 

/** 
* Gets real path from uri. 
* 
* @param contentUri the content uri 
* @return the real path from uri 
*/ 
private static String getRealPathFromURIDB(Uri contentUri) { 
    Cursor cursor = context.getContentResolver().query(contentUri, null, null, null, null); 
    if (cursor == null) { 
     return contentUri.getPath(); 
    } else { 
     cursor.moveToFirst(); 
     int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
     String realPath = cursor.getString(index); 
     cursor.close(); 
     return realPath; 
    } 
} 

/** 
* Gets data column. 
* 
* @param uri   the uri 
* @param selection  the selection 
* @param selectionArgs the selection args 
* @return the data column 
*/ 
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; 
} 

/** 
* Is external storage document boolean. 
* 
* @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()); 
} 

/** 
* Is downloads document boolean. 
* 
* @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()); 
} 

/** 
* Is media document boolean. 
* 
* @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()); 
} 

/** 
* Is google photos uri boolean. 
* 
* @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()); 
} 
    } 

PermissionUtil.java

public class PermissionUtil { 
     private String[] galleryPermissions = { 
      "android.permission.WRITE_EXTERNAL_STORAGE", 
      "android.permission.READ_EXTERNAL_STORAGE" 
     }; 

private String[] cameraPermissions = { 
     "android.permission.CAMERA", 
     "android.permission.WRITE_EXTERNAL_STORAGE", 
     "android.permission.READ_EXTERNAL_STORAGE" 
}; 

public String[] getGalleryPermissions(){ 
    return galleryPermissions; 
} 

public String[] getCameraPermissions() { 
    return cameraPermissions; 
} 

public boolean verifyPermissions(Context context, String[] grantResults) { 
    for (String result : grantResults) { 
     if (ActivityCompat.checkSelfPermission(context, result) != PackageManager.PERMISSION_GRANTED) { 
      return false; 
     } 
    } 
    return true; 
} 

public boolean checkMarshMellowPermission(){ 
    return(Build.VERSION.SDK_INT> Build.VERSION_CODES.LOLLIPOP_MR1); 
} 

public static void showPermissionDialog(Context mContext,String msg){ 
    AlertDialog.Builder builder = new AlertDialog.Builder(mContext, R.style.DatePicker); 
    builder.setTitle("Need Permission"); 
    builder.setMessage(msg); 
    builder.setPositiveButton(mContext.getString(R.string.invitation_yes), (dialogInterface, i) -> { 
     dialogInterface.dismiss(); 
     Intent intent = new Intent(); 
     intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); 
     Uri uri = Uri.fromParts("package", mContext.getPackageName(), null); 
     intent.setData(uri); 
     (mContext).startActivity(intent); 
    }); 

    builder.setNegativeButton(mContext.getString(R.string.invitation_del_no), (dialogInterface, i) -> { 
     dialogInterface.dismiss(); 
    }); 
    builder.show(); 
} 

}

provide_paths.xml

<?xml version="1.0" encoding="utf-8"?> 
<paths xmlns:android="http://schemas.android.com/apk/res/android"> 
    <external-path name="external_files" path="."/> 
</paths> 
+0

你做了一個偉大的工作,但你能告訴我如何刪除作物節,並獲得完整的形象 –

+0

@Shweta你可以請張貼在這裏'PermissionUtil'文件 – pb123

+0

是啊sure.let我補充。 –

1

你有沒有在增加的Manifest.xml這個?

<application 
     ........ 
    <provider 
     android:name="android.support.v4.content.FileProvider" 
     android:authorities="${applicationId}.provider" 
     android:exported="false" 
     android:grantUriPermissions="true"> 
     <meta-data 
      android:name="android.support.FILE_PROVIDER_PATHS" 
      android:resource="@xml/provider_paths"/> 
    </provider> 
</application> 

這必須在你的清單中有效。在naugut android 7.0中的效果。

同樣,您需要添加provider_paths.xml文件xml

<?xml version="1.0" encoding="utf-8"?> 
<paths xmlns:android="http://schemas.android.com/apk/res/android"> 
    <external-path name="external_files" path="."/> 
</paths> 
+0

是的,我已經添加了。 –

+1

https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en 請隨本教程 –

+0

我引用本教程,並從本教程中得到這個解決方案(提供者)。從這個教程我完成,直到與camare作物,但裁剪後崩潰。 –

14

我只是解決上Nexus6p安卓n這個問題,你需要授予權限URI所以系統相機可以暫時訪問該文件等待作物,因爲StrictMode的Android n具有不支持通過一個文件:URI中一個Intent額外再看到Scheme Ban in N Developer Preview,我們使用FileProvider instead.here是我的源代碼:

AndroidManifest.xml

<provider 
    android:name="android.support.v4.content.FileProvider" 
     android:authorities="dreamgo.corp.provider" 
     android:grantUriPermissions="true" 
     android:exported="false"> 
     <meta-data 
      android:name="android.support.FILE_PROVIDER_PATHS" 
      android:resource="@xml/filepaths"/> 
</provider> 

filepaths.xml

<?xml version="1.0" encoding="utf-8"?> 
<paths xmlns:android="http://schemas.android.com/apk/res/android"> 
    <external-path name="images" path="."/> 
</paths> 

MainActivity.java

Uri photoURI = FileProvider.getUriForFile(context, "dreamgo.corp.provider", file); 
//grant uri with essential permission the first arg is the The packagename you would like to allow to access the Uri. 
context.grantUriPermission("com.android.camera",photoURI, 
        Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); 

Intent intent = new Intent("com.android.camera.action.CROP"); 
intent.setDataAndType(photoURI, "image/*"); 

//you must setup two line below 
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 

intent.putExtra("crop", "true"); 
intent.putExtra("aspectX", 1); 
intent.putExtra("aspectY", 1); 
intent.putExtra("outputX", 200); 
intent.putExtra("outputY", 200); 
intent.putExtra("return-data", true); 
//you must setup this 
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); 
startActivityForResult(intent, 1); 
+0

你可以請給我建議如何在裁剪後將圖像存儲在ImageView中(當requestCode == CROP_IMAGE時)。因爲在裁剪圖像後它在Android中無法攝像。在NI NI使用'Bitmap bitmap = data.getParcelableExtra(「data」)之前,我們需要使用' –

+0

';'但是這不適用於Android NI爲相機創建一個臨時文件並在用戶使用相機拍攝照片後從此臨時文件中獲取uri, )臨時文件uri.system的臨時文件將在用戶剪下它後更改臨時文件。我將在此問題下的所有代碼中發佈其他答案。 – Ykh

+1

這是什麼文件名和上下文 –

2

我有兩個源,用於作物,一個是畫廊和另一種是照相機

方法畫廊:

//take a photo from gallery 
public void gallery() { 
    //set UUID to filename 
    String PHOTO_FILE_NAME = UUID.randomUUID().toString()+".jpg"; 
    Utils.putValue(this, Constants.UserPortraitFilePath,PHOTO_FILE_NAME); 
    Intent intent = new Intent(Intent.ACTION_PICK); 
    intent.setType("image/*"); 
    startActivityForResult(intent, PHOTO_REQUEST_GALLERY); 
} 

方法相機:

//take a photo from camera 
public void camera() { 
    //check sdcard is usable or not 
    if (Utils.hasSdcard()) { 
     //set UUID to filename 
     String PHOTO_FILE_NAME = UUID.randomUUID().toString()+".jpg"; 
     Utils.putValue(this,Constants.UserPortraitFilePath,PHOTO_FILE_NAME); 
     Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); 
     //set file location to DreamGo/Image 
     File path = Environment.getExternalStorageDirectory(); 
     File dir = new File(path, "DreamGo/Image"); 
     if(!dir.exists()) 
      dir.mkdirs(); 
     //Android N need use FileProvider get file 
     //uri because StrictMode System 
     //getUriForFile(content,provider author,file) 
     Uri photoURI = FileProvider.getUriForFile(context, "dream.go.provider", 
       new File(dir.getAbsolutePath(), PHOTO_FILE_NAME)); 
     intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); 
     startActivityForResult(intent, PHOTO_REQUEST_CAMERA); 
    }else { 
     showToast("no storage device"); 
    } 
} 

裁剪方法:

//Android N crop image 
public void crop(Uri uri) { 
    context.grantUriPermission("com.android.camera",uri, 
      Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); 
    Intent intent = new Intent("com.android.camera.action.CROP"); 
    intent.setDataAndType(uri, "image/*"); 
    //Android N need set permission to uri otherwise system camera don't has permission to access file wait crop 
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
    intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 
    intent.putExtra("crop", "true"); 
    //The proportion of the crop box is 1:1 
    intent.putExtra("aspectX", 1); 
    intent.putExtra("aspectY", 1); 
    //Crop the output image size 
    intent.putExtra("outputX", 800); 
    intent.putExtra("outputY", 800); 
    //image type 
    intent.putExtra("outputFormat", "JPEG"); 
    intent.putExtra("noFaceDetection", true); 
    //true - don't return uri | false - return uri 
    intent.putExtra("return-data", true); 
    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); 
    startActivityForResult(intent, PHOTO_REQUEST_CUT); 
} 

的onActivityResult方法:

private static final int PHOTO_REQUEST_CAMERA = 0;//camera 
private static final int PHOTO_REQUEST_GALLERY = 1;//gallery 
private static final int PHOTO_REQUEST_CUT = 2;//image crop 
@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    String PHOTO_FILE_NAME = Utils.getValue(this, Constants.UserPortraitFilePath); 
    File path = Environment.getExternalStorageDirectory(); 
    File dir = new File(path, "DreamGo/Image"); 
    if(!dir.exists()) 
     dir.mkdirs(); 
    switch (requestCode) 
    { 
     case PHOTO_REQUEST_GALLERY: 
      if (data != null){ 
       //file from gallery 
       File sourceFile = new File(getRealPathFromURI(data.getData())); 
       //blank file DreamGo/Image/uuid.jpg 
       File destFile = new File(dir.getAbsolutePath(), PHOTO_FILE_NAME); 
       Log.e("photo",data.getData().getPath()); 
       try { 
        //copy file from gallery to DreamGo/Image/uuid.jpg 
        // otherwise crop method can't cut image without write permission 
        copyFile(sourceFile,destFile); 
        //Android N need use FileProvider to get file uri 
        Uri photoURI = FileProvider.getUriForFile(context, "dream.go.provider", destFile); 
        //cut image 
        crop(photoURI); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
      break; 
     case PHOTO_REQUEST_CAMERA: 
      //whether sdcard is usable has been checked before use camera 
      File tempFile = new File(dir.getAbsolutePath(), PHOTO_FILE_NAME); 
      Uri photoURI = FileProvider.getUriForFile(context, "dream.go.provider", tempFile); 
      crop(photoURI); 
      break; 
     case PHOTO_REQUEST_CUT: 
      try { 
       if(data!=null) { 
        file = new File(dir.getAbsolutePath(), PHOTO_FILE_NAME); 
        icon.loadImage("file://" + file.getAbsolutePath()); 
       }else { 
        showToast("a error happened when cut picture"); 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      break; 
     default: 
      break; 
    } 
} 

的realted代碼:

//copy sourceFile to destFile 
public void copyFile(File sourceFile, File destFile) throws IOException { 
    if (!sourceFile.exists()) { 
     return; 
    } 
    FileChannel source = new FileInputStream(sourceFile).getChannel(); 
    FileChannel destination = new FileOutputStream(destFile).getChannel(); 
    if (destination != null && source != null) { 
     destination.transferFrom(source, 0, source.size()); 
    } 
    if (source != null) { 
     source.close(); 
    } 
    if (destination != null) { 
     destination.close(); 
    } 
} 

//file uri to real location in filesystem 
public 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); 
    } 
} 

public static final String getValue(Context context, String key) { 
    return getSharedPreference(context).getString(key, ""); 
} 
public static final boolean putValue(Context context, String key, 
            String value) { 
    value = value == null ? "" : value; 
    SharedPreferences.Editor editor = getSharedPreference(context).edit(); 
    editor.putString(key, value); 
    boolean result = editor.commit(); 
    if (!result) { 
     return false; 
    } 
    return true; 
} 
+0

Uri photoURI = FileProvider.getUriForFile(context,「dream.go.provider」,destFile);在這些行我得到文件沒有發現異常 –

0
Uri uri = FileProvider.getUriForFile(this, getPackageName() + Configs.FILE_PROVIDER_NAME, inFile); 
    Intent intent = new Intent("com.android.camera.action.CROP"); 
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
    intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 
    intent.setDataAndType(uri, "image/*"); 
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(outFile)); 

你應該注意到,對於EXTRA_OUTPUT的URI不應該由FileProvider修改。 因爲你創建getExternalFilesDir下作物文件的paths.xml想這

<paths xmlns:android="http://schemas.android.com/apk/res/android"> 
<external-path name="external_sd" path="."/> 
<external-files-path name="external_app" path="."/> 
<files-path name="files" path="."/> 
<cache-path name="cache" path="."/> 

。所以<external-files-path>是必要的。

-1
Intent pickImageIntent = new Intent("com.android.camera.action.CROP"); 
Uri contentUri = imageUri; 
pickImageIntent.setDataAndType(contentUri, "image/*"); 
pickImageIntent.putExtra("crop", "true"); 
pickImageIntent.putExtra("aspectX", 1); 
pickImageIntent.putExtra("aspectY", 1); 
pickImageIntent.putExtra("outputX", 400); 
pickImageIntent.putExtra("outputY", 400); 
pickImageIntent.putExtra("return-data", true); 
startActivityForResult(pickImageIntent, RESULT_CROP); 
+0

您應該提供額外的[上下文](https://meta.stackexchange.com/q/114762)關於_how_和/或_why_此代碼解決問題。這會提高答案的長期價值。請記住,你正在爲將來的讀者回答這個問題,而不僅僅是現在問的人!請[編輯](http://stackoverflow.com/posts/43231334/edit)您的答案添加一個解釋,並指出適用的限制和假設。它也不會提到爲什麼這個答案比其他答案更合適。 –

相關問題