简体   繁体   English

如何以编程方式从图库中将图像共享到 WhatsApp?

[英]How to share Image to WhatsApp from Gallery programmatically?

I tried the following code to share an image to WhatsApp.我尝试使用以下代码将图像共享给 WhatsApp。 For now, I manually added the image path.现在,我手动添加了图像路径。

I want to open the gallery when the user clicks a button in my application and he must be able to select an image to share in WhatsApp.我想在用户单击我的应用程序中的按钮时打开图库,并且他必须能够选择要在 WhatsApp 中共享的图像。

How can I do that?我怎样才能做到这一点?

PS: I need to set the image path dynamically PS:我需要动态设置图片路径

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Toast.makeText(MainActivity.this, "Testing Button", Toast.LENGTH_SHORT).show();

        File f=new File("/sdcard/Download/myimage.jpg");
        Uri uri = Uri.parse("file://"+f.getAbsolutePath());
        Intent share = new Intent(Intent.ACTION_SEND);
        share.setPackage("com.whatsapp");
        share.putExtra(Intent.EXTRA_STREAM, uri);
        share.setType("image/*");
        share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        v.getContext().startActivity(Intent.createChooser(share, "Share image File"));
    }
});

You can use the below code to dynamically get the image Uri.您可以使用以下代码动态获取图像 Uri。 It will work on all versions of Android.它适用于所有版本的 Android。

MainActivity主要活动

public class MainActivity extends Activity {

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


        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("image/*");
        startActivityForResult(intent, 0);
    }

    @Override
     protected void onActivityResult(int reqCode, int resCode, Intent data) {
        if(resCode == Activity.RESULT_OK && data != null){
            String realPath;

            if (Build.VERSION.SDK_INT < 11)
                realPath = RealPathUtil.getRealPathFromURI_BelowAPI11(this, data.getData());


            else if (Build.VERSION.SDK_INT < 19)
                realPath = RealPathUtil.getRealPathFromURI_API11to18(this, data.getData());


            else
                realPath = RealPathUtil.getRealPathFromURI_API19(this, data.getData());


            getImageInfo(Build.VERSION.SDK_INT, data.getData().getPath(),realPath);
        }
    }

    private void getImageInfo(int sdk, String uriPath,String realPath){

        Uri uriFromPath = Uri.fromFile(new File(realPath));
        Log.d("Log", "Build.VERSION.SDK_INT:"+sdk);
        Log.d("Log", "URI Path:"+uriPath);
        Log.d("Log", "Real Path: "+realPath);
    }
}

RealPathUtil.java RealPathUtil.java

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

public class RealPathUtil {

    @SuppressLint("NewApi")
    public static String getRealPathFromURI_API19(Context context, Uri uri){
        String filePath = "";
        String wholeID = DocumentsContract.getDocumentId(uri);

         // Split at colon, use second item in the array
         String id = wholeID.split(":")[1];

         String[] column = { MediaStore.Images.Media.DATA };     

         // where id is equal to             
         String sel = MediaStore.Images.Media._ID + "=?";

         Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
                                   column, sel, new String[]{ id }, null);

         int columnIndex = cursor.getColumnIndex(column[0]);

         if (cursor.moveToFirst()) {
             filePath = cursor.getString(columnIndex);
         }   
         cursor.close();
         return filePath;
    }


    @SuppressLint("NewApi")
    public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
          String[] proj = { MediaStore.Images.Media.DATA };
          String result = null;

          CursorLoader cursorLoader = new CursorLoader(
                  context, 
            contentUri, proj, null, null, null);        
          Cursor cursor = cursorLoader.loadInBackground();

          if(cursor != null){
           int column_index = 
             cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
           cursor.moveToFirst();
           result = cursor.getString(column_index);
          }
          return result;  
    }

    public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri){
               String[] proj = { MediaStore.Images.Media.DATA };
               Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
               int column_index
          = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
               cursor.moveToFirst();
               return cursor.getString(column_index);
    }
}

Add this Permission to Manifest.xml将此权限添加到 Manifest.xml

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

In Android 6+, You need to request the Permission during RunTime.在 Android 6+ 中,您需要在运行时请求权限。

base64 image share on any media在任何媒体上共享 base64 图像

public void shareImage() {
    try {

        File cachePath = new File(context.getCacheDir(), "images");
        cachePath.mkdirs(); // don't forget to make the directory
        FileOutputStream stream = new FileOutputStream(new File(cachePath, "image.png")); // overwrites this image every time
        Bitmap bitmap = ((BitmapDrawable) imagePhoto.getDrawable()).getBitmap();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        stream.close();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    File imagePath = new File(context.getCacheDir(), "images");
    File newFile = new File(imagePath, "image.png");
    Uri contentUri = FileProvider.getUriForFile(context, "com.appynitty.adminapp.fileprovider", newFile);

    if (contentUri != null) {

        Intent shareIntent = new Intent();
        shareIntent.setAction(Intent.ACTION_SEND);
        shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // temp permission for receiving app to read this file
        shareIntent.setDataAndType(contentUri, getContentResolver().getType(contentUri));
        shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
        startActivity(Intent.createChooser(shareIntent, "Choose an app"));

    }
}

base64 image save in galary base64图像保存在galary中

void SaveImageToSDCard(String Image) {
    try {
        byte[] imageBytes = Base64.decode(Image, Base64.DEFAULT);
        Log.e(TAG, "SaveImageToSDCard: imageBytes: " + imageBytes);
        InputStream is = new ByteArrayInputStream(imageBytes);
        Bitmap image = ((BitmapDrawable) imagePhoto.getDrawable()).getBitmap();

        String mBaseFolderPath = Environment.getExternalStoragePublicDirectory(DIRECTORY_PICTURES) + "/HouseScanify/";

        if (!new File(mBaseFolderPath).exists()) {
            new File(mBaseFolderPath).mkdirs();
        }
        String mFilePath = mBaseFolderPath + "/" + System.currentTimeMillis() + ".jpg";

        File file = new File(mFilePath);

        FileOutputStream stream = new FileOutputStream(file);

        if (!file.exists()) {
            file.createNewFile();
        }

        image.compress(Bitmap.CompressFormat.JPEG, 100, stream);

        is.close();

        stream.flush();
        stream.close();
        DynamicToast.makeSuccess(context, "Saved successfully!").show();

    } catch (Exception e) {
        Log.v("SaveFile", "" + e);
    }
}

storage permission存储权限

public boolean isStoragePermissionGranted() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED) {
            Log.v(TAG, "Permission is granted");
            return true;
        } else {

            Log.v(TAG, "Permission is revoked");
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 2);
            return false;
        }
    } else { //permission is automatically granted on sdk<23 upon installation
        Log.v(TAG, "Permission is granted");
        return true;
    }
}

on click点击

private void setOnClick() {
    imgDownload.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (qrImage != null || !qrImage.isEmpty()) {
                if (isStoragePermissionGranted())
                    SaveImageToSDCard(qrImage);
            } else {
                DynamicToast.makeError(context, "Invalid image!").show();
            }
        }
    });
    imgShareZ.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            shareImage();
        
        }
    });
}

touch image view to seen everywher触摸图像视图随处可见

public class TouchImageView extends androidx.appcompat.widget.AppCompatImageView {

Matrix matrix;

// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;

// Remember some things for zooming
PointF last = new PointF();
PointF start = new PointF();
float minScale = 1f;
float maxScale = 3f;
float[] m;

int viewWidth, viewHeight;
static final int CLICK = 3;
float saveScale = 1f;
protected float origWidth, origHeight;
int oldMeasuredWidth, oldMeasuredHeight;

ScaleGestureDetector mScaleDetector;

Context context;

public TouchImageView(Context context) {
    super(context);
    sharedConstructing(context);
}

public TouchImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    sharedConstructing(context);
}

private void sharedConstructing(Context context) {
    super.setClickable(true);
    this.context = context;
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    matrix = new Matrix();
    m = new float[9];
    setImageMatrix(matrix);
    setScaleType(ScaleType.MATRIX);

    setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            mScaleDetector.onTouchEvent(event);
            PointF curr = new PointF(event.getX(), event.getY());

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    last.set(curr);
                    start.set(last);
                    mode = DRAG;
                    break;

                case MotionEvent.ACTION_MOVE:
                    if (mode == DRAG) {
                        float deltaX = curr.x - last.x;
                        float deltaY = curr.y - last.y;
                        float fixTransX = getFixDragTrans(deltaX, viewWidth,
                                origWidth * saveScale);
                        float fixTransY = getFixDragTrans(deltaY, viewHeight,
                                origHeight * saveScale);
                        matrix.postTranslate(fixTransX, fixTransY);
                        fixTrans();
                        last.set(curr.x, curr.y);
                    }
                    break;

                case MotionEvent.ACTION_UP:
                    mode = NONE;
                    int xDiff = (int) Math.abs(curr.x - start.x);
                    int yDiff = (int) Math.abs(curr.y - start.y);
                    if (xDiff < CLICK && yDiff < CLICK)
                        performClick();
                    break;

                case MotionEvent.ACTION_POINTER_UP:
                    mode = NONE;
                    break;
            }

            setImageMatrix(matrix);
            invalidate();
            return true; // indicate event was handled
        }

    });
}

public void setMaxZoom(float x) {
    maxScale = x;
}

private class ScaleListener extends
        ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        mode = ZOOM;
        return true;
    }

    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        float mScaleFactor = detector.getScaleFactor();
        float origScale = saveScale;
        saveScale *= mScaleFactor;
        if (saveScale > maxScale) {
            saveScale = maxScale;
            mScaleFactor = maxScale / origScale;
        } else if (saveScale < minScale) {
            saveScale = minScale;
            mScaleFactor = minScale / origScale;
        }

        if (origWidth * saveScale <= viewWidth
                || origHeight * saveScale <= viewHeight)
            matrix.postScale(mScaleFactor, mScaleFactor, viewWidth / 2,
                    viewHeight / 2);
        else
            matrix.postScale(mScaleFactor, mScaleFactor,
                    detector.getFocusX(), detector.getFocusY());

        fixTrans();
        return true;
    }
}

void fixTrans() {
    matrix.getValues(m);
    float transX = m[Matrix.MTRANS_X];
    float transY = m[Matrix.MTRANS_Y];

    float fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale);
    float fixTransY = getFixTrans(transY, viewHeight, origHeight
            * saveScale);

    if (fixTransX != 0 || fixTransY != 0)
        matrix.postTranslate(fixTransX, fixTransY);
}

float getFixTrans(float trans, float viewSize, float contentSize) {
    float minTrans, maxTrans;

    if (contentSize <= viewSize) {
        minTrans = 0;
        maxTrans = viewSize - contentSize;
    } else {
        minTrans = viewSize - contentSize;
        maxTrans = 0;
    }

    if (trans < minTrans)
        return -trans + minTrans;
    if (trans > maxTrans)
        return -trans + maxTrans;
    return 0;
}

float getFixDragTrans(float delta, float viewSize, float contentSize) {
    if (contentSize <= viewSize) {
        return 0;
    }
    return delta;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    viewWidth = MeasureSpec.getSize(widthMeasureSpec);
    viewHeight = MeasureSpec.getSize(heightMeasureSpec);

    //
    // Rescales image on rotation
    //
    if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight
            || viewWidth == 0 || viewHeight == 0)
        return;
    oldMeasuredHeight = viewHeight;
    oldMeasuredWidth = viewWidth;

    if (saveScale == 1) {
        // Fit to screen.
        float scale;

        Drawable drawable = getDrawable();
        if (drawable == null || drawable.getIntrinsicWidth() == 0
                || drawable.getIntrinsicHeight() == 0)
            return;
        int bmWidth = drawable.getIntrinsicWidth();
        int bmHeight = drawable.getIntrinsicHeight();

        Log.d("bmSize", "bmWidth: " + bmWidth + " bmHeight : " + bmHeight);

        float scaleX = (float) viewWidth / (float) bmWidth;
        float scaleY = (float) viewHeight / (float) bmHeight;
        scale = Math.min(scaleX, scaleY);
        matrix.setScale(scale, scale);

        // Center the image
        float redundantYSpace = (float) viewHeight
                - (scale * (float) bmHeight);
        float redundantXSpace = (float) viewWidth
                - (scale * (float) bmWidth);
        redundantYSpace /= (float) 2;
        redundantXSpace /= (float) 2;

        matrix.postTranslate(redundantXSpace, redundantYSpace);

        origWidth = viewWidth - 2 * redundantXSpace;
        origHeight = viewHeight - 2 * redundantYSpace;
        setImageMatrix(matrix);
    }
    fixTrans();
}

} }

Thank you谢谢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM