Java Android:如何使用grantUriPermission创建并发送带有位图附件的电子邮件

Java Android:如何使用grantUriPermission创建并发送带有位图附件的电子邮件,java,android,bitmap,Java,Android,Bitmap,在我的应用程序中,我试图创建一封电子邮件,其中包含位图对象中包含的图像 private void sendEmailWithBitmapAttached(){ final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); emailIntent.setType("plain/text"); emailIntent.putExtra(android.content.Intent.EX

在我的应用程序中,我试图创建一封电子邮件,其中包含位图对象中包含的图像

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..."));
}
这在Android 2.3中运行良好

但使用更高版本时,会产生以下错误:

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()
因此,根据错误消息的建议,我尝试授予权限

grantUriPermission(String toPackage, Uri uri, int modeFlags)
但我不确定要把什么放在包或uri中

但是,我再次使用错误消息修改了代码,如下所示:

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..."));
}
我得到了完全相同的错误

一个善良的灵魂可以给我一个提示,如何照顾grantUriPermission的uri和提供者项目?这是正确的方法吗


非常感谢您提供的任何帮助、提示、指导或建议

尝试将其包含在您的AndroidManifest.xml中

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

在Android 6.0+上,用户必须向应用程序授予权限,否则将引发SecurityException


要执行此操作,请进入设置/Apps/[AppName]/Permissions并允许存储权限。

我遇到了类似的问题。下面是我如何解决我的项目的问题。您应该能够根据您的解决方案对其进行调整。此解决方案还有一些Firebase代码,您可以忽略这些代码。关键点是ActivityCompat.requestPermissions和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;
}
private void shareViaEmail(){
int permissionCheck=ContextCompat.checkSelfPermission(这是android.Manifest.permission.WRITE\u外部存储);
if(permissionCheck!=PackageManager.PERMISSION\u已授予){
if(ActivityCompat.shouldshowRequestPermissionRegulation(这是android.Manifest.permission.WRITE\u外部存储)){
AlertDialog.Builder alertBuilder=新建AlertDialog.Builder(此);
LayoutInflater充气机=this.getLayoutInflater();
最终视图组nullParent=null;
最终视图对话框视图=充气机。充气(R.layout.alert_对话框,空父级);
alertBuilder.setView(dialogView);
alertBuilder.setCancelable(真);
alertBuilder.setTitle(“权限请求”);
String message=“\n\n”+getString(R.String.email\u图像);
AppCompatTextView通知=(AppCompatTextView)dialogView.findViewById(R.id.notice);
if(注意!=null){
notice.setText(message);
注意.setTextSize(getResources().getInteger(R.integer.dialog_text_size));
}
否则{
alertBuilder.setMessage(消息);
}
alertBuilder.setPositiveButton(android.R.string.yes,新的DialogInterface.OnClickListener(){
@TargetApi(Build.VERSION\u code.JELLY\u BEAN)
public void onClick(DialogInterface dialog,int which){
mShowingAlert=false;
ActivityCompat.requestPermissions(baseActivity(),新字符串[]{android.Manifest.permission.WRITE\u EXTERNAL\u STORAGE},MY\u TARGET\u WRITE\u permission\u REQUEST);
}
});
mAlertDialog=alertBuilder.create();
mAlertDialog.show();
返回;
}
}
ActivityCompat.requestPermissions(此,
新字符串[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
我的\目标\写入\许可\请求);
}
@凌驾
public void onRequestPermissionsResult(int-requestCode,@NonNull-String[]permissions,@NonNull-int[]grantResults){
super.onRequestPermissionsResult(请求代码、权限、授权结果);
if(ActivityCompat.checkSelfPermission(this,android.Manifest.permission.WRITE_EXTERNAL_STORAGE)==PackageManager.permission_provided){
if(requestCode==MY\u TARGET\u WRITE\u PERMISSION\u REQUEST){
doShareViaEmail();
}否则{
failWriteImage();
}
}
}
受保护的无效failWriteImage(){
getHandler().post(新的Runnable()){
@凌驾
公开募捐{
String email\u failed=getResources().getString(R.String.fail\u email\u attach);
@SuppressLint(“ShowToast”)Toast Toast=Toast.makeText(getApplicationContext(),email\u失败,Toast.LENGTH\u SHORT);
新建CustomToast(toast.invoke();
}
});
}
受保护的void doShareViaEmail(){
FireUtilities=FireUtilities.getInstance();
fireUtilities.logEvent(mFirebaseAnalytics,“选项项”、“共享”、“共享字符串”);
意向意向=新意向(意向.行动\发送\多次);
intent.setFlags(intent.FLAG\u活动\u新任务);
intent.putExtra(intent.EXTRA_主题,getString(R.string.string_共享));
String appStoreLink=getString(R.String.app\u store\u link);
String emailText=getString(R.String.share\u String\u body1)
+“”+appStoreLink
+“”+getString(R.string.share\u string\u body 2);
emailText=emailText+“

”+getTitleOfSegment(true,mCurrentSegment,mCurrentSegmentIndex); 位图targetImage=屏幕截图(mTargetImageView); if(targetImage!=null){ ArrayList files=新的ArrayList(); String path=MediaStore.Images.Media.insertImage(getContentResolver(),targetImage,“String”,null); uritargeturi=Uri.parse(路径); 添加(targetUri); intent.putParcelableArrayListExtra(intent.EXTRA\u流,文件); } intent.setType(“message/rfc822”); 跨距htmlText=fromHtml(getString(R.string.share\u score\u head1) +emailText+getString(R.string.share_score_head2)); intent.putExtra(intent.EXTRA_TEXT,htmlText); 试一试{ startActivityForResult(Intent.createChooser(Intent,“Email:”),1234); }捕获(最终android.content.ActivityNotFoundException){ String no_email_client=getResources().getString(R.String.no_email_client); @SuppressLint(“ShowToast”)Toast Toast=Toast.makeText(getApplicationContext(),无电子邮件\u客户端,Toast.LENGTH\u LONG); 新海关吐司(致
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);