APP分享多张图片到微信和朋友圈 - Tears_fg

时间:2024-03-03 17:53:21

APP分享多张图片到微信和朋友圈

产品需求:

  微信分享多图至好友,朋友圈。由于微信禁用了分享9图至朋友圈功能,这里分享微信只是将图片保存至本地,具体让用户手动分享。

问题分析:

  微信没有提供分享多图的SDK,因此我们实现调用系统自带的分享功能。将分享的图片保存至本地,再调用系统本地的分享实现分享多图操作。

具体实现:

  这里保存图片实现用了两种方式:

  1. 使用网络请求下载图片。
  2. 使用Glide加载图片。

    2.1 将请求网络的图片转化成bitmap,再将bitmap图片保存至本地相册。

    2.2 获取缓存至本地的文件,再将文件保存至指定目录,更新相册。

   注意:保存图片至系统相册目录时,只能在主线程实现。推断里面使用了IO流的原因。

一、分享多图至微信

 AtomicInteger count = new AtomicInteger();
        ArrayList<Observable<File>> observables = new ArrayList<>();
        List<Uri> imageUris = new ArrayList<Uri>();
        mCommitDialog = WeiboDialogUtils.createLoadingDialog(this, "正在加载...");
            observables.add(Observable.fromIterable(imageList).flatMap(new Function<String, ObservableSource<File>>() {
                @Override
                public ObservableSource<File> apply(String imagePath) throws Exception {
                    return Observable.create(new ObservableOnSubscribe<File>() {
                        @Override
                        public void subscribe(ObservableEmitter<File> emitter) throws Exception {
                            File file = PhotoUtils.saveImageToSdCard(getActivity(), imagePath);
                            emitter.onNext(file);
                        }
                    });
                }
            }).subscribeOn(Schedulers.io()));

        Observable.merge(observables).map(new Function<File, Boolean>() {
            @Override
            public Boolean apply(File f) throws Exception {
                File file = new File(f.getAbsolutePath());
                if(file.exists()) {
                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {//android 7.0以下
                        imageUris.add(Uri.fromFile(file));
                    } else {//android 7.0及以上
                        Uri uri = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), file.getAbsolutePath(), file.getName(), null));
                        imageUris.add(uri);
                    }
                    return true;
                }
                return false;
            }}).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean a) throws Exception {
                        if(a)  count.addAndGet(1);
                        if(imageList.size() == count.get()){
                            mCommitDialog.dismiss();
//                            showMessage(R.string.text_share_success );
                            //分享到微信好友
                            Intent intent = new Intent();
                            ComponentName componentName = new ComponentName("com.tencent.mm", "com.tencent.mm.ui.tools.ShareImgUI");
                            if (imageUris.size() == 0) return;
                            intent.setComponent(componentName);
                            intent.setAction(Intent.ACTION_SEND_MULTIPLE);
                            intent.setType("image/*");
                            intent.putExtra(Intent.EXTRA_STREAM, (Serializable) imageUris);
                            startActivity(intent);
                        }

                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        mCommitDialog.dismiss();
                        showMessage(R.string.text_save_failed);
                    }
                }, new Action() {
                    @Override
                    public void run() throws Exception {

                    }
                })
        ;

saveImageToSdCard方法如下。

 //根据网络图片url路径保存到本地
    public static final File saveImageToSdCard(Context context, String image) {
        boolean success = false;
        File file = null;
        try {
            file = createStableImageFile(context);
            Bitmap bitmap = null;
            URL url = new URL(image);
            HttpURLConnection conn = null;
            conn = (HttpURLConnection) url.openConnection();
            InputStream is = null;
            is = conn.getInputStream();
            bitmap =  BitmapFactory.decodeStream(is);
            FileOutputStream outStream;
            outStream = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
            outStream.flush();
            outStream.close();
            success = true;
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (success) {
            return file;
        } else {
            return null;
        }
    }

二、保存多图至本地。

  1.Glide加载图片生成Bitmap对象。

AtomicInteger count = new AtomicInteger();
        ArrayList<Observable<Boolean>> observables = new ArrayList<>();
        for (String imagePath :
                imageList) {
                observables.add(Observable.create(new ObservableOnSubscribe<Boolean>() {
                    @Override
                    public void subscribe(ObservableEmitter<Boolean> emitter) throws Exception {
                        SimpleTarget<Bitmap> into = Glide.with(getActivity())
                                .asBitmap()
                                .load(imagePath)
                                .into(new SimpleTarget<Bitmap>() {
                                    @Override
                                    public void onResourceReady( Bitmap bitmap, @Nullable Transition<? super Bitmap> transition) {
                                        if (bitmap != null) {
                                            //图片信息不为空时才保存
                                            emitter.onNext( PhotoUtils.savePhoto(getActivity(), DateUtils.formatDate(getActivity(),
                                                    System.currentTimeMillis()) + UUID.randomUUID() + ".png", bitmap));
                                        }
                                    }
                                });
                    }
                }).subscribeOn(AndroidSchedulers.mainThread()));}
                Observable.merge(observables).observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Consumer<Boolean>() {
                            @Override
                            public void accept(Boolean b) throws Exception {
                                if (b) {
                                    count.addAndGet(1);
                                }
                                if(imageList.size() == count.get()){
                                    showHintDialog();
//                                    showMessage(R.string.text_save_pic_success );
                                }

                            }
                        }, new Consumer<Throwable>() {
                            @Override
                            public void accept(Throwable throwable) throws Exception {
                                showMessage(R.string.text_save_pic_failed);
                            }
                        }, new Action() {
                            @Override
                            public void run() throws Exception {

                            }
                        });

  2.Glide加载图片,得到文件形式。

File file = Glide.with(context)
                            .load(images[i])
                            .downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
                            .get()

 

savePhoto方法如下:

 

/**
     * 保存图片
     */
    public static boolean savePhoto(Context context, String fileName, Bitmap bitmap) {
        //系统相册目录
        String galleryPath = Environment.getExternalStorageDirectory()
                + File.separator + Environment.DIRECTORY_DCIM
                + File.separator + "Camera" + File.separator;
        File imagePath = new File(galleryPath);
        if (!imagePath.exists()) {
            imagePath.mkdirs();
        }    
        File fileUri = new File(imagePath + File.separator + fileName);
        if (!fileUri.exists()) {
            try {
                fileUri.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        Uri imgUri = Uri.fromFile(fileUri);
       
        try {
            FileOutputStream out = new FileOutputStream(fileUri);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            out.flush();
            out.close();
            Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            intent.setData(imgUri);
            context.sendBroadcast(intent);
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return false;
    }

 

注意:这里要申请权限。

 

参考博客:

1.APP分享多张图片和文字到微信朋友圈(android 7.0以上适配)

2.Android保存多张图片到本地