图文详解Android集成微信登录的步骤

互联网 17-3-15
这篇文章给大家图文详解Android集成微信登录的步骤,通过文章整理的内容,大家只需要几行代码就可以实现微信登录的功能了,刚兴趣的朋友们下面来一起看看吧。

一、首先在Application的onCreate中写:

// GeneralAppliction.java  public static IWXAPI sApi;  @Override  public void onCreate() {   super.onCreate();   sApi = WXEntryActivity.initWeiXin(this, AppConst.WEIXIN_APP_ID);  }

二、在需要登录的地方添加:

// MainActivity.java  WXEntryActivity.loginWeixin(MainActivity.this, GeneralAppliction.sApi);

三、下面对具体的集成步骤做详细的描述。

集成步骤:

1、在开放平台注册创建应用,申请登录权限

2、下载sdk,拷贝相关文件到项目工程目录

3、全局初始化微信组件

4、请求授权登录,获取code

5、通过code获取授权口令access_token

6、在第5步判断access_token是否存在和过期

7、如果access_token过期无效,就用refresh_token来刷新

8、使用access_token获取用户信息

1. 在开放平台注册创建应用,申请登录权限

这一步其实不用怎么讲,无法就是在微信开放平台上注册一个账号,然后创建移动应用。

需要注意的是:应用签名的部分

此处应用签名我使用的是线上的key的md5,关于这个需要注意的问题可以看:Android的签名总结

下载后把libammsdk.jar文件拷贝到AS工程的libs目录,并把示例Demo里源文件目录下的wxapi目录整个拷贝到,工程目录的src下的根包下:

如果wxapi这个文件夹放的位置不对,讲无法登录,微信sdk无法找到登录的Activity授权功能。然后在Manifest.xml里面加入:

<activity    android:name=".wxapi.WXEntryActivity"    android:theme="@android:style/Theme.Translucent.NoTitleBar"   android:configChanges="keyboardHidden|orientation|screenSize"   android:exported="true"   android:screenOrientation="portrait" />

3. 全局初始化微信组件

全局初始化微信组件,当然是Application的onCreate里(当然Activity的onCreate也是可以的,为了全局使用微信api对象方便操作):

@Override  public void onCreate() {    super.onCreate();   // 初始化微信组件   initWeiXin();  }    public static IWXAPI sApi;  private void initWeiXin() {   sApi = WXEntryActivity.initWeiXin(this, AppConst.WEIXIN_APP_ID);  }

4. 请求授权登录,获取code

为了同一业务的单一原则我把微信相关的都统一封装到了wxapi包下和WXEntryActivity中:

// 实现IWXAPIEventHandler 接口,以便于微信事件处理的回调  public class WXEntryActivity extends Activity implements IWXAPIEventHandler {     private static final String WEIXIN_ACCESS_TOKEN_KEY = "wx_access_token_key";   private static final String WEIXIN_OPENID_KEY = "wx_openid_key";   private static final String WEIXIN_REFRESH_TOKEN_KEY = "wx_refresh_token_key";     private Gson mGson;   @Override   public void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   // 微信事件回调接口注册   GeneralAppliction.sApi.handleIntent(getIntent(), this);   mGson = new Gson();   }     /**   * 微信组件注册初始化   * @param context 上下文   * @param weixin_app_id appid   * @return 微信组件api对象   *   /   public static IWXAPI initWeiXin(Context context, @NonNull String weixin_app_id) {   if (TextUtils.isEmpty(weixin_app_id)) {   Toast.makeText(context.getApplicationContext(), "app_id 不能为空", Toast.LENGTH_SHORT).show();   }   IWXAPI api = WXAPIFactory.createWXAPI(context, weixin_app_id, true);   api.registerApp(weixin_app_id);   return api;   }     /**    * 登录微信    *    * @param api 微信服务api    */   public static void loginWeixin(Context context, IWXAPI api) {   // 判断是否安装了微信客户端    if (!api.isWXAppInstalled()) {    Toast.makeText(context.getApplicationContext(), "您还未安装微信客户端!", Toast.LENGTH_SHORT).show();    return;    }   // 发送授权登录信息,来获取code   SendAuth.Req req = new SendAuth.Req();    // 应用的作用域,获取个人信息   req.scope = "snsapi_userinfo";    /**    * 用于保持请求和回调的状态,授权请求后原样带回给第三方   * 为了防止csrf攻击(跨站请求伪造攻击),后期改为随机数加session来校验    */    req.state = "app_wechat";   api.sendReq(req);   }     // 微信发送请求到第三方应用时,会回调到该方法   @Override   public void onReq(BaseReq req) {    switch (req.getType()) {    case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX:    break;    case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX:   break;    default:    break;    }   }   // 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法   @Override   public void onResp(BaseResp resp) {   switch (resp.errCode) {    // 发送成功    case BaseResp.ErrCode.ERR_OK:   // 获取code   String code = ((SendAuth.Resp) resp).code;   // 通过code获取授权口令access_token   getAccessToken(code);   break;   }   }  }

第三方通过code进行获取access_token的时候需要用到,code的超时时间为10分钟,一个code只能成功换取一次access_token即失效。code的临时性和一次保障了微信授权登录的安全性。第三方可通过使用https和state参数,进一步加强自身授权登录的安全性。

这样客户端使用的地方只要:

WXEntryActivity.loginWeixin(MainActivity.this, GeneralAppliction.sApi);

5. 通过code获取授权口令access_token

我们在onResp的回调方法中获取了code,然后通过code获取授权口令access_token:

/**   * 获取授权口令   */  private void getAccessToken(String code) {    String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +   "appid=" + AppConst.WEIXIN_APP_ID +   "&secret=" + AppConst.WEIXIN_APP_SECRET +   "&code=" + code +   "&grant_type=authorization_code";    // 网络请求获取access_token    httpRequest(url, new ApiCallback<String>() {    @Override    public void onSuccess(String response) {    Logger.e(response);    // 判断是否获取成功,成功则去获取用户信息,否则提示失败    processGetAccessTokenResult(response);    }    @Override    public void onError(int errorCode, final String errorMsg) {   Logger.e(errorMsg);    showMessage("错误信息: " + errorMsg);    }    @Override    public void onFailure(IOException e) {   Logger.e(e.getMessage());    showMessage("登录失败");    }    });  }    /**   * 处理获取的授权信息结果   * @param response 授权信息结果   */  private void processGetAccessTokenResult(String response) {    // 验证获取授权口令返回的信息是否成功   if (validateSuccess(response)) {   // 使用Gson解析返回的授权口令信息    WXAccessTokenInfo tokenInfo = mGson.fromJson(response, WXAccessTokenInfo.class);   Logger.e(tokenInfo.toString());   // 保存信息到手机本地   saveAccessInfotoLocation(tokenInfo);   // 获取用户信息    getUserInfo(tokenInfo.getAccess_token(), tokenInfo.getOpenid());    } else {   // 授权口令获取失败,解析返回错误信息    WXErrorInfo wxErrorInfo = mGson.fromJson(response, WXErrorInfo.class);    Logger.e(wxErrorInfo.toString());    // 提示错误信息   showMessage("错误信息: " + wxErrorInfo.getErrmsg());    }  }    /**   * 验证是否成功   *   * @param response 返回消息   * @return 是否成功   */  private boolean validateSuccess(String response) {    String errFlag = "errmsg";    return (errFlag.contains(response) && !"ok".equals(response))    || (!"errcode".contains(response) && !errFlag.contains(response));  }

6. 在第5步判断access_token是否存在和过期

在回调的onResp方法中获取code后,处理access_token是否登录过或者过期的问题:

// 从手机本地获取存储的授权口令信息,判断是否存在access_token,不存在请求获取,存在就判断是否过期  String accessToken = (String) ShareUtils.getValue(this, WEIXIN_ACCESS_TOKEN_KEY, "none");  String openid = (String) ShareUtils.getValue(this, WEIXIN_OPENID_KEY, "");  if (!"none".equals(accessToken)) {   // 有access_token,判断是否过期有效   isExpireAccessToken(accessToken, openid);  } else {   // 没有access_token   getAccessToken(code);  }

判断授权口令是否有效:

/**   * 判断accesstoken是过期   * @param accessToken token   * @param openid 授权用户唯一标识   */  private void isExpireAccessToken(final String accessToken, final String openid) {   String url = "https://api.weixin.qq.com/sns/auth?" +    "access_token=" + accessToken +    "&openid=" + openid;   httpRequest(url, new ApiCallback<String>() {   @Override   public void onSuccess(String response) {   Logger.e(response);   if (validateSuccess(response)) {   // accessToken没有过期,获取用户信息   getUserInfo(accessToken, openid);   } else {   // 过期了,使用refresh_token来刷新accesstoken   refreshAccessToken();   }   }   @Override   public void onError(int errorCode, final String errorMsg) {   Logger.e(errorMsg);   showMessage("错误信息: " + errorMsg);   }   @Override   public void onFailure(IOException e) {   Logger.e(e.getMessage());   showMessage("登录失败");   }   });  }

7. 如果access_token过期无效,就用refresh_token来刷新

/**   * 刷新获取新的access_token   *  /  private void refreshAccessToken() {   // 从本地获取以存储的refresh_token   final String refreshToken = (String) ShareUtils.getValue(this, WEIXIN_REFRESH_TOKEN_KEY, "");   if (TextUtils.isEmpty(refreshToken)) {   return;   }   // 拼装刷新access_token的url请求地址   String url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?" +   "appid=" + AppConst.WEIXIN_APP_ID +   "&grant_type=refresh_token" +   "&refresh_token=" + refreshToken;   // 请求执行   httpRequest(url, new ApiCallback<String>() {   @Override   public void onSuccess(String response) {   Logger.e("refreshAccessToken: " + response);   // 判断是否获取成功,成功则去获取用户信息,否则提示失败   processGetAccessTokenResult(response);   }   @Override   public void onError(int errorCode, final String errorMsg) {   Logger.e(errorMsg);   showMessage("错误信息: " + errorMsg);   // 重新请求授权   loginWeixin(WXEntryActivity.this.getApplicationContext(), GeneralAppliction.sApi);   }   @Override   public void onFailure(IOException e) {   Logger.e(e.getMessage());   showMessage("登录失败");   // 重新请求授权   loginWeixin(WXEntryActivity.this.getApplicationContext(), GeneralAppliction.sApi);   }   });  }

8. 使用access_token获取用户信息

/**   * 获取用户信息   *  /  private void getUserInfo(String access_token, String openid) {   String url = "https://api.weixin.qq.com/sns/userinfo?" +   "access_token=" + access_token +   "&openid=" + openid;   httpRequest(url, new ApiCallback<String>() {   @Override   public void onSuccess(String response) {   // 解析获取的用户信息   WXUserInfo userInfo = mGson.fromJson(response, WXUserInfo.class);   Logger.e("用户信息获取结果:" + userInfo.toString()); }   @Override   public void onError(int errorCode, String errorMsg) {   showMessage("错误信息: " + errorMsg);   }   @Override   public void onFailure(IOException e) {   showMessage("获取用户信息失败");   }   });  }
private OkHttpClient mHttpClient = new OkHttpClient.Builder().build();  private Handler mCallbackHandler = new Handler(Looper.getMainLooper());  /**   * 通过Okhttp与微信通信   * * @param url 请求地址   * @throws Exception   */  public void httpRequest(String url, final ApiCallback<String> callback) {   Logger.e("url: %s", url);   final Request request = new Request.Builder()   .url(url)   .get()   .build();   mHttpClient.newCall(request).enqueue(new Callback() {   @Override   public void onFailure(Call call, final IOException e) {   if (callback != null) {   mCallbackHandler.post(new Runnable() {    @Override    public void run() {    // 请求失败,主线程回调    callback.onFailure(e);    }   });   }   }   @Override   public void onResponse(Call call, final Response response) throws IOException {   if (callback != null) {   if (!response.isSuccessful()) {    mCallbackHandler.post(new Runnable() {    @Override    public void run() {    // 请求出错,主线程回调    callback.onError(response.code(), response.message());    }    });   } else {    mCallbackHandler.post(new Runnable() {    @Override    public void run() {    try {    // 请求成功,主线程返回请求结果    callback.onSuccess(response.body().string());    } catch (final IOException e) {    // 异常出错,主线程回调    mCallbackHandler.post(new Runnable() {     @Override     public void run() {     callback.onFailure(e);     }    });    }    }    });   }   }   }   });  }    // Api通信回调接口  public interface ApiCallback<T> {   /**   * 请求成功   *   * @param response 返回结果   */   void onSuccess(T response);   /**   * 请求出错   *   * @param errorCode 错误码   * @param errorMsg 错误信息   */   void onError(int errorCode, String errorMsg);   /**   * 请求失败   */   void onFailure(IOException e);  }

总结

集成的详细描述就这样,至于获取的用户信息,小伙伴们应该知道后续自己业务的需求,该怎么处理了。以上就是本文的全部内容了,希望能对大家的学习或者工作带来一定的帮助,如果有疑问大家可以留言交流。

以上就是图文详解Android集成微信登录的步骤的详细内容,更多内容请关注技术你好其它相关文章!

来源链接:
免责声明:
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
上一篇:php获取远程图片并下载保存到本地的方法分析 下一篇:图文详解Android开发微信授权登录与微信分享解析

相关资讯