2014-07-14 54 views
6

Từ trong ứng dụng của tôi, tôi đang cố tạo một email chứa hình ảnh chứa trong đối tượng bitmap.Android: Cách sử dụng grantUriPermission để có thể tạo và gửi email kèm theo tệp đính kèm bitmap

private void sendEmailWithBitmapAttached(){ 

    final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); 
    emailIntent.setType("plain/text"); 
    emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Email Subject"); 
    emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Email Body"); 
    emailIntent.setType("image/png"); 
    ContentResolver cr = getContentResolver(); 

    // insert the image and create a path 
    String imageBitmapPath = MediaStore.Images.Media.insertImage(cr, bitmapForEmail,"title", "description"); 

    // create a uri 
    Uri imageUri = Uri.parse(imageBitmapPath); 
    emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    emailIntent.putExtra(Intent.EXTRA_STREAM, imageUri); 

    // send the email 
    startActivity(Intent.createChooser(emailIntent, "Send mail...")); 
} 

Điều này hoạt động tốt trong Android 2.3.

Nhưng sử dụng các phiên bản sau, nó tạo ra các lỗi sau:

07-13 23:01:01.252: E/MediaStore(5194): Failed to insert image 
07-13 23:01:01.252: E/MediaStore(5194): java.lang.SecurityException: 
    Permission Denial: 
     writing com.android.providers.media.MediaProvider 
     uri content://media/external/images/media from 
      pid=5194, uid=10151 requires 
      android.permission.WRITE_EXTERNAL_STORAGE, 
      or grantUriPermission() 

Vì vậy, lấy gợi ý của thông báo lỗi, tôi đã cố gắng để grantUriPermission.

grantUriPermission(String toPackage, Uri uri, int modeFlags) 

Nhưng tôi không chắc chắn những gì để đặt cho toPackage hoặc uri

Nhưng một lần nữa, sử dụng các thông báo lỗi, tôi sửa đổi mã như sau:

private void sendEmailWithBitmapAttached(){ 

    final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); 
    emailIntent.setType("plain/text"); 
    emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Email Subject"); 
    emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Email Body"); 
    emailIntent.setType("image/png"); 
    ContentResolver cr = getContentResolver(); 

    // create a Uri for the content provider suggested by the error message 
    Uri uri = Uri.parse("content://media/external/images/media"); 

    // create a package provider string suggested by the error messge. 
    String provider = "com.android.providers.media.MediaProvider"; 


    // grant all three uri permissions! 
    grantUriPermission(provider, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); 
    grantUriPermission(provider, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 
    grantUriPermission(provider, uri, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 

    // insert the image and create a path 
    String imageBitmapPath = MediaStore.Images.Media.insertImage(cr, bitmapForEmail,"title", "description"); 

    // create a uri 
    Uri imageUri = Uri.parse(imageBitmapPath); 
    emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    emailIntent.putExtra(Intent.EXTRA_STREAM, imageUri); 

    // send the email 
    startActivity(Intent.createChooser(emailIntent, "Send mail...")); 
} 

Và tôi nhận được chính xác cùng một lỗi.

Một linh hồn tử tế có thể cho tôi một gợi ý về cách chăm sóc uri và các nhà cung cấp của grantUriPermission không? Đây có phải là cách tiếp cận chính xác không?

Cảm ơn bạn rất nhiều vì BẤT CỨ trợ giúp, gợi ý, hướng dẫn hoặc đề xuất, bạn có thể cung cấp!

Trả lời

7

Hãy thử đưa mã này vào tệp AndroidManifest.xml của bạn.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

Trên Android 6.0+ quyền này phải được người dùng cấp cho ứng dụng nếu không điều này sẽ ném SecurityException.

Để thực hiện việc này, hãy chuyển đến Cài đặt/Ứng dụng/[Tên ứng dụng]/Quyền và cho phép Giấy phép lưu trữ.

+1

không hoạt động ngay cả sau khi thêm quyền, nó vẫn bị treo. –

0

Tôi gặp sự cố tương tự. Dưới đây là cách tôi giải quyết vấn đề cho dự án của tôi. Bạn sẽ có thể thích nghi điều này cho giải pháp của bạn. Giải pháp này cũng có một số mã Firebase mà bạn có thể bỏ qua. Những điểm mấu chốt là ActivityCompat.requestPermissions và ActivityCompat.checkSelfPermission:

private void shareViaEmail() { 
    int permissionCheck = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE); 
    if (permissionCheck != PackageManager.PERMISSION_GRANTED) { 
     if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) { 
      AlertDialog.Builder alertBuilder = new AlertDialog.Builder(this); 
      LayoutInflater inflater = this.getLayoutInflater(); 
      final ViewGroup nullParent = null; 
      final View dialogView = inflater.inflate(R.layout.alert_dialog, nullParent); 
      alertBuilder.setView(dialogView); 

      alertBuilder.setCancelable(true); 
      alertBuilder.setTitle("Permission request"); 

      String message = "\n\n" + getString(R.string.email_images); 
      AppCompatTextView notice = (AppCompatTextView) dialogView.findViewById(R.id.notice); 
      if (notice != null) { 
       notice.setText(message); 
       notice.setTextSize(getResources().getInteger(R.integer.dialog_text_size)); 
      } 
      else { 
       alertBuilder.setMessage(message); 
      } 

      alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { 

       @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 
       public void onClick(DialogInterface dialog, int which) { 
        mShowingAlert = false; 
        ActivityCompat.requestPermissions(baseActivity(), new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_TARGET_WRITE_PERMISSION_REQUEST); 
       } 
      }); 

      mAlertDialog = alertBuilder.create(); 
      mAlertDialog.show(); 
      return; 
     } 
    } 
    ActivityCompat.requestPermissions(this, 
      new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 
      MY_TARGET_WRITE_PERMISSION_REQUEST); 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
    super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { 
     if (requestCode == MY_TARGET_WRITE_PERMISSION_REQUEST) { 
      doShareViaEmail(); 
     } else { 
      failWriteImage(); 
     } 
    } 
} 

protected void failWriteImage() { 
    getHandler().post(new Runnable() { 
     @Override 

     public void run() { 
      String email_failed = getResources().getString(R.string.fail_email_attach); 
      @SuppressLint("ShowToast") Toast toast = Toast.makeText(getApplicationContext(), email_failed, Toast.LENGTH_SHORT); 
      new CustomToast(toast).invoke(); 
     } 
    }); 
} 

protected void doShareViaEmail() { 
    FireUtilities fireUtilities = FireUtilities.getInstance(); 
    fireUtilities.logEvent(mFirebaseAnalytics, "option_item", "share", "share_string"); 

    Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE); 
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.string_share)); 

    String appStoreLink = getString(R.string.app_store_link); 

    String emailText = getString(R.string.share_string_body1) 
      + " " + appStoreLink 
      + " " + getString(R.string.share_string_body2); 

    emailText = emailText + "<br><br>" + getTitleOfSegment(true, mCurrentSegment, mCurrentSegmentIndex); 

    Bitmap targetImage = screenShot(mTargetImageView); 
    if (targetImage != null) { 
     ArrayList<Uri> files = new ArrayList<Uri>(); 
     String path = MediaStore.Images.Media.insertImage(getContentResolver(), targetImage, "string", null); 
     Uri targetUri = Uri.parse(path); 
     files.add(targetUri); 
     intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, files); 
    } 

    intent.setType("message/rfc822"); 

    Spanned htmlText = fromHtml(getString(R.string.share_score_head1) 
      + emailText + getString(R.string.share_score_head2)); 
    intent.putExtra(Intent.EXTRA_TEXT, htmlText); 

    try { 
     startActivityForResult(Intent.createChooser(intent, "Email:"), 1234); 
    } catch (final android.content.ActivityNotFoundException e) { 
     String no_email_client = getResources().getString(R.string.no_email_client); 
     @SuppressLint("ShowToast") Toast toast = Toast.makeText(getApplicationContext(), no_email_client, Toast.LENGTH_LONG); 
     new CustomToast(toast).invoke(); 
    } 
} 

public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (requestCode == 1234) { 
     LogHelper.v(TAG, "e-mail successfully sent"); 
    } 
} 

public Bitmap screenShot(View view) { 
    if (view != null) { 
     Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), 
       view.getHeight(), Bitmap.Config.ARGB_8888); 
     Canvas canvas = new Canvas(bitmap); 
     view.draw(canvas); 
     return bitmap; 
    } 
    return null; 
} 
Các vấn đề liên quan