Android——微信登录、分享
写在前面的话
应用要接入微信登录,分享,需要在微信的开发者平台上进行提交应用,并且审核通过,应用已经获取到appId。
相关jar包下载地址:http://download.csdn.net/detail/sapce_fish/9571142
也可到官网下载:https://open.weixin.qq.com
将 libammsdk.jar 引进自己的项目中
第一步:在Manifest中进行如下配置:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <activity android:name=".wxapi.WXEntryActivity" android:configChanges="orientation|keyboardHidden" android:exported="true" android:launchMode="singleTop" android:screenOrientation="portrait" android:theme="@android:style/Theme.Translucent.NoTitleBar"> <intent-filter> <action android:name="android.intent.action.VIEW">action> <category android:name="android.intent.category.LAUNCHER" /> intent-filter> activity>
第二步:写微信回调,这个需要特别注意,因为微信对这个回调类有特殊的要求
注意点:
1.位置:回调Activity的位置在包名的wxapi下。例如:包名为aaa.bbb.ccc 那么回调Activity的位置则应在aaa.bbb.ccc.wxapi下
2.Activity名:回调Activity名字必须为WXEntryActivity。此Activity继承自Activity,这也跟上面在Manifest文件中配置的那个Activity对应上了。
3.Activity实现IWXAPIEventHandler接口。
微信回调Activity(这个回调Activity比较容易写错,我就全部贴出来,如有需要可以参考)
public class WXEntryActivity extends Activity implements IWXAPIEventHandler{ private IWXAPI api; /** 标记是否有code,默认为有,当调用登录微信授权方法后此值会被设置成false*/ public static boolean mHaveCode = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); api = WXAPIFactory.createWXAPI(this, AppConstants.APP_ID_WX, false); api.handleIntent(getIntent(), this); } /** * 微信发送的请求将回调到onReq方法 */ @Override public void onReq(BaseReq req) { Log.d("space", req.toString()); finish(); } /** * 发送到微信请求的响应结果将回调到onResp方法 */ @Override public void onResp(BaseResp resp) { Log.i("space",resp.toString()); String result = ""; if (resp != null && !mHaveCode && ((SendAuth.Resp) resp).code != null) {// mResp = resp; mHaveCode = true; //设置好微信code getWXCode(resp); } Log.i("space", "WXEntryActivity resp.errCode="+resp.errCode); switch(resp.errCode) { case BaseResp.ErrCode.ERR_OK: result ="成功"; JsCallbackExecutor.onSocialWXOptionResult(resp.errCode, "code is weixin sdk back ,ref status" + result); finish(); break; case BaseResp.ErrCode.ERR_USER_CANCEL: result = "取消"; JsCallbackExecutor.onSocialWXOptionResult(resp.errCode, "code is weixin sdk back ,ref status" + result); Log.i("space", result); finish(); break; case BaseResp.ErrCode.ERR_AUTH_DENIED: result = "被拒绝"; JsCallbackExecutor.onSocialWXOptionResult(resp.errCode, "code is weixin sdk back ,ref status" + result); Log.i("space", result); finish(); break; default: result = "返回"; JsCallbackExecutor.onSocialWXOptionResult(resp.errCode, "code is weixin sdk back ,ref status" + result); Log.i("space", result); finish(); break; } } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); api.handleIntent(intent, this); finish(); } /** * 根据resp获取微信code * @param resp */ private void getWXCode(BaseResp resp){ if (resp != null && resp.getType() == ConstantsAPI.COMMAND_SENDAUTH) { // code返回 JsCallbackExecutor.onSocialWXLoginResult(CallbackCode.SUCCESS, ((SendAuth.Resp) resp).code); }else{ JsCallbackExecutor.onSocialWXLoginResult(CallbackCode.GET_WX_CODE_FAIL, "get wx code fail"); } }}
第三步:微信登录,拉出授权请求授权,获取微信access_token和openid,刷新access_token
微信登录,拉出授权请求授权
/** * 微信登录,拉出授权请求授权 */ @JavascriptInterface public void wxLogin(){ Log.i("space",">>>>>>>>>>wxLogin()"); //初始化微信相关 mWXapi = WXAPIFactory.createWXAPI(mActivity, AppConstants.APP_ID_WX, true); if(!mWXapi.isWXAppInstalled()) { JsCallbackExecutor.onSocialWXLoginResult(CallbackCode.NO_INSTALL_WX, "weixin no install"); Log.i("space","weixin no install"); return ; } WXEntryActivity.mHaveCode = false; mWXapi.registerApp(AppConstants.APP_ID_WX); SendAuth.Req req = new SendAuth.Req(); req.scope = "snsapi_userinfo"; req.state = "wechat_sdk_demo"; mWXapi.sendReq(req); }
获取微信access_token和openid
/** * 获取微信access_token和openid */ @JavascriptInterface public void getWXAccessTokenOpenId(final String code){ new Thread(new Runnable() { @Override public void run() { try { HttpClient get_access_token_httpClient = new DefaultHttpClient(); HttpPost postMethod = new HttpPost(getRequestAccessTokenUrl(code)); HttpResponse response = get_access_token_httpClient.execute(postMethod); // 执行POST方法 if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { InputStream is = response.getEntity().getContent(); BufferedReader br = new BufferedReader( new InputStreamReader(is)); String str = ""; StringBuffer sb = new StringBuffer(); while ((str = br.readLine()) != null) { sb.append(str); } is.close(); String josn = sb.toString(); //将获取到的json串传给epg,如果获取到的结果中没有openId或者access_token //epg应该用refresh_token进行刷新授权时间,如果也过期则应该重新拉出授权 JsCallbackExecutor.onSocialWXGetTokenOpenIdResult(CallbackCode.SUCCESS, josn); } else { JsCallbackExecutor.onSocialWXGetTokenOpenIdResult(CallbackCode.GET_WX_ACCESS_TOKEN_FAIL, "get access token fail"); } } catch (Exception e) { e.printStackTrace(); JsCallbackExecutor.onSocialWXGetTokenOpenIdResult(CallbackCode.GET_WX_ACCESS_TOKEN_FAIL, "get access token fail"); } } }).start(); }
刷新access_token
/** * 刷新access_token * @param appId * @param refresh_token * @return */ @JavascriptInterface public void refreshAccessToken(final String appId, final String refresh_token){ new Thread(new Runnable() { @Override public void run() { try { HttpClient get_access_token_httpClient = new DefaultHttpClient(); HttpPost postMethod = new HttpPost(getRefreshAccessTokenUrl(appId, refresh_token)); HttpResponse response = get_access_token_httpClient.execute(postMethod); // 执行POST方法 if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { InputStream is = response.getEntity().getContent(); BufferedReader br = new BufferedReader( new InputStreamReader(is)); String str = ""; StringBuffer sb = new StringBuffer(); while ((str = br.readLine()) != null) { sb.append(str); } is.close(); String josn = sb.toString(); //将获取到的json串传给epg,如果获取到的结果中没有openId或者access_token //epg应该用refresh_token进行刷新授权时间,如果也过期则应该重新拉出授权 JsCallbackExecutor.onSocialWXRefreshTokenResult(CallbackCode.SUCCESS, josn); } else { JsCallbackExecutor.onSocialWXRefreshTokenResult(CallbackCode.REFRESH_WX_ACESS_TOKEN_FAIL, "refresh access token fail"); } } catch (Exception e) { e.printStackTrace(); JsCallbackExecutor.onSocialWXRefreshTokenResult(CallbackCode.REFRESH_WX_ACESS_TOKEN_FAIL, "refresh access token fail"); } } }).start(); }
第四步:微信分享、获取用户信息
分享文字到微信好友会话或者朋友圈
/** * 分享文字到微信好友会话或者朋友圈 * @param msgText 需分享的消息内容 * @param sceneType 0 分享到朋友圈 ,1 分享到好友会话 */ @JavascriptInterface public void shareMessageToWX(String msgText,int sceneType ){ if(TextUtils.isEmpty(msgText) ||(sceneType != 0 && sceneType != 1)){ JsCallbackExecutor.onSocialWXUserInfoResult(CallbackCode.PARAMS_ERROR, "msgText or sceneType error"); return; } // 初始化一个WXTextObject对象 WXTextObject textObj = new WXTextObject(); textObj.text = msgText; // 用WXTextObject对象初始化一个WXMediaMessage对象 WXMediaMessage msg = new WXMediaMessage(); msg.mediaObject = textObj; // 发送文本类型的消息时,title字段不起作用 // msg.title = "Will be ignored"; msg.description = msgText; // 构造一个Req SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("text"); // transaction字段用于唯一标识一个请求 req.message = msg; //分享到好友会话或者朋友圈 req.scene = sceneType==0 ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession; // 调用api接口发送数据到微信 mWXapi.sendReq(req); }
分享图片到微信好友会话或者朋友圈
/** * 分享图片到微信好友会话或者朋友圈 * @param bmp 需分享的图片 * @param dstWidth 生成图片的宽 * @param dstHeight 生成图片的高 * @param sceneType 0 分享到朋友圈 ,1 分享到好友会话 */ @JavascriptInterface public void shareImageToWX(Bitmap bmp,int dstWidth, int dstHeight,int sceneType){ if(bmp == null || dstWidth==0 || dstHeight ==0 ||(sceneType != 0 && sceneType != 1)){ JsCallbackExecutor.onSocialWXUserInfoResult(CallbackCode.PARAMS_ERROR, "params error"); return; } //初始化WXImageObject和WXMediaMessage对象 WXImageObject imgObj = new WXImageObject(bmp); WXMediaMessage msg = new WXMediaMessage(); msg.mediaObject = imgObj; //设置缩略图 Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, dstWidth, dstHeight, true); bmp.recycle(); msg.thumbData = bmpToByteArray(thumbBmp, true); // 设置缩略图 // 构造一个Req SendMessageToWX.Req req = new SendMessageToWX.Req(); // transaction字段用于唯一标识一个请求 req.transaction = buildTransaction("img"); req.message = msg; //分享到好友会话或者朋友圈 req.scene = sceneType ==0 ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession; mWXapi.sendReq(req); }
分享音乐到微信好友会话或者朋友圈
/** * 分享音乐到微信好友会话或者朋友圈 * @param musicUrl 音乐url * @param musicTitle 音乐标题 * @param musicDesc 音乐描述 * @param bitmap 音乐图片 * @param sceneType 0 分享到朋友圈 ,1 分享到好友会话 */ @JavascriptInterface public void shareMusicToWX(String musicUrl,String musicTitle,String musicDesc,Bitmap bitmap ,int sceneType){ if((sceneType != 0 && sceneType != 1)){ JsCallbackExecutor.onSocialWXUserInfoResult(CallbackCode.PARAMS_ERROR, "params error"); return; } //初始化WXMusicObject对象 WXMusicObject music = new WXMusicObject(); music.musicUrl=musicUrl; //用一个WXMusicObject初始化一个WXMediaMessage对象,填写标题、描述 WXMediaMessage msg = new WXMediaMessage(); msg.mediaObject = music; //音乐标题 msg.title = musicTitle; //音乐描述 msg.description = musicDesc; //音乐缩略图 msg.thumbData = bmpToByteArray(bitmap, true); //构造一个req SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("music"); req.message = msg; req.scene = sceneType ==0 ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession; mWXapi.sendReq(req); }
分享视频到微信好友会话或者朋友圈
/** * 分享视频到微信好友会话或者朋友圈 * @param videoUrl 视频地址 * @param videoTitle 视频标题 * @param videoDesc 视频描述 * @param videoBitmap 视频图片 * @param sceneType 0 分享到朋友圈 ,1 分享到好友会话 */ @JavascriptInterface public void shareVideoToWX(String videoUrl,String videoTitle,String videoDesc,Bitmap videoBitmap,int sceneType){ if((sceneType != 0 && sceneType != 1)){ JsCallbackExecutor.onSocialWXUserInfoResult(CallbackCode.PARAMS_ERROR, "params error"); return; } WXVideoObject video = new WXVideoObject(); video.videoUrl = videoUrl; WXMediaMessage msg = new WXMediaMessage(video); msg.title = videoTitle; msg.description = videoDesc; msg.thumbData = bmpToByteArray(videoBitmap, true); SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("video"); req.message = msg; req.scene = sceneType ==0 ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession; mWXapi.sendReq(req); }
分享网页到微信好友会话或者朋友圈
/** * 分享网页到微信好友会话或者朋友圈 * @param webPagUrl 网页地址 * @param title 标题 * @param desc 描述 * @param bitmap 图片 * @param sceneType 0 分享到朋友圈 ,1 分享到好友会话 */ @JavascriptInterface public void shareWebPagToWX(String webPagUrl,String title,String desc,Bitmap bitmap, int sceneType){ if((sceneType != 0 && sceneType != 1)){ JsCallbackExecutor.onSocialWXUserInfoResult(CallbackCode.PARAMS_ERROR, "params error"); return; } WXWebpageObject webpage = new WXWebpageObject(); webpage.webpageUrl = webPagUrl; WXMediaMessage msg = new WXMediaMessage(webpage); msg.title = title; msg.description = desc; msg.thumbData = bmpToByteArray(bitmap, true); SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("webpage"); req.message = msg; req.scene = sceneType ==0 ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession; mWXapi.sendReq(req); }
获取微信用户信息
/** * 获取微信用户信息 */ @JavascriptInterface public void getWXUserInfo(String accessToken,String openId){ HttpClient get_user_info_httpClient = new DefaultHttpClient(); try { HttpGet getMethod = new HttpGet(getRequestUserInfoUrl(accessToken,openId)); HttpResponse response = get_user_info_httpClient.execute(getMethod); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { InputStream is = response.getEntity().getContent(); BufferedReader br = new BufferedReader( new InputStreamReader(is)); String str = ""; StringBuffer sb = new StringBuffer(); while ((str = br.readLine()) != null) { sb.append(str); } is.close(); JsCallbackExecutor.onSocialWXUserInfoResult(CallbackCode.SUCCESS, sb.toString()); } else { JsCallbackExecutor.onSocialWXUserInfoResult(CallbackCode.GET_USER_INFO_FAIL, "get user info fail"); } }catch (Exception e) { e.printStackTrace(); JsCallbackExecutor.onSocialWXUserInfoResult(CallbackCode.GET_USER_INFO_FAIL, "get user info fail"); } }
app在微信中的相关常量值
/** 微信中获取code后,请求以下链接获取access_token */ public static String GET_ACCESS_TOKEN_URL_WX = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code"; /** 微信中access_token过期后,请求以下链接刷新access_token */ public static String REFRESH_ACCESS_TOKEN_URL_WX = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN_VALUE"; /** 微信中获取用户个人信息的url */ public static String GET_USER_INFO_URL_WX="https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
获取access_token的URL(微信)
/** * 获取access_token的URL(微信) * @param code 授权时,微信回调给的 * @return URL */ @JavascriptInterface private String getRequestAccessTokenUrl(String code) { String tempTokenUrl = null; try { tempTokenUrl = AppConstants.GET_ACCESS_TOKEN_URL_WX; tempTokenUrl = tempTokenUrl.replace("APPID", URLEncoder.encode(AppConstants.APP_ID_WX, "UTF-8")); tempTokenUrl = tempTokenUrl.replace("SECRET", URLEncoder.encode(AppConstants.APP_SECRET_WX, "UTF-8")); tempTokenUrl = tempTokenUrl.replace("CODE", URLEncoder.encode(code, "UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return tempTokenUrl; }
刷新access_token的URL(微信)
/** * 刷新access_token的URL(微信) * @param appId 应用唯一标识 * @param refresh_token 获取access_token获取的refresh_token * @return URL */ private String getRefreshAccessTokenUrl(String appId, String refresh_token) { String tempRefreshTokenUrl = null; try { tempRefreshTokenUrl = AppConstants.REFRESH_ACCESS_TOKEN_URL_WX; tempRefreshTokenUrl = tempRefreshTokenUrl.replace("APPID", URLEncoder.encode(appId, "UTF-8")); tempRefreshTokenUrl = tempRefreshTokenUrl.replace("REFRESH_TOKEN_VALUE", URLEncoder.encode(refresh_token, "UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return tempRefreshTokenUrl; }
获取用户个人信息的URL(微信)
/** * 获取用户个人信息的URL(微信) * @param access_token 获取access_token时给的 * @param openid 获取access_token时给的 * @return URL */ private static String getRequestUserInfoUrl(String access_token, String openid){ String tempUserInfoUrl = null; try { tempUserInfoUrl = AppConstants.GET_USER_INFO_URL_WX; tempUserInfoUrl = tempUserInfoUrl.replace("ACCESS_TOKEN", URLEncoder.encode(access_token, "UTF-8")); tempUserInfoUrl = tempUserInfoUrl.replace("OPENID", URLEncoder.encode(openid, "UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return tempUserInfoUrl; }
其他
/** * 微信分享构建唯一请求标识type * @param type type * @return */ private String buildTransaction(final String type) { return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis(); } /** * 微信分享时将bitmap转arr * @param bmp * @param needRecycle * @return */ private static 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; }
写在最后
请注意应用的签名是否与微信开放平台中配置的是否一致查看签名的方法如果不一致的话是拉不起微信授权的。
我这个是基于混合开发的,所以回调部分大家可以忽略,其他方法是通用的。
另外如果有不明白的地方可以留言。有写错或者不好的地方欢迎指正
ps:查看签名的方法:http://blog.csdn.net/sapce_fish/article/details/51636578
更多相关文章
- Android之Action_SEND小例子
- SDK-IOS 关于SDK接入 MAC平台笔记
- fir.im Weekly - 如何在 iOS 上构建 TensorFlow 应用
- Flutter 新闻客户端 - 09 详情页展示、分享、远程真机调试
- 为Android应用程序添加社会化分享功能
- geekband android #5 第十周分享
- [置顶] Android源码分享
- 上官网学android之九(Building Apps with Content Sharing)
- Android开发之自定义Notification(源代码分享)