微信开放平台
需要先注册开发这账号
创建应用注意事项
点击下载 签名生成工具
官方文档
1.申请你的 AppID
请到 开发者应用登记页面 进行登记,登记并选择移动应用进行设置后,将该应用提交审核,只有审核通过的应用才能进行开发。
2. 添加依赖
在app模块的build.gradle文件中
dependencies {
api 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
}
(从5.4.3版本开始,wechat-sdk-android-with-mta不再维护)
3.搭建开发环境
Android Studio 环境下:
在 Android Studio 中新建你的工程,并保证网络设置可以成功从 jcenter 下载微信 SDK 即可。
4. 添加权限
添加必要的权限支持(其中网络权限如果没有使用扫码登录功能非必要;后三个权限,如果没有使用 mta,也非必要,即使有使用 mta,去掉也不影响功能):
<uses-permission android:name="android.permission.INTERNET" />
<!-- for mta statistics, not necessary-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
5. 注册到微信
要使你的程序启动后微信终端能响应你的程序,必须在代码中向微信终端注册你的 id。(可以在程序入口 Activity 的 onCreate 回调函数处,或其他合适的地方将你的应用 id 注册到微信。
public class ShareApplication extends Application {
private static final String APP_ID = "wx88888888";
// IWXAPI 是第三方app和微信通信的openApi接口
private IWXAPI api;
@Override
public void onCreate() {
super.onCreate();
// 通过WXAPIFactory工厂,获取IWXAPI的实例
// 三个参数分别是上下文、应用的appId、是否检查签名(默认为false)
api = WXAPIFactory.createWXAPI(this, APP_ID, true);
// 将应用的appId注册到微信
api.registerApp(APP_ID);
//建议动态监听微信启动广播进行注册到微信
/* registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 将该app注册到微信
api.registerApp(APP_ID);
}
}, new IntentFilter(ConstantsAPI.ACTION_REFRESH_WXAPP));*/
}
}
如果需要混淆代码,为了保证 sdk 的正常使用,需要在 proguard.cfg 加上下面两行配置:
-keep class com.tencent.mm.opensdk.** {
*;
}
-keep class com.tencent.wxop.** {
*;
}
-keep class com.tencent.mm.sdk.** {
*;
}
如果你的程序需要接收微信发送的请求,或者接收发送到微信请求的响应结果,需要下面 操作:
在你的包名相应目录下新建一个 wxapi 目录,并在该 wxapi 目录下新增一个 WXEntryActivity 类,该类继承自 Activity
并在 manifest 文件里面加上 exported 属性,设置为 true,例如:
<activity
android:name=".wxapi.WXEntryActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Translucent.NoTitleBar">activity>
WXEntryActivity
实现 IWXAPIEventHandler 接口,微信发送的请求将回调到 onReq 方法,发送到微信请求的响应结果将回调到 onResp 方法。
在 WXEntryActivity 中将接收到的 intent 及实现了 IWXAPIEventHandler 接口的对象传递给 IWXAPI 接口的 handleIntent 方法。
当微信发送请求到你的应用,将通过 IWXAPIEventHandler 接口的 onReq 方法进行回调,类似的,应用请求微信的响应结果将通过 onResp 回调。
/**
* Cerated by xiaoyehai
* Create date : 2019/11/15 17:31
* description : 分享到微信和微信朋友圈的回调
*
* SendMessageToWX.Req.WXSceneSession(0):是分享到好友会话
* SendMessageToWX.Req.WXSceneTimeline(1):是分享到朋友圈
* 微信 4.2 以上版本支持才支持分享到朋友圈
*/
public class WXEntryActivity extends AppCompatActivity implements IWXAPIEventHandler {
//IWXAPI 是第三方app和微信通信的openApi接口
private IWXAPI iwxapi;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_test);
//如果没回调onResp,八成是这句没有写
iwxapi = WXAPIFactory.createWXAPI(this, Constants.WX_APP_ID, false);
iwxapi.handleIntent(getIntent(), this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
iwxapi.handleIntent(intent, this);
}
/**
* 微信发送的请求将回调到 onReq 方法
*
* @param baseReq
*/
@Override
public void onReq(BaseReq baseReq) {
}
/**
* 发送到微信请求的响应结果将回调到 onResp 方法
*
* @param resp
*/
@Override
public void onResp(BaseResp resp) {
String result;
switch (resp.errCode) {
case BaseResp.ErrCode.ERR_OK:
result = "分享成功";
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
result = "取消分享";
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
result = "分享被拒绝";
break;
default:
result = "发送返回";
break;
}
Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
finish();
}
}
WxShareHelper:封装分享功能
该类只封装了一些简单的分享功能,如果需要分享其他类型的数据,请参考官方文档
/**
* Cerated by xiaoyehai
* Create date : 2019/12/4 22:06
* description :微信分享帮助类
*
* 分享到对话:SendMessageToWX.Req.WXSceneSession
* 分享到朋友圈:SendMessageToWX.Req.WXSceneTimeline
*/
public class WxShareHelper {
//分享到微信
public static final int WX_SCENE = SendMessageToWX.Req.WXSceneSession;
//分享到朋友圈
public static final int TIMELINE_SCENE = SendMessageToWX.Req.WXSceneSession;
private static WxShareHelper mInstance = new WxShareHelper();
private WxShareHelper() {
}
public static WxShareHelper getInstnce() {
return mInstance;
}
/**
* 判断是否安装微信
*
* @param context
*/
private void checkInstallWx(Context context) {
IWXAPI wxapi = WXAPIFactory.createWXAPI(context, Constants.WX_APP_ID);
if (!wxapi.isWXAppInstalled()) {
Toast.makeText(context, "对不起,您没有安装微信", Toast.LENGTH_SHORT).show();
return;
}
}
/**
* 分享文本到微信
*
* @param context
* @param scene
*/
public void shareTextToWX(Context context, int scene) {
checkInstallWx(context);
// 通过appId得到IWXAPI这个对象
IWXAPI wxapi = WXAPIFactory.createWXAPI(context, Constants.WX_APP_ID);
//初始化一个 WXTextObject 对象,填写分享的文本内容
WXTextObject textObj = new WXTextObject();
textObj.text = "我是分享到微信的数据";
//用 WXTextObject 对象初始化一个 WXMediaMessage 对象
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = textObj;
msg.description = "描述";
SendMessageToWX.Req req = new SendMessageToWX.Req();
//req.transaction = String.valueOf(System.currentTimeMillis()); //transaction字段用与唯一标示一个请求
req.transaction = buildTransaction("text");
req.message = msg;
req.scene = scene;
//调用api接口,发送数据到微信
wxapi.sendReq(req);
}
/**
* 分享网页类型至微信
*
* @param context 上下文
* @param scene
*/
public void shareWebToWX(Context context, int scene) {
checkInstallWx(context);
IWXAPI wxapi = WXAPIFactory.createWXAPI(context, Constants.WX_APP_ID);
// 初始化一个WXWebpageObject对象
WXWebpageObject webpageObject = new WXWebpageObject();
// 填写网页的url
webpageObject.webpageUrl = "https://www.baidu.com/";
// 用WXWebpageObject对象初始化一个WXMediaMessage对象
WXMediaMessage msg = new WXMediaMessage(webpageObject);
// 填写网页标题、描述、位图
msg.title = "网页标题";
msg.description = "网页描述";
//这块需要注意,图片的像素千万不要太大,不然的话会调不起来微信分享
Bitmap thumbBmp = BitmapFactory.decodeResource(context.getResources(), R.drawable.login_logo);
// 如果没有位图,可以传null,会显示默认的图片
msg.setThumbImage(thumbBmp);
// 构造一个Req
SendMessageToWX.Req req = new SendMessageToWX.Req();
// transaction用于唯一标识一个请求(可自定义)
req.transaction = buildTransaction("webpage");
// 上文的WXMediaMessage对象
req.message = msg;
req.scene = scene;
//req.userOpenId = getOpenId();
// 向微信发送请求
wxapi.sendReq(req);
}
/**
* 分享图片到微信,朋友圈
*
* @param context
* @param scene
*/
public void shareBitmapToWX(Context context, int scene) {
checkInstallWx(context);
// 通过appId得到IWXAPI这个对象
IWXAPI wxapi = WXAPIFactory.createWXAPI(context, Constants.WX_APP_ID);
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.login_logo);
//初始化 WXImageObject 和 WXMediaMessage 对象
WXImageObject imgObj = new WXImageObject(bitmap);
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = imgObj;
//设置缩略图
Bitmap thumbBmp = Bitmap.createScaledBitmap(bitmap, 100, 100, true);
bitmap.recycle();
msg.thumbData = bmpToByteArray(thumbBmp, true);
//构造一个Req
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("img");
req.message = msg;
req.scene = scene;
//req.userOpenId = getOpenId();
//调用api接口,发送数据到微信
wxapi.sendReq(req);
}
/**
* 用于解析图片
* 分享的图片大小不能大于32KB,
*
* @param bmp
* @param needRecycle
* @return
*/
public byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
ByteArrayOutputStream output = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, output);
if (needRecycle) {
bmp.recycle();
}
byte[] result = output.toByteArray();
try {
output.close();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 生成transaction
*
* @param type
* @return
*/
private String buildTransaction(final String type) {
return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
}
}
使用
//分享文本
WxShareHelper.getInstnce().shareTextToWX(mContext,WxShareHelper.WX_SCENE);
// 分享网页
WxShareHelper.getInstnce().shareWebToWX(mContext,WxShareHelper.WX_SCENE);
//分享图片
WxShareHelper.getInstnce().shareBitmapToWX(mContext,WxShareHelper.WX_SCENE);
备注:
①.这个不用导入微信的jar和注册微信的APP_ID 。
②. 实际上分享时是调用系统本地的分享功能,所以分享的图片必须要保存到本地。
③. 保存到本地是耗时操作 分享的代码需要在子线程执行 。
分享多张图片
微信平台没有提供分享多张的SDK,我们只能自己调用系统自带的分享功能实现。
在ShareHelper种加入下面代码:
private static final String WX_PACKAGE_NAME = "com.tencent.mm"; //微信包名
private static final String SHARE_IMG_UI = "com.tencent.mm.ui.tools.ShareImgUI"; //分享到微信好友
private static final String SHARE_TO_TIMELINE_UI = "com.tencent.mm.ui.tools.ShareToTimeLineUI"; //分享到微信朋友圈
/**
* 微信7.0版本号,兼容处理微信7.0版本分享到朋友圈不支持多图片的问题
*/
private static final int VERSION_CODE_FOR_WEI_XIN_VER7 = 1380;
/**
* Android调用系统分享的实现;分享单张图片到微信
*
* @param context
* @param imageFile
*/
public void shareSingleImageToWX(Context context, File imageFile) {
//判断是否安装微信,如果没有安装微信 又没有判断就直达微信分享是会挂掉的
if (!Tools.isWeixinAvilible(mContext)) {
Toast.makeText(context, "您还没有安装微信", Toast.LENGTH_SHORT).show();
return;
}
Intent intent = new Intent();
//发送图片给好友
ComponentName componentName = new ComponentName(WX_PACKAGE_NAME, SHARE_IMG_UI);
intent.setComponent(componentName);
intent.setAction(Intent.ACTION_SEND);
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(imageFile));
context.startActivity(intent);
}
/**
* Android调用系统分享的实现:分享多张图片到微信,分享单张图片也可以用该方法
*
* 昨天公司老大通知客户改需求了,原来的微信分享改成分享多张图片,然后屁颠屁颠跑到微信平台看了以后
* 心里千万只草泥马狂奔而过,微信平台没有提供分享多张的SDK有木有啊,我们只能自己调用系统自带的分享功能实现。
*
* 实际分享的时候因为是调用系统本地的分享功能,所以分享的图片也就必须要存到本地,不然就会提示获取资源失败,那就要把图片存到本地了
* 这个是直接调用微信的分享,所以调起分享的时候一定要判断手机里面是否已经安装了微信,如果没有安装还要掉微信分享就是直接崩溃掉。
*
* @param context
* @param imageFileList 保存到本地的图片
*/
public void shareMultiImageToWX(Context context, List<File> imageFileList) {
//判断是否安装微信,如果没有安装微信 又没有判断就直达微信分享是会挂掉的
if (!Tools.isWeixinAvilible(mContext)) {
Toast.makeText(context, "您还没有安装微信", Toast.LENGTH_SHORT).show();
return;
}
ArrayList<Uri> imageUris = new ArrayList<>();
for (File file : imageFileList) {
imageUris.add(Uri.fromFile(file));
}
if (imageUris.size() == 0) {
ToastUtil.showShortToast("获取图片失败");
return;
}
Intent intent = new Intent();
ComponentName componentName = new ComponentName(WX_PACKAGE_NAME, SHARE_IMG_UI);
intent.setComponent(componentName);
intent.setAction(Intent.ACTION_SEND_MULTIPLE);
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_STREAM, imageUris);
context.startActivity(intent);
}
/**
* Android调用系统分享的实现
* 分享多张图片到朋友圈:微信7.0及以上版本,朋友圈只支持单张图片分享
*
* @param context
* @param imageFileList
*/
public void shareMultiImageToWXTimeLine(Context context, List<File> imageFileList) {
//判断是否安装微信,如果没有安装微信 又没有判断就直达微信分享是会挂掉的
if (!Tools.isWeixinAvilible(mContext)) {
Toast.makeText(context, "您还没有安装微信", Toast.LENGTH_SHORT).show();
return;
}
ArrayList<Uri> imageUris = new ArrayList<>();
for (File file : imageFileList) {
imageUris.add(Uri.fromFile(file));
}
if (imageUris.size() == 0) {
ToastUtil.showShortToast("获取图片失败");
return;
}
Intent intent = new Intent();
if (getVersionCode(context, WX_PACKAGE_NAME) < VERSION_CODE_FOR_WEI_XIN_VER7) {
// 微信7.0以下版本
intent.setAction(Intent.ACTION_SEND_MULTIPLE);
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
} else {
// 微信7.0及以上版本,朋友圈只支持单张图片分享
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, imageUris.get(0));
}
ComponentName componentName = new ComponentName(WX_PACKAGE_NAME, SHARE_TO_TIMELINE_UI);
intent.setComponent(componentName);
intent.setType("image/*");
// intent.putExtra("kdescription", "分享描述"); //分享描述
context.startActivity(intent);
}
/**
* 获取制定包名应用的版本的versionCode
*
* @param context
* @param
* @return
*/
public static int getVersionCode(Context context, String packageName) {
try {
PackageManager manager = context.getPackageManager();
PackageInfo info = manager.getPackageInfo(packageName, 0);
int version = info.versionCode;
return version;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
ShareFragment
public class ShareFragment extends BaseFragment {
private List<String> urlList = new ArrayList<>();
@Override
protected int getLayoutId() {
return R.layout.fragment_share;
}
@Override
protected void init() {
urlList.add("https://img.alicdn.com/imgextra/i1/650413329/O1CN01SLxEmg1aSj43VIlHm_!!650413329.jpg");
urlList.add("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2973069531,657782944&fm=26&gp=0.jpg");
urlList.add("http://img.alicdn.com/imgextra/i2/2206462034816/O1CN01mZogLE1lRm0njgsRT_!!2206462034816.jpg");
}
@OnClick(R.id.btn_share)
public void onViewClicked() {
new ShareDialog(getActivity()).setOnItemClickListener(new ShareDialog.OnBottomDialogItemClickListener() {
@Override
public void onClick(Dialog dialog, int position) {
switch (position) {
case 0: //微信
shareToWX();
break;
case 1: //朋友圈
shareToTimeLine();
break;
case 2: //qq
shareToQQ();
break;
case 3: //qq空间
shareToQQZone();
break;
}
}
}).show();
}
private void shareToWX() {
showLoading();
DonwloadSaveImage.getImageList(urlList, new DonwloadSaveImage.OnImageFileListCallback() {
@Override
public void onimageFileList(ArrayList<File> imageFileList) {
hideLoading();
WxShareHelper.getInstnce().shareMultiImageToWX(mContext, imageFileList);
}
});
}
private void shareToTimeLine() {
showLoading();
DonwloadSaveImage.getImageList(urlList, new DonwloadSaveImage.OnImageFileListCallback() {
@Override
public void onimageFileList(ArrayList<File> imageFileList) {
hideLoading();
ShareHelper.getInstnce().shareMultiImageToWXTimeLine(mContext, imageFileList);
}
});
}
private void shareToQQ() {
}
private void shareToQQZone() {
}
}
DonwloadSaveImage:下载和保存图片
/**
* Cerated by xiaoyehai
* Create date : 2019/12/4 17:57
* description : 下载图片并且保存到本地
*/
public class DonwloadSaveImage {
//线程池
private static ExecutorService executor;
private static Handler mHandler;
private static String imageDirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "tjz";
static {
executor = Executors.newFixedThreadPool(5);
mHandler = new Handler();
}
public static void getImageList(List<String> urlList, OnImageFileListCallback callback) {
executor.execute(new Runnable() {
@Override
public void run() {
deleteFile();
ArrayList<File> localUrls = new ArrayList<>();
for (String url : urlList) {
localUrls.add(downloadImage(url));
}
mHandler.post(new Runnable() {
@Override
public void run() {
callback.onimageFileList(localUrls);
}
});
}
});
}
/* Glide.with(getActivity()) // could be an issue!
.load(shareimgUrl)
.asBitmap() //强制转换Bitmap
.into(new SimpleTarget() {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation super Bitmap> glideAnimation) {
// //这里我们拿到回掉回来的bitmap,可以加载到我们想使用到的地方
hideLoading();
ShareUtils.shareImage(mContext, resource, wxSceneSession);
}
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable);
hideLoading();
ToastUtil.showShortToast("加载图片失败");
}
});*/
/**
* 下载图片
*
* @param url
* @return
*/
private static File downloadImage(String url) {
File file = null;
try {
URL imageurl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) imageurl.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(is);
is.close();
file = saveBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
/**
* 保存图片到本地
*
* @param bitmap
* @return
*/
private static File saveBitmap(Bitmap bitmap) {
File appDir = new File(imageDirPath);
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = System.currentTimeMillis() + ".jpg";
File file = new File(appDir, fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
//通过io流的方式来压缩保存图片
bitmap.compress(Bitmap.CompressFormat.JPEG, 60, fos);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
return new File(imageDirPath, fileName);
}
private static void deleteFile() {
File dir = new File(imageDirPath);
if (dir.exists()) {
File[] files = dir.listFiles();
if (files != null) {
for (File file : files) {
file.delete();
}
}
}
}
public interface OnImageFileListCallback {
void onimageFileList(ArrayList<File> imageFileList);
}
}
注意问题:
实际分享的时候因为是调用系统本地的分享功能,所以分享的图片也就必须要存到本地,不然就会提示获取资源失败,只支持分享到朋友圈等等的问题。
因为考虑到如果存的图片太多就太占内存了,所以最多设置分享9张。
这个是直接调用微信的分享,所以调起分享的时候一定要判断手机里面是否已经安装了微信,如果没有安装还要掉微信分享就是直接崩溃掉。
android N系统以后分享的链接用file://…的时候会出现一个异常android.os.FileUriExposedException。网上虽然很多朋友都给出了用 v4包中的FileProvider来解决,但是不知道为什么,反正我的项目导入后就报错了,最后在网上找了另一个方法在项目的BaseApplication的onCreate中用VmPolicy的方法解决。
/解决android N(>=24)系统以上分享 路径为file://时的 android.os.FileUriExposedException异常
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
}