Android之微信接入分享,登录功能。
来源:互联网 发布:坐久了腰疼 知乎 编辑:程序博客网 时间:2024/05/28 20:20
最近在做一个APP项目,需要用到微信分享啊,登录这些。
微信支付的参考另外一篇:Android之微信支付功能
1 前期准备
1.1 下载签名生成工具和SDK包
去微信:https://open.weixin.qq.com/cgi-bin/readtemplate?t=resource/app_download_android_tmpl&lang=zh_CN下载签名生成工具 还有开发工具包(第一个),然后将签名生成工具安装到我们的机器上。微信的这个东西百度很难找,我把地址转为二维码,用手机扫描打开然后下载吧。
1.2获取应用签名
1.2.1 未签名应用
将我们的程序运行在手机上后,打开签名生成工具,输入我们应用的包名,这个可以在我们工程的Manifest.xml文件里看到,然后就可以得到签名。
优点:方便快捷,只需直接输入包名即可。
缺点:该签名只在当时的手机上有效,在其它手机上无效。
1.2.2 已签名应用
先对我们的程序进行打包和签名,我为了方便就在打包签名的时候给它起名为debug.keystore,密码为android,alias为androiddebugkey,这样的方便就在于能够直接在eclipse里通过Window——preferences——Android——bulid里的Custom debug keystore里去引用查看,点击apply。当然你也可以签名后,安装到手机上,同样的用微信签名生成工具查看签名,这里的签名是MD5签名,填写的时候不用添加冒号“:”。
优点:可以让该应用在任何手机上都可以调用微信的功能。
缺点:也不算什么缺点,就是要注意签名过程中的一些东西,这个请另行查找,步骤比较琐碎。
1.3 微信开放平台创建应用
获取到我们的签名后,就进入微信开放平台,先注册一个账号,然后就创建我们的应用:
1.填写基本信息:
2.填写平台信息:官网如果没有的话可以随便填,我填的是www.baidu.com~,应用签名就是我们刚才获取到的那一长串,应用包名也是之前填写的包名。
3.提交审核,静候佳音。
4.审核成功后,我们就会得到AppID和APPSecret:(注意此时你只能拥有微信分享的功能,关于微信登录的功能你需要去进行开发者认证,叫三百块,填写一些企业的相关内容这样)
2 开发工作:
2.1 导入jar包
解压我们下载好的开发工具包,将里面的libammsdk.jar拉到我们的libs文件夹里,然后右键工程——Build Path——Config Build Path——Libraries——ADD JARs,去我们工程的libs里选择libammsdk.jar,然后ok,apply就行了。
2.2 AndroidManifest里添加权限
<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"/>
2.3 注册应用到微信
2.4 微信分享
你可以弄个button之类的控件,为它设置点击事件,我这里只做文本信息的分享,其它的可以在微信开发文档上看,虽然有些难看。
case R.id.weChat_friends://构建文本信息的分享对象(其它的有WXVideoObject,WXImageObject等),内容为helloWXTextObject textObject = new WXTextObject(); textObject.text = "hello"; //将textObject分装到WXMediaMessage里 WXMediaMessage mediaMessage = new WXMediaMessage(); mediaMessage.mediaObject = textObject; mediaMessage.description = "hello"; //构建发送请求 SendMessageToWX.Req req = new SendMessageToWX.Req(); //设置发送场景为分享给微信好友 req.scene = SendMessageToWX.Req.WXSceneSession; //设置该事务为唯一事务(因为时间只有一个) req.transaction = String.valueOf(System.currentTimeMillis()); //将封装好的WXMediaMessage再封装给SendMessageToWX.Req req.message = mediaMessage; //通过IWXAPI发送请求 MyApplication.api.sendReq(req);这里面除了第一步的内容有不同,就是分享的是文本,图片,还是链接不同外,以下的步骤都差不多,那是一个微信给的流程。(MyApplication.api是我在自定义的Application里定义的:其实也就是public static IWXAPI api。)
2.5 微信登录
微信登录我觉得看文档是个很难看懂的东西......完全不知道从何入手,我百度了几天无果,通过google才算结果比较正确。
2.5.1 调用微信授权窗口
//微信登陆,跳转到WXEntryActivitycase R.id.cjd_UnsignActivity_iv_weChat:if(!MyApplication.api.isWXAppInstalled()){Toast.makeText(this, "请先安装微信", Toast.LENGTH_SHORT).show();}else {SendAuth.Req req = new SendAuth.Req(); req.scope = "snsapi_userinfo"; req.state = "Moke"; MyApplication.api.sendReq(req);}做到这一步的时候,你点击就可以唤起微信登录界面了,当然我们还没有做处理结果,所以你在登录界面那里点击授权,取消什么的,它会跳转到一个空白界面而已。如果没有唤起微信登录界面,你就要检查一下开放平台上的签名正不正确啊,包名有没有写错啊,一般就是错在这些地方。
2.5.2 微信请求处理
为了处理微信请求的结果,首先我们要新建一个包,名字为“包名.wxapi”,包名就是AndroidManifest里的packagename。这个必须要遵守,然后新建一个Activity为WXEntryActivity。这里就是用于唤醒的微信登录界面,以及处理请求的地方。<activity android:name="com.moke.wxapi.WXEntryActivity" android:exported="true" android:label="@string/app_name" ></activity>
@Overridepublic void onResp(BaseResp arg0) {switch (arg0.errCode ) {//同意授权case BaseResp.ErrCode.ERR_OK:SendAuth.Resp resp = (Resp) arg0;//获得codeString code = resp.code; }}
SendAuth.Resp resp = (Resp) arg0;
以下是我的完整的代码
package com.moke.wxapi;import java.net.URLEncoder;import org.json.JSONException;import org.json.JSONObject;import com.moke.activity.BaseActivity;import com.moke.activity.CJD_MemberCenterActivity;import com.moke.activity.CJD_UnSignActivity;import com.moke.common.PathCommonDefines;import java.net.URLEncoder;import java.util.Timer;import java.util.TimerTask;import org.json.JSONException;import org.json.JSONObject;import com.moke.common.PathCommonDefines;import com.moke.model.WeChatUser;import com.moke.until.HttpCallbackListener;import com.moke.until.HttpUtil;import com.moke.until.MyApplication;import com.tencent.mm.sdk.modelbase.BaseReq;import com.tencent.mm.sdk.modelbase.BaseResp;import com.tencent.mm.sdk.modelmsg.SendAuth;import com.tencent.mm.sdk.modelmsg.SendAuth.Resp;import com.tencent.mm.sdk.modelmsg.SendMessageToWX;import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;import com.tencent.mm.sdk.openapi.WXAPIFactory;import android.app.Activity;import android.content.Context;import android.content.SharedPreferences;import android.os.Bundle;import android.os.Handler;import android.preference.PreferenceManager;import android.util.Log;import android.widget.Toast;public class WXEntryActivity extends BaseActivity implements IWXAPIEventHandler {private MyApplication myApp;// 请求access_token地址格式,要替换里面的APPID,SECRET还有CODEpublic static String GetCodeRequest = "https://api.weixin.qq.com/sns/oauth2/access_token?"+ "appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";// 请求unionid地址格式,要替换里面的ACCESS_TOKEN和OPENIDpublic static String GetUnionIDRequest = "https://api.weixin.qq.com/sns/userinfo?"+ "access_token=ACCESS_TOKEN&openid=OPENID";private String newGetCodeRequest = "";private String newGetUnionIDRequest = "";private String mOpenId = "";private String mAccess_token = "";private SharedPreferences preferences;private SharedPreferences.Editor editor;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);myApp = (MyApplication) getApplication();<span style="color:#ff0000;">myApp.api.handleIntent(getIntent(), this);</span>preferences = PreferenceManager.getDefaultSharedPreferences(this);editor = preferences.edit();}/** * 回调微信发送的请求 */@Overridepublic void onReq(BaseReq arg0) {// TODO Auto-generated method stub}/** * 发送到微信请求的响应结果 * * (1)用户同意授权后得到微信返回的一个code,将code替换到请求地址GetCodeRequest里的CODE,同样替换APPID和SECRET * (2)将新地址newGetCodeRequest通过HttpClient去请求,解析返回的JSON数据 * (3)通过解析JSON得到里面的openid (用于获取用户个人信息)还有 access_token * (4)同样地,将openid和access_token替换到GetUnionIDRequest请求个人信息的地址里 * (5)将新地址newGetUnionIDRequest通过HttpClient去请求,解析返回的JSON数据 * (6)通过解析JSON得到该用户的个人信息,包括unionid */@Overridepublic void onResp(BaseResp arg0) {if (arg0.getType() == 2) {finish();}if (arg0.getType() == 1) {switch (arg0.errCode) {// 同意授权case BaseResp.ErrCode.ERR_OK:SendAuth.Resp respLogin = (Resp) arg0;// 获得codeString code = respLogin.code; // 把code,APPID,APPSECRET替换到要请求的地址里,成为新的请求地址newGetCodeRequest = getCodeRequest(code);// 请求新的地址,解析相关数据,包括openid,acces_token等HttpUtil.sendHttpRequest(newGetCodeRequest, new HttpCallbackListener() {@Overridepublic void onFinish(String response) {// Log.d("WXActivity", response);parseAccessTokenJSON(response);// 将解析得到的access_token和openid在请求unionid地址里替换newGetUnionIDRequest = getUnionID(mAccess_token, mOpenId);// 请求新的unionid地址,解析出返回的unionid等数据HttpUtil.sendHttpRequest(newGetUnionIDRequest, new HttpCallbackListener() {@Overridepublic void onFinish(String response) {parseUnionIdJson(response);}@Overridepublic void onError(Exception e) {}});}@Overridepublic void onError(Exception e) {// TODO Auto-generated method stub}});Timer timer = new Timer();TimerTask task = new TimerTask() {@Overridepublic void run() {// TODO Auto-generated method stubWXEntryActivity.this.finish();}};timer.schedule(task, 2000);break;// 拒绝授权case BaseResp.ErrCode.ERR_AUTH_DENIED:finish();break;// 取消操作case BaseResp.ErrCode.ERR_USER_CANCEL:finish();break;default:break;}}}/** * * 替换GetCodeRequest 将APP ID,APP SECRET,code替换到链接里 * * @param code * * 授权时,微信回调给的 * @return URL */public static String getCodeRequest(String code) {String result = null;GetCodeRequest = GetCodeRequest.replace("APPID", urlEnodeUTF8(PathCommonDefines.WECHAT_APP_ID));GetCodeRequest = GetCodeRequest.replace("SECRET", urlEnodeUTF8(PathCommonDefines.WECHAT_APP_SECRET));GetCodeRequest = GetCodeRequest.replace("CODE", urlEnodeUTF8(code));result = GetCodeRequest;return result;}/** * * 替换GetUnionID * * @param access_token * @param open_id * @return */public static String getUnionID(String access_token, String open_id) {String result = null;GetUnionIDRequest = GetUnionIDRequest.replace("ACCESS_TOKEN", urlEnodeUTF8(access_token));GetUnionIDRequest = GetUnionIDRequest.replace("OPENID", urlEnodeUTF8(open_id));result = GetUnionIDRequest;return result;}public static String urlEnodeUTF8(String code) {String result = code;try {result = URLEncoder.encode(code, "UTF-8");} catch (Exception e) {e.printStackTrace();}return result;}/** * * 解析access_token返回的JSON数据 * * @param response */private void parseAccessTokenJSON(String response) {// TODO Auto-generated method stubtry{JSONObject jsonObject = new JSONObject(response);mAccess_token = jsonObject.getString("access_token");String expiresIn = jsonObject.getString("expires_in");String refreshToken = jsonObject.getString("refresh_token");mOpenId = jsonObject.getString("openid");String scope = jsonObject.getString("scope");//将获取到的数据写进SharedPreferences里editor.putString("access_token",mAccess_token);editor.putString("expires_in",expiresIn);editor.putString("refresh_token",refreshToken);editor.putString("openid",mOpenId);editor.putString("scope", scope);editor.commit(); Log.d("WXActivity", "access_token is " + mAccess_token); Log.d("WXActivity", "expires_in is " + expiresIn); Log.d("WXActivity", "refresh_token is " + refreshToken); Log.d("WXActivity", "openid is " + mOpenId); Log.d("WXActivity", "scope is " + scope); } catch (JSONException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/** * * 解析unionid数据 * @param response */private void parseUnionIdJson(String response) {try {JSONObject jsonObject = new JSONObject(response);String openid = jsonObject.getString("openid");String nickname = jsonObject.getString("nickname");String sex = jsonObject.getString("sex");String province = jsonObject.getString("province");String city = jsonObject.getString("city");String country = jsonObject.getString("country");String headimgurl = jsonObject.getString("headimgurl");String unionid = jsonObject.getString("unionid");editor.putString("nickname", nickname);editor.putString("headimgurl", headimgurl);editor.putBoolean("haveSign", true);editor.putString("unionid", unionid);editor.commit();myApp.setWxName(nickname);Log.d("WXActivity ", " openid is " + openid);Log.d("WXActivity", "nickname is " + nickname);Log.d("WXActivity", "sex is " + sex);Log.d("WXActivity", "province is " + province);Log.d("WXActivity", "city is " + city);Log.d("WXActivity", "country is " + country);Log.d("WXActivity", "headimgurl is " + headimgurl);Log.d("WXActivity", "unionid is " + unionid);} catch (JSONException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
public class HttpUtil {public static void sendHttpRequest(final String address , final HttpCallbackListener listener) {new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubHttpURLConnection connection = null;try {URL url = new URL(address);connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");connection.setConnectTimeout(8000);connection.setReadTimeout(8000);connection.setDoInput(true);connection.setDoOutput(true);InputStream inputStream = connection.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));StringBuilder response = new StringBuilder();String line;while((line = reader.readLine())!=null){response.append(line);}if(listener != null){//回调onFinish()方法listener.onFinish(response.toString());}} catch(Exception e){if(listener != null){//回调onError()方法listener.onError(e);}}finally {if(connection != null){connection.disconnect();}}}}).start();}}
回调接口:
public interface HttpCallbackListener {/** * 服务器响应成功时调用,根据返回的内容在里面处理逻辑 * @param response */void onFinish(String response);/** * 网络操作出现错误的时候调用,在里面对异常情况进行处理 * @param e */void onError(Exception e);}
微信支付的参考另外一篇:Android之微信支付功能
- Android之微信接入分享,登录功能。
- Android微信SDK分享功能接入
- android接入原生微信登录功能
- Android微信SDK登录功能接入
- Android微信登录接入
- ShareSDK接入实现微信分享功能
- Unity开发之接入Sharesdk微信分享Android
- android-----------实现微信登录和分享功能。
- Android接入微信分享注意事项目
- cocos2dx3.15接入微信SDK实现登录和分享android studio2.3.3
- Android微信第三方登录接入
- Android 分享功能之 微信 图片分享
- cocos2d-x项目Android版和IOS版接入微信分享功能示例
- android 微信 以及QQ的SDK接入分享功能遇到的些问题小结
- android微信登录,分享
- AndroidStudio用微信官方方法接入微信分享功能
- React Native 接入微博、微信、QQ 登录功能
- android微信分享功能
- 在使用分组操作时的几个注意事项
- 复数和复函数
- JAVA中为什么要采用get,set方法的形式来对成员变量进行访问
- java程序执行时间计算
- 自定义视图
- Android之微信接入分享,登录功能。
- UML之交互图(顺序图和协作图)
- python+uiautomator测试环境搭建
- input和raw_input
- ca
- Java基础---类和对象
- 枚举
- 【Java爬虫】爬取南通大学教务系统成绩计算绩点
- linux 获取经过N层Nginx转发的访问来源真实IP