前言:接着上一篇QQ登录~
1、效果图
登录前:
登录后:
2、微信开放平台注册应用:链接:https://open.weixin.qq.com/
创建应用并获得需要的参数
填入应用包名与签名如下图,下载地址非必填
关于签名在build.gradle配置如下,这样运行出来的则是正式版本签名
signingConfigs {
debug {
storeFile file('D:/workspace/helloword.jks')
storePassword '123456'
keyAlias '123'
keyPassword '123456'
}
release {
storeFile file('D:/workspace/helloword.jks')
storePassword '123456'
keyAlias '123'
keyPassword '123456'
}
}
3、登录类
public class TestActivity extends AppCompatActivity {
private static final String TAG = "TestActivity";
//微信AppID
public static final String APP_ID = "wx08c24bb11123e4f5";
//微信AppSecret
public static final String WEIXIN_ID = "66fzzds17e660f5f5zq4f9d5e283aweba3";
//展示个人信息
private TextView infoText, infoName;
private ImageView infoIcon;
//初始化微信服务
private IWXAPI api;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
//注册EventBus
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().register(this);
}
//通过WXAPIFactory工厂,获取IWXAPI实例,是否检查signature
api = WXAPIFactory.createWXAPI(this, APP_ID, true);
//将应用的appId注册到微信
api.registerApp(APP_ID);
infoText = this.findViewById(R.id.text_info);
infoIcon = this.findViewById(R.id.info_icon);
infoName = this.findViewById(R.id.info_name);
//登录点击事件
findViewById(R.id.button_login).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loginWeiXin();
}
});
}
/**
* 微信登录
*/
private void loginWeiXin() {
SendAuth.Req auth = new SendAuth.Req();
//snsapi_base属于基础接口,若应用已拥有其它scope权限,则默认拥有snsapi_base的权限。
//使用snsapi_base可以让移动端网页授权绕过跳转授权登录页请求用户授权的动作,
//直接跳转第三方网页带上授权临时票据(code),但会使得用户已授权作用域(scope)仅为snsapi_base,
//从而导致无法获取到需要用户授权才允许获得的数据和基础功能。
auth.scope = "snsapi_userinfo";
auth.state = "wechat_sdk_微信登录";
api.sendReq(auth);//向微信发送请求
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void OnLoginWeiXinEvent(LoginWeiXinEvent event) {
//获取Token信息
getWeiXinAccessToken(event.getCode());
}
/**
* 根据code获取微信token
*/
private void getWeiXinAccessToken(String code) {
String url = "https://api.weixin.qq.com/sns/oauth2/access_token" +
"?appid=" + APP_ID
+ "&secret=" + WEIXIN_ID
+ "&code=" + code
+ "&grant_type=authorization_code&connect_redirect=1";
Log.e(TAG, "请求url:" + url);
Log.e(TAG, "请求code:" + code);
//1.okhttpClient对象
// OkHttpClient okHttpClient = new OkHttpClient();
//2、构造Request,
//builder.get()代表的是get请求,url方法里面放的参数是一个网络地址
// Request.Builder builder = new Request.Builder();
//okHttpClient.sslSocketFactory();
//okHttpClient.
Request request = new Request.Builder().url(url).build();
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
// Request request = builder.get().url(url).build();
//3将Request封装成call
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//失败回调
Log.e(TAG, "请求失败:" + e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//成功回调
String result = response.body().string();
Log.e(TAG, "请求成功:" + result);
try {
JSONObject jsonObject = new JSONObject(result);
String token = jsonObject.getString("access_token");
String openId = jsonObject.getString("openid");
Log.e(TAG, "登录token:" + token);
Log.e(TAG, "登录openId:" + openId);
//获取用户信息
getUserInfo(token, openId);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
/**
* 获取个人信息
* 根据openId和token获取个人信息
*/
private void getUserInfo(final String token, final String openId) {
String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + token + "&openid=" + openId;
Log.e(TAG, "请求token:" + token);
Log.e(TAG, "请求openId:" + openId);
Request request = new Request.Builder().url(url).build();
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e(TAG, "请求失败:" + e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//成功回调
final String result = response.body().string();
Log.e(TAG, "请求成功:" + result);
try {
JSONObject jsonObject = new JSONObject(result);
final String nickname = jsonObject.getString("nickname");
final String headimgurl = jsonObject.getString("headimgurl");
//切换至主线程上
runOnUiThread(new Runnable() {
@Override
public void run() {
//头像
GlideUtils.showGlide(TestActivity.this, headimgurl, infoIcon);
//昵称
infoName.setText(nickname);
infoText.setText(result);
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
@Override
public void onDestroy() {
super.onDestroy();
//销毁EventBus
if (EventBus.getDefault().isRegistered(this))//加上判断
EventBus.getDefault().unregister(this);
}
}
对应布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="10dp"
tools:context=".activity.TestActivity">
<ImageView
android:id="@+id/info_icon"
android:src="@mipmap/ic_launcher"
android:layout_width="150dp"
android:layout_height="150dp" />
<TextView
android:gravity="center"
android:id="@+id/info_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp" />
<TextView
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:id="@+id/text_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp" />
<Button
android:id="@+id/button_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="微信登录" />
</LinearLayout>
4、微信回调类
在最外层新建wxapi包,并新建类名WXEntryActivity(注意不要更改名字)
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
/**
* 微信登录相关
*/
private IWXAPI api;
private static final String TAG = "WXPayEntryActivity";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_bg);
api = WXAPIFactory.createWXAPI(this, APP_ID, true);
//将应用的appid注册到微信
api.registerApp(APP_ID);
//注意:
//第三方开发者如果使用透明界面来实现WXEntryActivity,需要判断handleIntent的返回值,
// 如果返回值为false,则说明入参不合法未被SDK处理,应finish当前透明界面,
// 避免外部通过传递非法参数的Intent导致停留在透明界面,引起用户的疑惑
try {
boolean result = api.handleIntent(getIntent(), this);
if (!result) {
finish();
}
LogUtil.e("result:", result + "");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onReq(BaseReq baseReq) {
}
// 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
//app发送消息给微信,处理返回消息的回调
@Override
public void onResp(BaseResp baseResp) {
/**
* 0 成功 展示成功页面
* -1 错误 可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等
* -2 用户取消 无需处理。发生场景:用户不支付了,点击取消,返回APP
*/
Log.e(TAG, "请求成功:" + "错误码:"+ baseResp.errStr);
Log.e(TAG, "errCode:""errCode:"+baseResp.errCode);
switch (baseResp.errCode) {
case 0:
//拿到了微信返回的code,立马再去请求access_token
String loginCode = ((SendAuth.Resp) baseResp).code;
LoginWeiXinEvent event = new LoginWeiXinEvent();
event.setCode(loginCode);
EventBus.getDefault().post(event);
finish();
break;
case -1:
finish();
break;
case -2:
finish();
break;
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
finish();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
api.handleIntent(data, this);
}
}
其中layout_bg为自动生成布局,无UI界面
LoginWeiXinEvent通知类
public class LoginWeiXinEvent {
private String code;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
5、AndroidManifest.xml清单文件中配置
<!-- 微信登录 -->
<activity
android:name=".wxapi.WXEntryActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
theme设置为透明防止登录后出现白色一闪而过的界面,引起用户疑惑。
6、依赖的资源:
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'//微信登录与支付
implementation 'org.greenrobot:eventbus:3.1.1'//通知
implementation 'com.squareup.okhttp3:okhttp:3.4.1'//网络请求
implementation 'com.github.bumptech.glide:glide:4.7.1'//图片加载