网站首页 > 开源技术 正文
作者:天枢破军
链接:https://juejin.im/post/5d77b123f265da03970be35b
申请账号
去微信开放平台申请账号
使用方法是把这个APP安装到手机,然后把要获取签名的APP使用发布版签名安装到同一个手机,然后输入包名点击下图的获取。
签名和包名填写到页面底部的这里↓
然后在页面顶部复制这个AppID,这个东西是不会变的,复制一次就行了,下面的AppSecret可用可不用。
因为微信的登录回调写得很智障,用户昵称头像之类的东东,你和后台,谁去管微信要,谁就要用到这个AppSecret
自动给debug包签名
如果不想每次都手动签名,可以使用gradle脚本自动签名。 在APP的build.gradle下android中加入
signingConfigs {
debug {
keyAlias 'aaa'//库中对应的签名文件
keyPassword '123456'//签名密码
storeFile file('D:/AndroidProjects/xxx.jks')//签名库文件路径和名称,强烈建议存在项目目录里
storePassword '123456'//签名库密码
}
}
导入lib
跟我念:Gradle大法好!微信支付和微信登录都在这一个包里,导入就完事了
//微信SDK implementation 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
登录代码(写到你的登录界面里)
先实例化一个微信API对象
Java
private IWXAPI api;
//实例化全局微信api对象,可以写到Activity的onCreate里也可以把整个对象放在Application里全局使用
api = WXAPIFactory.createWXAPI(this, "你的AppID", false);
api.registerApp("你的AppID");
Kotlin
lateinit var api: IWXAPI
//实例化全局微信api对象,可以写到Activity的onCreate里也可以把整个对象放在Application里全局使用
api = WXAPIFactory.createWXAPI(this, "你的AppID", false)
api.registerApp("你的AppID")
然后是登录方法
Java
private void login(IWXAPI api) {
if (!api.isWXAppInstalled()) {
ToastUtils.showShort("您还未安装微信客户端!");//这里是一句Toast,可以用你自己的Toast工具类替换
return;
}
SendAuth.Req req = SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = "wechat_sdk_demo_test";
api.sendReq(req);
finish();
}
Kotlin
private fun login(api: IWXAPI) {
if (!api.isWXAppInstalled) {
ToastUtils.showShort("您还未安装微信客户端!")//这里是一句Toast,可以用你自己的Toast工具类替换
return
}
val req = SendAuth.Req()
req.scope = "snsapi_userinfo"
req.state = "wechat_sdk_demo_test"
api.sendReq(req)
finish()
}
直接调用这个方法就可以请求微信登录,回调写的下面提到的Activtiy里。
对,没错,回调写到其他Activity里,是不是很扯淡?不知道他微信的SDK开发人员脑子里是不是进了硫酸(╯‵□′)╯︵┻━┻写出这种神仙操作逻辑。
创建wxapi的Activity
在你的包名下建一个子package叫wxapi,这个名字不能改,然后在里面新建
WXEntryActivity -> 微信登录/微信分享回调
WXPayEntryActivity -> 微信支付回调
他们都继承Activity实现IWXAPIEventHandler接口
注册回调Activity
<!-- 微信回调STRART --> <activity android:name=".wxapi.WXEntryActivity" android:configChanges="keyboardHidden|orientation|screenSize" android:exported="true" android:theme="@android:style/Theme.Translucent.NoTitleBar" /> <!--/*微信支付*/--> <activity android:name=".wxapi.WXPayEntryActivity" android:exported="true" android:launchMode="singleInstance" android:theme="@style/AppSplash"> <!-- 微信支付 --> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="在这里填写AppID" /> </intent-filter> </activity>
style内容
<style name="AppSplash" parent="Theme.AppCompat.Light.NoActionBar"> <!-- 设置启动背景透明 --> <item name="android:windowIsTranslucent">true</item> <!-- 设置启动不要Title --> <item name="android:windowNoTitle">true</item> </style>
本篇讲微信登录,支付用的WXPayEntryActivity如果你的项目没用到可以不写也没关系。
在WXEntryActivity和刚才一样拿一个WXAPI对象,创建过程是一毛一样的这里就省略不写了,如果你一开始是写在Application里面的现在直接拿来用就好了。
不同的是这次要在onCreate和onNewIntent里加上
setIntent(intent);//onNewIntent还要在前面加这句,onCreate不用 api.handleIntent(intent, this);
然后重写onReq(请求发出)和onResp(请求返回)两个方法
发出的地方(onReq)打个日志就好
Toast.makeText(this, "openid = " + req.openId, Toast.LENGTH_SHORT).show();
接收返回的地方(onResp)我们来搞事情
Java
@Override
private void onResp(BaseResp resp) {
String result = "";
switch (resp.errCode) {
case BaseResp.ErrCode.ERR_USER_CANCEL:
result = "操作取消";
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
result = "请求被拒绝";
break;
default:
result = "未知错误";
break;
}
}
switch (resp.type) {
case 1:{
if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
SendAuth.Resp resp2 = (SendAuth.Resp) resp;
val code = resp2.code;
result = "登录成功";
getAccessToken(code);//如果你家后台要昵称头像啥的用户信息你还要用这个code去请求微信的接口,否则在这里直接返回code给后台即可
}
break;
}
case 2: {
if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
result = "分享成功";
}
}
}
ToastUtil.showShort(result);
Logger.d(result);
}
Kotlin
override fun onResp(resp: BaseResp) {
when (resp.errCode) {
BaseResp.ErrCode.ERR_USER_CANCEL -> result = "操作取消"
BaseResp.ErrCode.ERR_AUTH_DENIED -> result = "请求被拒绝"
else -> {
result = "未知错误"
}
}
when (resp.type) {
1 -> {
if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
val code = (resp as SendAuth.Resp).code
result = "登录成功"
getAccessToken(code)//如果你家后台要昵称头像啥的用户信息你还要用这个code去请求微信的接口,否则在这里直接返回code给后台即可
}
}
2 -> {
if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
result = "分享成功"
}
}
}
ToastUtil.showShort(result)
Logger.d(result)
}
如果你家后台只要code的话,到这里为止就结束了,把getAccessToken那个方法换成http请求发给你家后台就行了。
如果你还想拿微信的昵称和头像的话,请继续往下看。
用code调微信接口拿token
Java+OkHttp3
private void getAccessToken(String code) {
// String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
String url = "https://api.weixin.qq.com/sns/oauth2/access_token";
OkHttpClient mOkHttpClient = new OkHttpClient();
///< Post方式也可以...
// RequestBody body = new FormBody.Builder()
// .add("appid", "替换为你的appid")
// .add("secret", "替换为你的app密钥")
// .add("code", code)
// .add("grant_type", "authorization_code")
// .build();
url += "?appid=" + "替换为你的appid" + "&secret=xxxxxxxx"
+ "&code=" + code + "&grant_type=authorization_code";
final Request request = new Request.Builder()
.url(url)
//.post(body)
.build();
Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
finish();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String json = response.body().string();
AccessToken accessToken = JSONObject.parseObject(json, new TypeReference<AccessToken>() {
});
getUserInfo(accessToken.getAccess_token(), accessToken.getOpenid());
}
});
}
Kotlin+Kolley
/**
* @param code 根据code再去获取AccessToken
*/
private fun getAccessToken(code: String) {
// String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
///< Post方式也可以...
// RequestBody body = new FormBody.Builder()
// .add("appid", "替换为你的appid")
// .add("secret", "替换为你的app密钥")
// .add("code", code)
// .add("grant_type", "authorization_code")
// .build();
Http.post {
// url += ("?appid=" + "替换为你的appid" + "&secret=xxxxxxxx"
// + "&code=" + code + "&grant_type=authorization_code")
url = "https://api.weixin.qq.com/sns/oauth2/access_token"
params {
"appid" - "你的AppID"
"secret" - "你的Secret"
"code" - code//你拿到的code
"grant_type" - "authorization_code"
}
onSuccess { byts ->
var result = byts.toString(Charset.defaultCharset())
if (TextUtils.isNotEmpty(result)) {
val model: WXTokenModel = StringNullAdapter.gson.fromJson(result)
getUserInfo(model.access_token, model.openid)
}
}
onFail { error ->
var message = error.message
ToastUtil.showShort(message)
}
}
}
其中用到的
kolley是一个仅支持Kotlin的轻量级网络请求框架
StringNuallAdapter是一个解析json时即使遇到空也不会崩溃的第三方库仅支持Kotlin
implementation 'com.ohmerhe.kolley:kolley:0.3.1' implementation 'com.github.mfangtao:FTLibary:2.0.2'
WXTokenModel
JavaBean
public class WXTokenModel{
private String access_token = "";
private int expires_in = 0;
private var openid: String = "";
private String refresh_token = "";
private String scope: = "";
//getter/setter略
}
Kotlin data class
data class WXTokenModel( var access_token: String = "", var expires_in: Int = 0, var openid: String = "", var refresh_token: String = "", var scope: String = "" )
用token调微信接口拿用户信息
Java+OkHttp3
private void getUserInfo(String access_token, String openid) {
// String url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
String url = "https://api.weixin.qq.com/sns/userinfo";
OkHttpClient mOkHttpClient = new OkHttpClient();
RequestBody body = new FormBody.Builder()
.add("access_token", access_token)
.add("openid", openid)
.build();
final Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
finish();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String json = response.body().string();
WXUserInfo wxUserInfo = JSONObject.parseObject(json, new TypeReference<WXUserInfo>() {
});//至此昵称头像全部到手,传给你家后台吧
finish();
}
});
}
Kotlin+kolley
private fun getUserInfo(access_token: String, openid: String) {
// String url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
Http.post {
url = "https://api.weixin.qq.com/sns/userinfo"
params {
"access_token" - access_token
"openid" - openid
}
onSuccess { byts ->
var result = byts.toString(Charset.defaultCharset())
if (TextUtils.isNotEmpty(result)) {
val model: WXUserInfo = StringNullAdapter.gson.fromJson(result)
sendThird(openid, model.headimgurl, model.nickname)//至此昵称头像全部到手,传给你家后台吧
}
}
onFail { error ->
var message = error.message
ToastUtil.showShort(message)
}
}
}
WXUserInfo
JavaBean
public class WXUserInfo( private String city = ""; private String country = ""; private String headimgurl = ""; private String nickname = ""; private String openid= ""; private List<String> privilege = ArrayList(); private String province ""; private int sex 0; private String unionid ""; //getter/setter略 )
Kotlin data class
data class WXUserInfo( var city: String = "", var country: String = "", var headimgurl: String = "", var nickname: String = "", var openid: String = "", var privilege: MutableList<String> = ArrayList(), var province: String = "", var sex: Int = 0, var unionid: String = "" )
微信登录奇怪的调用链导致的问题
这里的调用链是你的登录界面→微信的登录界面→微信的回调界面,你会发现在这个跳转中由于微信的登录界面这个东东屁都不给你返回,你的登录界面不能通过onActivtiyResult之类的方法去拿登录结果,登录结果被传给了微信的回调界面。
你的登录界面完完全全就是个请求发送器,发送请求之后就没用了,所以在api.sendReq(req)这行下面通常都会加一句finish()让登录界面出栈,避免用户在APP玩了一圈想退出的时候退回到了栈底的登录界面。
当然这样一来会导致一个问题,那就是用户在微信授权的界面点退出直接就没有栈底元素了直接回桌面了,但是这种情况一样会走到WXEntryActivity里,所以解决办法就是在WXEntryActivity里当resp.errCode != BaseResp.ErrCode.ERR_OK的时候手动去启动一下我们自己的登录界面。
关于集成友盟的登录方案
如果你的项目使用了友盟分享的话,就不用导入一开始说的那个库了,取而代之的是下面这个库
implementation 'com.umeng.umsdk:share-wx:6.9.4'
然后在Application的onCreate中加上
UMConfigure.init(this, "友盟AppKey", "Umeng", UMConfigure.DEVICE_TYPE_PHONE, "友盟MessageSecret");
PlatformConfig.setWeixin("微信AppID", "微信AppSecret");
调用改为 Java
private UMShareAPI umShareAPI; private UMAuthListener umAuthListener;//这东西的方法直接空实现即可,因为它的回调微信不会走。是方法空实现,不是对象留空 //onCreate中 umShareAPI = UMShareAPI.get(this); //调用登录 umShareAPI.getPlatformInfo(this, SHARE_MEDIA.WEIXIN, umAuthListener);//微信登录
Kotlin
lateinit var umShareAPI: UMShareAPI lateinit var umAuthListener: UMAuthListener//这东西的方法直接空实现即可,因为它的回调微信不会走。是方法空实现,不是对象留空 //onCreate中 umShareAPI = UMShareAPI.get(this) //调用登录 umShareAPI.getPlatformInfo(this, SHARE_MEDIA.WEIXIN, umAuthListener)//微信登录
最后
谢谢大家阅读都这里,想看更多技术文章可以给我加个关、。
我从事Android开发快十年了,今年年初我花两个月的时间收录整理了一套知识体系,此外,还有面试专题、架构视频,如果有想法深入的系统化的去学习的,可以关注我,我会把我收录整理的资料都送给大家,帮助大家更快的提升。
私信【架构】
关注+转发+私信,让更多需要的朋友们都可以免费看到、领到。
猜你喜欢
- 2024-10-12 Java实现微信支付程序的解决方案(java实现微信支付程序的解决方案有哪些)
- 2024-10-12 微信支付的SDK曝出重大漏洞,看程序开发人员怎么讲?
- 2024-10-12 JAVA 线上故障排查完整套路!牛掰(java在线运行平台)
- 2024-10-12 Android 11 安装外部来源应用需要重启 APP
- 2024-10-12 网络安全之Springboot heapdump信息泄露复现
- 2024-10-12 Fanx 语言 3.2 发布,全面支持中文编程
- 2024-10-12 如果网站的 Cookie 特别多特别大,会发生什么情况?
- 2024-10-12 JAVA后端推送企业微信消息到普通微信
- 2024-10-12 xk-time 1.1.1 发布,Java 时间工具包
- 2024-10-12 微信、企业微信和支付窗极速SDK三合一,JeeWx-api 1.2.0版本发布
欢迎 你 发表评论:
- 1598℃北京那些看上去很牛的车牌们!(北京厉害车牌)
- 1115℃2025年度视频去水印软件TOP5对比:哪款最值得用
- 603℃新疆话里的“虫子”
- 529℃中兴光猫 Telnet下设置大全(中兴光猫命令大全)
- 521℃蓝牙设备配对失败的系统性解决方案与技术解析
- 518℃未备份电脑文件数据恢复的七种方法
- 502℃工艺管道常用英文缩写 英汉对照
- 457℃是爱情啊!比伯分享度假照 与海莉礁石上甜蜜接吻
- 最近发表
- 标签列表
-
- jdk (81)
- putty (66)
- rufus (78)
- 内网穿透 (89)
- okhttp (70)
- powertoys (74)
- windowsterminal (81)
- netcat (65)
- ghostscript (65)
- veracrypt (65)
- asp.netcore (70)
- wrk (67)
- aspose.words (80)
- itk (80)
- ajaxfileupload.js (66)
- sqlhelper (67)
- express.js (67)
- phpmailer (67)
- xjar (70)
- redisclient (78)
- wakeonlan (66)
- tinygo (85)
- startbbs (72)
- webftp (82)
- vsvim (79)

本文暂时没有评论,来添加一个吧(●'◡'●)