[转载]微享,微信分享实例-Android开发源码下载-eoe Android开发者社区_Android开发论坛 – Powered by Discuz!.
最近在搞微信分享,因此做了个小应用,坑爹的微信官方文档,真让人火大,这是后话了,先看我这个应用的效果图:



主要有三个功能,拍照立即分享、取本地照片分享、微信好友及好友圈,我一一讲解,先看项目结构图:

(一)拍照
//打开相机
private final int CAMERA_CODE = 1; // 这里的CAMERA_CODE 是自己任意定义的
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent,CAMERA_CODE);
//onActivityResult方法返回处理拍照照片
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) { // 此处的 RESULT_OK 是系统自定义得一个常量
Toast.makeText(WXEntryActivity.this, "操作取消", Toast.LENGTH_SHORT)
.show();
return;
}
switch (requestCode) {
case CAMERA_CODE:
if (data != null) {
// HTC
if (data.getData() != null) {
// 根据返回的URI获取对应的SQLite信息
Cursor cursor = getContentResolver().query(data.getData(),
null, null, null, null);
if (cursor.moveToFirst()) {
filePath = cursor.getString(cursor
.getColumnIndex("_data"));// 获取绝对路径
}
cursor.close();
} else {
// 三星 小米(小米手机不会自动存储DCIM
mBitmap = (Bitmap) (data.getExtras() == null ? null : data
.getExtras().get("data"));
}
// 直接强转报错 这个主要是为了去高宽比例
Bitmap bitmap = mBitmap == null ? null : (Bitmap) mBitmap;
if (bitmap == null) {
/**
* 该Bitmap是为了获取压缩后的文件比例 如果没有缩略图的比例
* 就获取真实文件的比例(真实图片比例会耗时很长,所以如果有缩略图最好)
*/
bitmap = BitmapFactory.decodeFile(filePath);
}
path = AppUtil.saveBitmap(bitmap);
shareImg.setImageBitmap(AppUtil.getLoacalBitmap(path)); // 设置Bitmap
isPicture = true;
}
break;
default:
break;
}
}
其中saveBitmap()方法:
/**
* 是否存在SDCard
*
*/
public static boolean hasSdCard() {
if (Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState())) {
return true;
}
return false;
}
/**
* 将Bitmap保存在本地
*
* @param mBitmap
* @return
*/
@SuppressLint("SimpleDateFormat")
public static String saveBitmap(Bitmap mBitmap) {
try {
String sdCardPath = "";
if (hasSdCard()) {
sdCardPath = Environment.getExternalStorageDirectory()
.getPath();
} else {
}
String filePath = sdCardPath + "/" + "MicroShare/";
Date date = new Date(System.currentTimeMillis());
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");// 时间格式-显示方式
String imgPath = filePath + sdf.format(date) + ".png";
File file = new File(filePath);
if (!file.exists()) {
file.mkdirs();
}
File imgFile = new File(imgPath);
if (!imgFile.exists()) {
imgFile.createNewFile();
}
FileOutputStream fOut = new FileOutputStream(imgFile);
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
if (fOut != null) {
fOut.close();
}
return imgPath;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
这样拍照的过程完了,分享等下再说。
(二)本地照片
// 使用intent调用系统提供的相册功能,使用startActivityForResult是为了获取用户选择的图片
private final int IMAGE_CODE = 0; // 这里的IMAGE_CODE是自己任意定义的
Intent getAlbum = new Intent( Intent.ACTION_GET_CONTENT); getAlbum.setType(IMAGE_TYPE); startActivityForResult(getAlbum,IMAGE_CODE);
//onActivityResult方法返回处理照片
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) { // 此处的 RESULT_OK 是系统自定义得一个常量
Toast.makeText(WXEntryActivity.this, "操作取消", Toast.LENGTH_SHORT)
.show();
return;
}
switch (requestCode) {
case IMAGE_CODE:
Bitmap bm = null;
// 外界的程序访问ContentProvider所提供数据 可以通过ContentResolver接口
ContentResolver resolver = getContentResolver();
try {
Uri originalUri = data.getData(); // 获得图片的uri
bm = MediaStore.Images.Media.getBitmap(resolver, originalUri); // 显得到bitmap图片
// 这里开始的第二部分,获取图片的路径:
String[] proj = { MediaStore.Images.Media.DATA };
// 好像是android多媒体数据库的封装接口,具体的看Android文档
Cursor cursor = managedQuery(originalUri, proj, null, null,
null);
// 按我个人理解 这个是获得用户选择的图片的索引值
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
// 将光标移至开头 ,这个很重要,不小心很容易引起越界
cursor.moveToFirst();
// 最后根据索引值获取图片路径
path = cursor.getString(column_index);
Bitmap bitmap = AppUtil.getLoacalBitmap(path); // 从本地取图片(在cdcard中获取)
shareImg.setImageBitmap(bitmap); // 设置Bitmap
isPicture = true;
} catch (IOException e) {
Toast.makeText(WXEntryActivity.this, e.toString(),
Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
提示:调用系统提供的相册功能时,请选择系统的相册功能进入,比如:

这里请选择系统的,如果你选择第三方进入它的的相册肯定是报错,关于这个错误我没有做处理。
(三)微信分享
这部分是重点也是难点,我慢慢讲解我两天做的微 信分享的心得,首先我给的项目源码你们肯定跑不起来,因为我的这项目已经微信审核通过了,审核的时候应用签名(打包时MD5值)和包名绑定了,因此运行源 码是不能调微信客户端的。附件里已经附带了我打包好了apk,大家可以跑这个看效果。

1、申请你的appid
请到 微信开发者应用登记页面 进行登记,登记并选择移动应用进行设置后,将该应用提交审核,只有审核通过的应用才能进行开发。

2、导jar包
在工程中新建一个libs目录,将开发工具包中libs目录下的libammsdk.jar复制到该目录中(如下图所示,建立了一个名为SDK_Sample 的工程,并把jar包复制到libs目录下)。

3、代码编写
(1)初始化、注册
// 通过WXAPIFactory工厂,获取IWXAPI的实例 api = WXAPIFactory.createWXAPI(this, APP_ID, false); // 将该app注册到微信 api.registerApp(APP_ID); api.handleIntent(getIntent(), this);//此行后面再说
(2)分享部分
此项目制涉及分享本地的图片,代码如下:
// 微信好友 case 0: weixinShare(true); break; // 微信朋友圈 case 1: weixinShare(false); break;
weixinShare方法:
private void weixinShare(boolean isFriend) {
File file = new File(path);
if (!file.exists()) {
String tip = WXEntryActivity.this
.getString(R.string.send_img_file_not_exist);
Toast.makeText(WXEntryActivity.this, tip + " path = " + path,
Toast.LENGTH_LONG).show();
return;
}
WXImageObject imgObj = new WXImageObject();
imgObj.setImagePath(path);
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = imgObj;
Bitmap bmp = BitmapFactory.decodeFile(path);
Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, THUMB_SIZE,
THUMB_SIZE, true);
bmp.recycle();
msg.thumbData = Util.bmpToByteArray(thumbBmp, true);
int imageSize = msg.thumbData.length / 1024;
if (imageSize > 32) {
Toast.makeText(WXEntryActivity.this, "您分享的图片过大", Toast.LENGTH_SHORT)
.show();
return;
}
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("img");
req.message = msg;
req.scene = isFriend ? SendMessageToWX.Req.WXSceneSession
: SendMessageToWX.Req.WXSceneTimeline;
api.sendReq(req);
finish();
}
注意点:如果分享的图片大于35k,微信客户端是没有响应的,因此做了判断,这是官方demo没有的,官方文档有讲解。
(3)接收微信的请求及返回值如果你的程序需要接收微信发送的请求,或者接收发送到微信请求的响应结果,需要下面3步操作:
a. 在你的包名相应目录下新建一个wxapi目录,并在该wxapi目录下新增一个WXEntryActivity类(注意点:必须是wxapi目录,WXEntryActivity类),该类继承自Activity并在manifest文件里面加上exported属性,设置为true,例如:

b. 实现IWXAPIEventHandler接口,微信发送的请求将回调到onReq方法,发送到微信请求的响应结果将回调到onResp方法
c. 在WXEntryActivity中将接收到的intent及实现了IWXAPIEventHandler接口的对象传递给IWXAPI接口的handleIntent方法,示例如下:
api.handleIntent(getIntent(), this);
当微信发送请求到你的应用,将通过IWXAPIEventHandler接口的onReq方法进行回调,类似的,应用请求微信的响应结果将通过onResp回调。
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
}
// 微信发送请求到第三方应用时,会回调到该方法
@Override
public void onReq(BaseReq req) {
}
// 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
@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_LONG).show();
}
(四)其他功能
(1)再按一次退出程序
private static Boolean isExit = false;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (isExit == false) {
isExit = true;
Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
isExit = false;
}
}, 2000);
} else {
finish();
System.exit(0);
}
}
return false;
}
(2)检测网络
public boolean checkNetworkInfo() {
ConnectivityManager conMan = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
// mobile 3G Data Network
State mobile = conMan.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
.getState();
// wifi
State wifi = conMan.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
.getState();
// 如果3G网络和wifi网络都未连接,且不是处于正在连接状态 则进入Network Setting界面 由用户配置网络连接
if (mobile == State.CONNECTED || mobile == State.CONNECTING)
return true;
if (wifi == State.CONNECTED || wifi == State.CONNECTING)
return true;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("网络不给力")
.setTitle("提示")
.setCancelable(false)
.setPositiveButton("配置", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// 进入无线网络配置界面
startActivity(new Intent(
Settings.ACTION_WIRELESS_SETTINGS));
WXEntryActivity.this.finish();
}
})
.setNegativeButton("退出", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
WXEntryActivity.this.finish();
}
});
builder.show();
return false;
}
Mikel