Sharing Bitmap via Android Intent

后端 未结 8 1534
名媛妹妹
名媛妹妹 2020-12-02 17:35

In my android app, I have a bitmap (say b) and a button. Now when I click on the button, I want to share the bitmap. I am making use of the below code inside my onClic

相关标签:
8条回答
  • 2020-12-02 17:39
    private void sharePalette(Bitmap bitmap) {
    
     String bitmapPath = MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, "palette", "share palette");
        Uri bitmapUri = Uri.parse(bitmapPath);
    
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("image/png");
        intent.putExtra(Intent.EXTRA_STREAM, bitmapUri);
        startActivity(Intent.createChooser(intent, "Share"));
    }
    
    0 讨论(0)
  • 2020-12-02 17:41

    ** finally i got the solution.**

    Step 1 : Share Intent handling Block. This will Pop Up your window with list of Applications in you phone

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

    Step 2 : Converting your view to BItmap

    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;
    }
    

    Step 3 :

    To get The URI from Bitmap Image

    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);
    }
    
    0 讨论(0)
  • 2020-12-02 17:42

    I found 2 variants of the solution. Both involve saving Bitmap to storage, but the image will not appear in the gallery.

    First variant:

    Saving to external storage

    • but to private folder of the app.
    • for API <= 18 it requires permission, for newer it does not.

    1. Setting permissions

    Add into AndroidManifest.xml before tag

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

    2. Saving method:

     /**
     * Saves the image as PNG to the app's private external storage folder.
     * @param image Bitmap to save.
     * @return Uri of the saved file or null
     */
    private Uri saveImageExternal(Bitmap image) {
        //TODO - Should be processed in another thread
        Uri uri = null;
        try {
            File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "to-share.png");
            FileOutputStream stream = new FileOutputStream(file);
            image.compress(Bitmap.CompressFormat.PNG, 90, stream);
            stream.close();
            uri = Uri.fromFile(file);
        } catch (IOException e) {
            Log.d(TAG, "IOException while trying to write file for sharing: " + e.getMessage());
        }
        return uri;
    }
    

    3. Checking storage accesibility

    External storage might not be accessible, so you should check it before trying to save: https://developer.android.com/training/data-storage/files

    /**
     * Checks if the external storage is writable.
     * @return true if storage is writable, false otherwise
     */
    public boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            return true;
        }
        return false;
    }
    

    Second variant

    Saving to cacheDir using FileProvider. It does not require any permissions.

    1. Setup FileProvider in AndroidManifest.xml

    <manifest>
        ...
        <application>
            ...
            <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="com.mydomain.fileprovider"
                android:exported="false"
                android:grantUriPermissions="true">
                    <meta-data
                        android:name="android.support.FILE_PROVIDER_PATHS"
                        android:resource="@xml/file_paths" />
            </provider>
            ...
        </application>
    </manifest>
    

    2. Add path to the res/xml/file_paths.xml

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

    3. Saving method:

     /**
     * Saves the image as PNG to the app's cache directory.
     * @param image Bitmap to save.
     * @return Uri of the saved file or null
     */
    private Uri saveImage(Bitmap image) {
        //TODO - Should be processed in another thread
        File imagesFolder = new File(getCacheDir(), "images");
        Uri uri = null;
        try {
            imagesFolder.mkdirs();
            File file = new File(imagesFolder, "shared_image.png");
    
            FileOutputStream stream = new FileOutputStream(file);
            image.compress(Bitmap.CompressFormat.PNG, 90, stream);
            stream.flush();
            stream.close();
            uri = FileProvider.getUriForFile(this, "com.mydomain.fileprovider", file);
    
        } catch (IOException e) {
            Log.d(TAG, "IOException while trying to write file for sharing: " + e.getMessage());
        }
        return uri;
    }
    

    More info about file provider - https://developer.android.com/reference/android/support/v4/content/FileProvider

    Compressing and saving can be time-consuming, therefore this should be done in a different thread

    Actual sharing

    /**
     * Shares the PNG image from Uri.
     * @param uri Uri of image to share.
     */
    private void shareImageUri(Uri uri){
        Intent intent = new Intent(android.content.Intent.ACTION_SEND);
        intent.putExtra(Intent.EXTRA_STREAM, uri);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.setType("image/png");
        startActivity(intent);
    }
    
    0 讨论(0)
  • 2020-12-02 17:48

    After spending a lot of time on this:

    Check if permissions are given. Then:

    Step 1: Create ImageView of the image you want to in the activity and then convert it itno bitmap

    ImageView imageView = findViewById(R.id.image);
    Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
    
    //save the image now:
    saveImage(bitmap);
    //share it
    send();
    

    Step 2: Store the image in internal folder:

    private static void saveImage(Bitmap finalBitmap) {
    
        String root = Environment.getExternalStorageDirectory().getAbsolutePath();
        File myDir = new File(root + "/saved_images");
        Log.i("Directory", "==" + myDir);
        myDir.mkdirs();
    
        String fname = "Image-test" + ".jpg";
        File file = new File(myDir, fname);
        if (file.exists()) file.delete();
        try {
            FileOutputStream out = new FileOutputStream(file);
            finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
            out.flush();
            out.close();
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    Step 3: Send the saved image:

    public void send() {
        try {
            File myFile = new File("/storage/emulated/0/saved_images/Image-test.jpg");
            MimeTypeMap mime = MimeTypeMap.getSingleton();
            String ext = myFile.getName().substring(myFile.getName().lastIndexOf(".") + 1);
            String type = mime.getMimeTypeFromExtension(ext);
            Intent sharingIntent = new Intent("android.intent.action.SEND");
            sharingIntent.setType(type);
            sharingIntent.putExtra("android.intent.extra.STREAM", Uri.fromFile(myFile));
            startActivity(Intent.createChooser(sharingIntent, "Share using"));
        } catch (Exception e) {
            Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }
    

    Now after sending you can delete the saved image if you don't want it in your storage. Check other link to do that.

    0 讨论(0)
  • 2020-12-02 17:59
    ImageButton capture_share = (ImageButton) findViewById(R.id.share);
    capture_share.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
    
        String bitmapPath = MediaStore.Images.Media.insertImage(getContentResolver(), bitmap,"title", null);
        Uri bitmapUri = Uri.parse(bitmapPath);
    
            Intent intent = new Intent(Intent.ACTION_SEND);
            intent.setType("image/png");
            intent.putExtra(Intent.EXTRA_STREAM, bitmapUri);
            startActivity(Intent.createChooser(intent, "Share"));
      }
    });
    
    0 讨论(0)
  • 2020-12-02 18:01

    Quoting the documentation:

    A content: URI holding a stream of data associated with the Intent, used with ACTION_SEND to supply the data being sent.

    b, therefore, is not supposed to be a Bitmap, but rather a Uri pointing to a Bitmap, served by a ContentProvider. For example, you could write the Bitmap to a file, then use FileProvider to serve it.

    0 讨论(0)
提交回复
热议问题