产品需求:

  微信分享多图至好友,朋友圈。由于微信禁用了分享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保存多张图片到本地

APP分享多张图片到微信和朋友圈的更多相关文章

  1. [h5+api]移动app开发用到的微信好友,朋友圈,qq好友,新浪微博分享合集

    适用H5+环境,能够使用plus方法的移动app中 /** * Created by HBuilder. * User: tyx * Date: 2018-11-21 * Time: 17:28:51 ...

  2. Android 调用系统分享文字、图片、文件,可直达微信、朋友圈、QQ、QQ空间、微博

    原文:Android 调用系统分享文字.图片.文件,可直达微信.朋友圈.QQ.QQ空间.微博 兼容SDK 18以上的系统,直接调用系统分享功能,分享文本.图片.文件到第三方APP,如:微信.QQ.微博 ...

  3. H5+ 分享到微信、朋友圈代码示例

    h5+分享到微信.朋友圈代码示例 在使用分享功能的时候会莫名的分享失败,debug时发现是图片过大的问题. 图片过大时ios平台上返回错误码-8,安卓上返回错误码-3(我测试是这样) 因此如果第一次分 ...

  4. Android分享到微信和朋友圈的工具类

    1.只要填写上正确的app_id,且引用上该工具类你就能实现分享到朋友圈和分享到微信. 2.需要到微信平台下载jar包,以及注册一个appid import android.content.Conte ...

  5. Apple Watch版微信来了 收发微信刷朋友圈不在话下

    昨晚果粉守了一夜的Apple Watch发布会,意料中的惊喜不少,最让人兴奋的是微信成为首批支持的应用.是的,在全球拥有4.68亿月活跃用户的微信怎么可能不第一时间入驻呢?之前我们就有聊过Apple ...

  6. 在小程序内点击按钮分享H5网页给好友或者朋友圈

    在小程序内点击按钮分享H5网页给好友或者朋友圈 首先需要建立h5容器文件夹 页面.wxml <navigator url="/pages/report-await/fouryearh5 ...

  7. H5分享到微信好友朋友圈QQ好友QQ空间微博二维码

    这是分享按钮: <button onclick="call()">通用分享</button> <button onclick="call(' ...

  8. Android 分享微信好友 朋友圈

    第三方应用,可以调用微信分享,把链接,文字,各种media,分享到微信好友或者微信朋友圈,步骤: package com.edaixi.utils; import android.content.Co ...

  9. 关于APP分享到QQ、微信等

    <script> var shares=null;        var Intent=null,File=null,Uri=null,main=null; function plusRe ...

随机推荐

  1. 《python 网络数据采集》代码更新

    <python 网络数据采集>这本书中会出现很多这一段代码: 1 from urllib.request import urlopen 2 from bs4 import Beautifu ...

  2. mysql间隙锁 转

    前面一文 mysql锁 介绍了mysql innodb存储引擎的各种锁,本文介绍一下innodb存储引擎的间隙锁,就以下问题展开讨论 1.什么是间隙锁?间隙锁是怎样产生的? 2.间隙锁有什么作用? 3 ...

  3. MySQL备份和恢复[3]-mysqldump备份工具

    mysqldump 概述 逻辑备份工具: mysqldump, mydumper, phpMyAdmin Schema和数据存储在一起.巨大的SQL语句.单个巨大的备份文件 mysqldump:是My ...

  4. axb_2019_heap-format_string + off-by-one

    axb_2019_heap 简单题,格式化字符串泄漏栈地址 算上rsp,格式化字符串参数是栈顺序+6-1 edit有off by one 构造unlink chunk0 chunk1 chunk2 构 ...

  5. [String] intern()方法

    intern()方法设计的初衷,就是重用String对象,以节省内存消耗. JDK1.6以及以前版本中,常量池是放在 Perm 区(属于方法区)中的,熟悉JVM的话应该知道这是和堆区完全分开的. 使用 ...

  6. 常用物联网应用层协议(1)——先说HTTP协议

    概念 简介 HTTP是一个属于应用层的面向对象的协议,目前使用最为广泛的是HTTP1.1协议.当然,许多网站已经开始支持HTTP2.0,HTTP2复杂度高于HTTP1.1,我们先从HTTP1.1说起. ...

  7. 实用!8个 chrome插件玩转GitHub,单个文件下载小意思

    作为程序员对 GitHub 应该都不会陌生,我经常沉迷其中,找一些惊艳的项目或者工具.不过用的时间久了,发现它的用户体验实在是不敢恭维,有时候会让你做很多重复操作,浪费不少时间. 比如我想单独下载一个 ...

  8. error:docker-ce conflicts with 2:docker-1.13.1-74.git6e3bb8e.el7.centos.x86_64

    问题原因:安装docker之前有安装cockpit-docker服务 解决方法:卸载docker-ce [root@localhost ~]# yum list installed | grep do ...

  9. ansible-hoc命令行

    ansible一种开源的自动化工具 ansible: hoc命令行: 是一款开源的自动化运维工具 python paramiko #模拟ssh协议批量管理主机 jinja2 #模板语言,主要用来传递变 ...

  10. java开发-前后端分离

    众所周知,做java开发是后端的开发,我们时常与前端打交道,但更加注重后端代码的实现,前台的页面都是由前端开发人员做的,那么,是怎么做到前后端分离的呢? 首先,是后端的开发, 在mapper层:Stu ...