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的签名总结

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

开发工具包(SDK)的下载:可以使用微信分享、登录、收藏、支付等功能需要的库以及文件

示例Demo

下载后把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是啥玩意:

第三方通过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);
}

总结

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

(0)

相关推荐

  • 微信第三方登录Android实现代码

    记录一下微信第三方实现登录的方法.还是比较简单. 一.必要的准备工作 1.首先需要注册并被审核通过的微信开放平台帐号,然后创建一个移动应用,也需要被审核: 2.然后到资源中心下载开发微信所需的工具: 下载的网址:点击打开链接,有一个是SDK,一个是签名生成工具还有一个范例代码. 3.将SDK文件夹lib下的jar文件libammsdk.jar导入到项目工程中: 4.你的测试手机需要装好微信客户端: 5.在项目的AndroidManifest.xml文件中添加如下的权限: <uses-permis

  • Android 实现微信登录详解

    前言 分享到微信朋友圈的功能早已经有了,但微信登录推出并不久,文档写的也并不是很清楚,这里记录分享一下.  正文 一.准备 注册.认证步骤自己来.微信开放平台:https://open.weixin.qq.com 二. 代码 2.1 唤起微信登录 参考官网文档:资源中心/移动应用开放/接入指南/Android接入指南 private IWXAPI mWeixinAPI; private void loginWithWeixin() { if (mWeixinAPI == null) { mWei

  • Android实现使用微信登录第三方APP的方法

    本文实例讲述了Android实现使用微信登录第三方APP的方法.分享给大家供大家参考,具体如下: 使用微信登录APP,免去注册过程,现在已经有很多的类似应用了.集成该功能过程不复杂,但还是有一些地方需要注意的. 开始之前,需要做下面的准备工作. 1.到微信开放平台注册你的APP,并申请开通微信登录的权限.参考这里: https://open.weixin.qq.com// 2.下载Android SDK和签名查看工具,请参考: https://open.weixin.qq.com/cgi-bin

  • android实现微信联合登录开发示例

    随着现在社交app的越来越普及,微信,QQ,微博几乎成了我们每个人的手机必备,而且第三方应用也越来越多,不是每个用户都想为你的应用注册一个独立帐号的,所以联合登录也就显得尤为重要,成了我们不得不掌握的开发要点,但你要用微信等帐号实现联合登录,人家也有要求,就是你必须遵守OAuth2.0协议标准(https://oauth.net/2/)就行. 接下来我们就以android studio为平台,介绍下接入微信的整个流程: 这里有一个官方参考资料:https://open.weixin.qq.com

  • 详解Android微信登录与分享

    Android 使用微信登录.分享功能 具体的文档详情微信官网上介绍(微信官网文档),本人直接按照项目部署步骤进行讲解: 第一步:申请你的AppID: 第二步:依赖 dependencies { compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:1.0.2' } 或者: dependencies { compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:1

  • Android开发:微信授权登录与微信分享完全解析

    前言 在移动互联网浪潮中,联网APP已经把单机拍死在沙滩上,很多公司都希望自家应用能够有一套帐号系统,可是许多用户却并不一定买账:我凭啥注册你家应用的帐号?微博,微信,QQ几乎成了每个人手机中的必装应用,于是微信,微博,QQ说了:来来来,你们都可以用我家的帐号登录你家应用,只要你遵循OAuth2.0协议标准就行.于是第三方社交帐号登陆成为了许多新兴应用的选择,由于腾讯官方微信开放平台的在线文档相对最新的SDK有些出入,并且登录相关的文档结构次序有些紊乱,今天就把我的一些经验记录在此,对微信开放平

  • Android微信第三方登录(个人笔记)

    今天在写微信登录,花了半天时间搞定.然后写下自己的笔记,希望帮助更多的人.欢迎各位指教. 微信授权登录,官方说的不是很清楚.所以导致有一部分的坑. 微信注册应用平台的应用签名,下载 微信签名生成工具 输入项目的packageName也可以查看到. (注意:debug.Release 一定要区分,因为2种生成的微信签名不一致,会导致没有跳转.回调....一般在微信开发者上面注册的是正式环境打包好的.) 申请微信开发者账号.应用申请省略. 1. AndroidManifest.xml 权限 <!--

  • Android 类似微信登录输入框效果

    微信的登录输入框效果如下 进入自动打开自动启动软键盘 点击下一个输入框,下划线颜色改变 怎么实现这样的效果呢,其实非常简单! 简单的布局我就不说了,直接上干货. 1.实现进入自动弹出软键盘,在根文件中的Activity中设置 windowSoftInputMode 属性为 stateVisible|adjustResize 例如 <activity android:name=".SetLoginPasswordActivity" android:windowSoftInputMo

  • 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 WXEntryActivi

  • sql server 2008 数据库管理系统使用SQL语句创建登录用户步骤详解

    废话不多说了,直接给大家贴代码了,具体代码如下所示: --服务器角色: --固定服务器角色具有一组固定的权限,并且适用于整个服务器范围. 它们专门用于管理 SQL Server,且不能更改分配给它们的权限. --可以在数据库中不存在用户帐户的情况下向固定服务器角色分配登录. --按照从最低级别的角色(bulkadmin)到最高级别的角色(sysadmin)的顺序进行描述: --1.Bulkadmin:这个服务器角色的成员可以运行BULKINSERT语句.这条语句允许从文本文件中将数据导入到SQL

  • 修改Android中hosts文件的步骤详解

    前言 在开发的时候我们可能会需要修改Android的hosts文件.Android的hosts文件路径是/system/etc/hosts,在修改该文件前首先需要Android手机获取root权限.至于如何root你的手机,这里就不加详述,可以自行在网络上查找,很多也很简单. 本文将要阐述的是如何在命令行下通过adb程序访问root过的手机,把hosts拖到电脑上修改,然后再复制回手机来实现修改hosts的方法. 下面就开始具体的步骤: C:\tools>adb pull /system/etc

  • Laravel搭建后台登录系统步骤详解

    本文实例讲述了Laravel搭建后台登录系统的方法.分享给大家供大家参考,具体如下: 今天想用laravel搭建一个后台系统,就需要最简单的那种,有用户登录系统,试用了下,觉得laravel的用户登录这块做的还真happy.当然,前提就是,你要的用户管理系统是最简单的那种,就是没有用户权限,能登录就好. 我这里就不用默认的user表做例子了,那样很容易和laravel的一些默认设置混淆. 首先确认,后台的用户表,我设计表叫做badmin,每个管理员有用户名(username),有昵称(nickn

  • Android源码导入Eclipse步骤详解

    我们找到一个android的源码之后 想要修改如果一个一个文件导入会非常的麻烦.我们就可以批量的把android源码导入到eclipse里面.今天我来交给大家 首先我们先打开我们的 eclipse开发工具.过程中会出现一个让你选择开发空间的一个选项  我们直接OK 就可以了. 进入到我们的 主页面了.我们选择左上角的  文件----导入.如下图所示 进入下一个页面之后.我们选择 导入的是 android文件.所以我们选择  下面红色方框里面的东西.点击   下一步 这里就是该你选择 你的源码的 

  • 基于VSTS的Xamarin.Android持续集成步骤详解

    目录 Build Agent 环境需求 Build的部分分为以下步骤 1. 还原NuGet包 2. 替换版本号 3. 编译Android程序 4. 获取编译Andorid的AndroidManifest数据 5. 对编译好的Android apk进行签名 6. 删除多余的文件 7. 生成 ReleaseNotes 8. 生成预发布脚本 这些天做了一个,这里分享下 Build Agent 环境需求 DotNetFramework msbuild visualstudio AndroidSDK JD

  • PHP实现微信支付(jsapi支付)流程步骤详解

    最近接触到一个项目,涉及到微信支付,搞微信开发这么久以来,还没搞过支付,之前也就搞过公众号发红包,感谢前辈们的探索,我看了他们的博文,让我少走了很多弯路. 前期准备: 1.微信认证服务号,并且开通了微信支付 2.微信支付SDK,下载地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 3.登录微信支付平台https://pay.weixin.qq.com/index.php/account/api_cert下载支付证书

  • PHP实现微信支付(jsapi支付)和退款(无需集成支付SDK)流程教程详解

    之前有写过几篇文章将微信支付和退款: 1.PHP实现微信支付(jsapi支付)流程 2.ThinkPHP中实现微信支付(jsapi支付)流程 3.PHP实现微信申请退款 这几篇都是使用了微信官方给的PHP版本的SDK,进行支付的时候写代码可以省不少事,步骤也挺简化,但是集成SDK有很多坑,很多人说引入的SDK老报错,或者说官方SDK本身有不少错误,改起来很麻烦,也确实挺麻烦的,对于新手搞支付很容易被绕进去,那么今天就来讲讲不集成支付SDK直接调用支付接口实现支付和退款. 前期准备: 1.当然了,

  • Android几种多渠道打包的步骤详解

    1.什么是多渠道打包 在不同的应用市场可能有不同的统计需求,需要为每个应用市场发布一个安装包,这里就引出了Android的多渠道打包.在安装包中添加不同的标识,以此区分各个渠道,方便统计app在市场的各种. 2.几种打包方式 友盟 UMeng Android Studio自带 美团 Walle 3.开始使用 3.1 友盟UMeng 第一步:在AndroidManifest中添加 <meta-data android:name="UMENG_CHANNEL" android:val

  • Android Studio 3.6安装全过程及AVD安装运行步骤详解

    1.安装JDK1.7以上版本,Android Studio集成开发环境 (1)安装并检查JDK1.8,如图1.1所示 图1.1 配置完成的验证 (2)开始安装Android Studio集成开发环境,安装允许以管理员模式运行,如图1.2所示 图1.2 安装界面 (3)安装位置为F:\Studio\ android-studio-ide-192.6200805-windows,进行安装,如图1.3所示 图1.3 安装位置 (4)Android Studio集成开发环境安装完成,如图1.4所示 图1

随机推荐