如何使用"Share image using"共享意图在安卓中共享图像?



我有一个图片厨房应用程序;在那个应用程序中,我把所有的图像都放到了draw_hdpi文件夹中。我在activity中这样调用图像:

private Integer[] imageIDs = {
        R.drawable.wall1, R.drawable.wall2,
        R.drawable.wall3, R.drawable.wall4,
        R.drawable.wall5, R.drawable.wall6,
        R.drawable.wall7, R.drawable.wall8,
        R.drawable.wall9, R.drawable.wall10
};

如何使用共享意图共享这些图像?我把共享代码像这样:

     Button shareButton = (Button) findViewById(R.id.share_button);
     shareButton.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v) {
       
        Intent sharingIntent = new Intent(Intent.ACTION_SEND);
        Uri screenshotUri = Uri.parse(Images.Media.EXTERNAL_CONTENT_URI + "/" + imageIDs);
        sharingIntent.setType("image/jpeg");
        sharingIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
        startActivity(Intent.createChooser(sharingIntent, "Share image using"));  
    
         }
    });

我也有一个分享按钮;当我点击分享按钮时,分享框会打开,但当我点击任何服务时,大多数情况下它会崩溃,或者一些服务会说:"无法打开图像"。我该如何解决这个问题,或者是否有任何其他格式代码来共享图像?

我试着使用下面的代码,但它不工作。

Button shareButton = (Button) findViewById(R.id.share_button);
     shareButton.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v) {
        Intent sharingIntent = new Intent(Intent.ACTION_SEND);
        Uri screenshotUri = Uri.parse("android.resource://com.android.test/*");
        try {
            InputStream stream = getContentResolver().openInputStream(screenshotUri);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        sharingIntent.setType("image/jpeg");
        sharingIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
        startActivity(Intent.createChooser(sharingIntent, "Share image using"));  
         }
    });

我如何从draw_hdpi文件夹共享我的图像?

Bitmap icon = mBitmap;
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/jpeg");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
icon.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File f = new File(Environment.getExternalStorageDirectory() + File.separator + "temporary_file.jpg");
try {
    f.createNewFile();
    FileOutputStream fo = new FileOutputStream(f);
    fo.write(bytes.toByteArray());
} catch (IOException e) {                       
        e.printStackTrace();
}
share.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///sdcard/temporary_file.jpg"));
startActivity(Intent.createChooser(share, "Share Image"));

superM提出的解决方案为我工作了很长一段时间,但最近我在4.2 (HTC One)上测试了它,它停止了工作。我知道这是一个变通方法,但这是唯一一个适用于我所有设备和版本的方法。

根据文档,开发人员被要求"使用系统MediaStore"来发送二进制内容。然而,这有(缺点)的好处,媒体内容将被永久保存在设备上。

如果这是您的一个选项,您可能希望授予权限WRITE_EXTERNAL_STORAGE并使用系统范围的MediaStore。

Bitmap icon = mBitmap;
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/jpeg");
ContentValues values = new ContentValues();
values.put(Images.Media.TITLE, "title");
values.put(Images.Media.MIME_TYPE, "image/jpeg");
Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI,
        values);

OutputStream outstream;
try {
    outstream = getContentResolver().openOutputStream(uri);
    icon.compress(Bitmap.CompressFormat.JPEG, 100, outstream);
    outstream.close();
} catch (Exception e) {
    System.err.println(e.toString());
}
share.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(share, "Share Image"));

首次添加权限

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

使用Bitmap from resources

Bitmap b =BitmapFactory.decodeResource(getResources(),R.drawable.userimage);
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/jpeg");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(getContentResolver(), b, "Title", null);
Uri imageUri =  Uri.parse(path);
share.putExtra(Intent.EXTRA_STREAM, imageUri);
startActivity(Intent.createChooser(share, "Select"));

通过蓝牙和其他信使进行测试

我发现最简单的方法是使用MediaStore临时存储您想要共享的图像:

Drawable mDrawable = mImageView.getDrawable();
Bitmap mBitmap = ((BitmapDrawable) mDrawable).getBitmap();
String path = MediaStore.Images.Media.insertImage(getContentResolver(), mBitmap, "Image Description", null);
Uri uri = Uri.parse(path);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/jpeg");
intent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(intent, "Share Image"));

From: Sharing Content With intent

简单和最容易的代码,你可以用它来分享图片库。

 String image_path;
            File file = new File(image_path);
            Uri uri = Uri.fromFile(file);
            Intent intent = new Intent(Intent.ACTION_SEND);
            intent .setType("image/*");
            intent .putExtra(Intent.EXTRA_STREAM, uri);
            context.startActivity(intent );

如何在android中以编程方式共享图像,有时您想要拍摄视图的快照,然后喜欢分享它所以请遵循以下步骤:添加维护文件权限

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

2。首先,截取你的视图的截图Imageview, Textview, frameayout,LinearLayout等

例如,你有一个图像视图截图在oncreate()

中调用这个方法
 ImageView image= (ImageView)findViewById(R.id.iv_answer_circle);
     ///take a creenshot
    screenShot(image);

截图后调用共享图像方法点击你想要的地方

shareBitmap(screenShot(image),"myimage");

创建方法后定义这两个方法##

    public Bitmap screenShot(View view) {
    Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
            view.getHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    view.draw(canvas);
    return bitmap;
}
//////// this method share your image
private void shareBitmap (Bitmap bitmap,String fileName) {
    try {
        File file = new File(getContext().getCacheDir(), fileName + ".png");
        FileOutputStream fOut = new FileOutputStream(file);
        bitmap.compress(CompressFormat.PNG, 100, fOut);
        fOut.flush();
        fOut.close();
        file.setReadable(true, false);
        final Intent intent = new Intent(     android.content.Intent.ACTION_SEND);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
        intent.setType("image/png");
        startActivity(intent);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

谢谢大家,我尝试了给出的几个选项,但这些选项似乎不适用于最新的android版本,因此添加了适用于最新android版本的修改步骤。这些都是基于上面的几个答案,但做了一些修改。解决方案基于文件提供程序的使用:

步骤:1

在Manifest文件中添加以下代码:

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

步骤:2创建一个XML文件>xml

在xml中创建file_provider_paths文件。

请注意,这是我们在上一步中包含在android:资源中的文件。

在file_provider_paths中编写以下代码:

<?xml version="1.0" encoding="utf-8"?>
<paths>
        <cache-path name="cache" path="/" />
        <files-path name="files" path="/" />
</paths>

步骤:3

然后点击你的按钮:

Button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
       Bitmap bit = BitmapFactory.decodeResource(context.getResources(),  R.drawable.filename);
        File filesDir = context.getApplicationContext().getFilesDir();
        File imageFile = new File(filesDir, "birds.png");
        OutputStream os;
        try {
            os = new FileOutputStream(imageFile);
            bit.compress(Bitmap.CompressFormat.PNG, 100, os); 
            os.flush();
            os.close();
        } catch (Exception e) {
            Log.e(getClass().getSimpleName(), "Error writing bitmap", e);
        }
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_SEND);
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        Uri imageUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID, imageFile);
        intent.putExtra(Intent.EXTRA_STREAM, imageUri);
        intent.setType("image/*");
        context.startActivity(intent);
    }
});

更详细的解释访问https://droidlytics.wordpress.com/2020/08/04/use-fileprovider-to-share-image-from-recyclerview/

这是一个解决方案,为我工作。一个问题是你需要将图像存储在共享或非应用程序私有位置(http://developer.android.com/guide/topics/data/data-storage.html#InternalCache)

许多建议说存储在Apps"私有"缓存位置,但这当然不能通过其他外部应用程序访问,包括正在使用的通用共享文件意图。当你尝试这样做时,它会运行,但例如dropbox会告诉你文件不再可用。

/*步骤1 -使用下面的文件保存功能在本地保存位图文件。*/

localAbsoluteFilePath = saveImageLocally(bitmapImage);

/*步骤2 -将非私有的绝对文件路径共享给共享文件intent */

if (localAbsoluteFilePath!=null && localAbsoluteFilePath!="") {
    Intent shareIntent = new Intent(Intent.ACTION_SEND);
    Uri phototUri = Uri.parse(localAbsoluteFilePath);
    File file = new File(phototUri.getPath());
    Log.d(TAG, "file path: " +file.getPath());
    if(file.exists()) {
        // file create success
    } else {
        // file create fail
    }
    shareIntent.setData(phototUri);
    shareIntent.setType("image/png");
    shareIntent.putExtra(Intent.EXTRA_STREAM, phototUri);
    activity.startActivityForResult(Intent.createChooser(shareIntent, "Share Via"), Navigator.REQUEST_SHARE_ACTION);
}   

/*保存图像函数*/

    private String saveImageLocally(Bitmap _bitmap) {
        File outputDir = Utils.getAlbumStorageDir(Environment.DIRECTORY_DOWNLOADS);
        File outputFile = null;
        try {
            outputFile = File.createTempFile("tmp", ".png", outputDir);
        } catch (IOException e1) {
            // handle exception
        }
        try {
            FileOutputStream out = new FileOutputStream(outputFile);
            _bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
            out.close();
        } catch (Exception e) {
            // handle exception
        }
        return outputFile.getAbsolutePath();
    }

/* STEP 3 -处理共享文件意图结果。需要远程临时文件等*/

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
            // deal with this with whatever constant you use. i have a navigator object to handle my navigation so it also holds all mys constants for intents
        if (requestCode== Navigator.REQUEST_SHARE_ACTION) {
            // delete temp file
            File file = new File (localAbsoluteFilePath);
            file.delete();
            Toaster toast = new Toaster(activity);
            toast.popBurntToast("Successfully shared");
        }

    }   

我希望这对某人有所帮助。

我厌倦了从我的应用程序到其他应用程序共享视图或图像的不同选项。最后我得到了答案。

步骤1:共享意图处理块。这将弹出窗口,显示手机中的应用程序列表

public void share_bitMap_to_Apps() {
    Intent i = new Intent(Intent.ACTION_SEND);
    i.setType("image/*");
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    /*compress(Bitmap.CompressFormat.PNG, 100, stream);
    byte[] bytes = stream.toByteArray();*/

    i.putExtra(Intent.EXTRA_STREAM, getImageUri(mContext, getBitmapFromView(relative_me_other)));
    try {
        startActivity(Intent.createChooser(i, "My Profile ..."));
    } catch (android.content.ActivityNotFoundException ex) {
        ex.printStackTrace();
    }

}

步骤2:将视图转换为位图

public static Bitmap getBitmapFromView(View view) {
    //Define a bitmap with the same size as the view
    Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(),      view.getHeight(), Bitmap.Config.ARGB_8888);
    //Bind a canvas to it
    Canvas canvas = new Canvas(returnedBitmap);
    //Get the view's background
    Drawable bgDrawable = view.getBackground();
    if (bgDrawable != null)
        //has background drawable, then draw it on the canvas
        bgDrawable.draw(canvas);
    else
        //does not have background drawable, then draw white background on the canvas
        canvas.drawColor(Color.WHITE);
    // draw the view on the canvas
    view.draw(canvas);
    //return the bitmap
    return returnedBitmap;
}

步骤3:

从Bitmap Image获取URI

public Uri getImageUri(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);
}

我刚刚遇到了同样的问题。
这里有一个答案,不使用任何显式的文件编写在你的主代码(让api为你照顾它)。

Drawable mDrawable = myImageView1.getDrawable();
Bitmap mBitmap = ((BitmapDrawable)mDrawable).getBitmap();
String path = MediaStore.Images.Media.insertImage(getContentResolver(), mBitmap, "Image I want to share", null);
Uri uri = Uri.parse(path);
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
shareIntent.setType("image/*");
startActivity(Intent.createChooser(shareIntent, "Share Image"));

这是路径…你只需要在一个Drawable对象中添加你的图像id。在我的例子中(上面的代码),drawable是从ImageView中提取的。

SuperM答案为我工作,但与Uri.fromFile()而不是Uri.parse()。

对于Uri.parse(),它只适用于Whatsapp。

这是我的代码:

sharingIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(mFile));

Uri.parse()的输出:
/存储/模拟/0/Android/数据/application_package/文件/17072015 _0927.jpg

Uri.fromFile的输出:
file:///storage/emululated/0/Android/data/application_package/Files/17072015_0927.jpg

ref:- http://developer.android.com/training/sharing/send.html#send-multiple-content

ArrayList<Uri> imageUris = new ArrayList<Uri>();
imageUris.add(imageUri1); // Add your image URIs here
imageUris.add(imageUri2);
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
shareIntent.setType("image/*");
startActivity(Intent.createChooser(shareIntent, "Share images to.."));

上述所有解决方案在Android Api 26 & 27 (Oreo)中对我不起作用,正在获得Error: exposed beyond app through ClipData.Item.getUri。适合我的情况的解决方案是

  1. 使用FileProvider.getUriForFile(Context,packagename,File)作为
  2. 获取路径uri
void shareImage() {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("image/*");
        intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(this,getPackageName(),deleteFilePath));
        startActivity(Intent.createChooser(intent,"Share with..."));
    }
  1. Manifest.xml中的<provider>定义为
<provider
     android:name="android.support.v4.content.FileProvider"
     android:authorities="com.example.stickerapplication"
      android:exported="false"
      android:grantUriPermissions="true">
      <meta-data
          android:name="android.support.FILE_PROVIDER_PATHS"
          android:resource="@xml/file_paths">
       </meta-data>
</provider>
最后一步是为你的目录定义resource文件
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="." />
</paths>
*Note this solution is for `external storage` `uri`

通过Intent共享文本和图像的完美解决方案是:

在你的分享按钮上点击:

Bitmap image;
shareimagebutton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            URL url = null;
            try {
                url = new URL("https://firebasestorage.googleapis.com/v0/b/fir-notificationdemo-dbefb.appspot.com/o/abc_text_select_handle_middle_mtrl_light.png?alt=media&token=c624ab1b-f840-479e-9e0d-6fe8142478e8");
                image = BitmapFactory.decodeStream(url.openConnection().getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
            shareBitmap(image);
        }
    });

然后创建shareBitmap(image)方法。

private void shareBitmap(Bitmap bitmap) {
    final String shareText = getString(R.string.share_text) + " "
            + getString(R.string.app_name) + " developed by "
            + "https://play.google.com/store/apps/details?id=" + getPackageName() + ": nn";
    try {
        File file = new File(this.getExternalCacheDir(), "share.png");
        FileOutputStream fOut = new FileOutputStream(file);
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
        fOut.flush();
        fOut.close();
        file.setReadable(true, false);
        final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra(Intent.EXTRA_TEXT, shareText);
        intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
        intent.setType("image/png");
        startActivity(Intent.createChooser(intent, "Share image via"));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

然后测试一下…!!

随着更严格的安全策略的实现,在应用程序外部暴露uri会抛出错误并导致应用程序崩溃。

@Ali Tamoor的回答解释了使用文件提供程序,这是推荐的方法。

详细信息请参见- https://developer.android.com/training/secure-file-sharing/setup-sharing

你还需要在你的项目中包含androidx核心库。

implementation "androidx.core:core:1.2.0"

当然,这是一个有点庞大的库,需要它只是为了共享文件-如果有一个更好的方法,请告诉我。

if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
            Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
        Log.d(TAG, "Permission granted");
    } else {
        ActivityCompat.requestPermissions(getActivity(),
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                100);
    }
    fab.setOnClickListener(v -> {
        Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.refer_pic);
        Intent share = new Intent(Intent.ACTION_SEND);
        share.setType("image/*");
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        b.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
        String path = MediaStore.Images.Media.insertImage(requireActivity().getContentResolver(),
                b, "Title", null);
        Uri imageUri = Uri.parse(path);
        share.putExtra(Intent.EXTRA_STREAM, imageUri);
        share.putExtra(Intent.EXTRA_TEXT, "Here is text");
        startActivity(Intent.createChooser(share, "Share via"));
    });
Strring temp="facebook",temp="whatsapp",temp="instagram",temp="googleplus",temp="share";
    if(temp.equals("facebook"))
    {
        Intent intent = getPackageManager().getLaunchIntentForPackage("com.facebook.katana");
        if (intent != null) {
            Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
            shareIntent.setType("image/png");
            shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + "/sdcard/folder name/abc.png"));
            shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            shareIntent.setPackage("com.facebook.katana");
            startActivity(shareIntent);
        }
        else
        {
            Toast.makeText(MainActivity.this, "Facebook require..!!", Toast.LENGTH_SHORT).show();
        }
    }
    if(temp.equals("whatsapp"))
    {
        try {
            File filePath = new File("/sdcard/folder name/abc.png");
            final ComponentName name = new ComponentName("com.whatsapp", "com.whatsapp.ContactPicker");
            Intent oShareIntent = new Intent();
            oShareIntent.setComponent(name);
            oShareIntent.setType("text/plain");
            oShareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Website : www.google.com");
            oShareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(filePath));
            oShareIntent.setType("image/jpeg");
            oShareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            MainActivity.this.startActivity(oShareIntent);

        } catch (Exception e) {
            Toast.makeText(MainActivity.this, "WhatsApp require..!!", Toast.LENGTH_SHORT).show();
        }
    }
    if(temp.equals("instagram"))
    {
        Intent intent = getPackageManager().getLaunchIntentForPackage("com.instagram.android");
        if (intent != null)
        {
            File filePath =new File("/sdcard/folder name/"abc.png");
            Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
            shareIntent.setType("image");
            shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + "/sdcard/Chitranagari/abc.png"));
            shareIntent.setPackage("com.instagram.android");
            startActivity(shareIntent);
        }
        else
        {
            Toast.makeText(MainActivity.this, "Instagram require..!!", Toast.LENGTH_SHORT).show();
        }
    }
    if(temp.equals("googleplus"))
    {
        try
        {
            Calendar c = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
            String strDate = sdf.format(c.getTime());
            Intent shareIntent = ShareCompat.IntentBuilder.from(MainActivity.this).getIntent();
            shareIntent.setType("text/plain");
            shareIntent.putExtra(Intent.EXTRA_TEXT, "Website : www.google.com");
            shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + "/sdcard/folder name/abc.png"));
            shareIntent.setPackage("com.google.android.apps.plus");
            shareIntent.setAction(Intent.ACTION_SEND);
            startActivity(shareIntent);
        }catch (Exception e)
        {
            e.printStackTrace();
            Toast.makeText(MainActivity.this, "Googleplus require..!!", Toast.LENGTH_SHORT).show();
        }
    }
    if(temp.equals("share")) {
        File filePath =new File("/sdcard/folder name/abc.png");  //optional //internal storage
        Intent shareIntent = new Intent();
        shareIntent.setAction(Intent.ACTION_SEND);
        shareIntent.putExtra(Intent.EXTRA_TEXT, "Website : www.google.com");
        shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(filePath));  //optional//use this when you want to send an image
        shareIntent.setType("image/jpeg");
        shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        startActivity(Intent.createChooser(shareIntent, "send"));
    }

最新更新