Android应用调用微信登录接口

很多App都是需要用户登录的,例如电商类的APP,用户登录后可以查看自己的购物订单,浏览痕迹等,登陆的话又可以分为多种登录,例如QQ,微信,微博,支付宝等,那么接下来这篇文章讲诉的是应用如何调用微信的支付接口;

要想调用微信登录或者支付等接口首先要在微信公共平台申请一个账号,这是链接微信公众平台,然后再管理中心跟着提示申请一个应用,申请应用的时候包名要跟自己创建的项目的报名一致,否则无法使用,然后就是应用签名,应用签名的话可以下载一个软件到手机上,然后运行自己的项目,两者必须要在同一部手机,然后再软件上输入自己项目的包名,就可以拿到应用签名了(应用链接GenSignature
在这里插入图片描述
应用审核的话一般是一周以内,审核通过之后你就会拿到一个APP_ID和APP_SECRET,这两个在项目里面非常重要,这意味着你的应用能不能调用微信登录接口
创建一个constanst类,用来放APP_ID和APP_SECRET

public class Constants {
    // APP_ID 替换为你的应用从官方网站申请到的合法appID
    public static final String APP_ID = "XXXXXXXXX";
    public static final String APP_SECRET = "XXXXXXXXXXX";
}

移动应用微信登录是基于OAuth2.0协议标准 构建的微信OAuth2.0授权登录系统。微信OAuth2.0授权登录让微信用户使用微信身份安全登录第三方应用或网站,在微信用户授权登录已接入微信OAuth2.0的第三方应用后,第三方可以获取到用户的接口调用凭证(access_token),通过access_token可以进行微信开放平台授权关系接口调用,从而可实现获取微信用户基本开放信息和帮助用户实现基础开放功能等。
这个是获取access_token时序图:登录的流程图
首先要在MainActivity中的onCreate函数中注册

  private void regToWx(){
        api = WXAPIFactory.createWXAPI(this,Constants.APP_ID,false);
        api.registerApp(Constants.APP_ID);
    }

然后先创建WXEntryActivity类
然后重写两个方法onReq以及onResp
在这个类的onCreate函数中接收登录的intent传递handleIntent方法

//接收到分享以及登录的intent传递handleIntent方法,处理结果
        api = WXAPIFactory.createWXAPI(this,Constants.APP_ID,false);
        api.handleIntent(getIntent(),this);

接下来在onRep()方法里获取回调
用户点击授权后,微信客户端会被拉起,跳转至授权界面,用户在该界面点击允许或取消,SDK通过SendAuth的Resp返回数据给调用方

    @Override
    //请求回调结果处理
    public void onResp(BaseResp baseResp) {
        //登录回调
        switch (baseResp.errCode){
            case BaseResp.ErrCode.ERR_OK:
                String code = ((SendAuth.Resp) baseResp).code;
                //获取accesstoken
                getAccessToken(code);
                break;
                //用户拒绝授权
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                finish();
                break;
                //用户取消授权
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                finish();
                break;
        }
    }

通过code来获取access_token,请求以下链接获取access_token:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
这个是请求上面这个链接返回的正确结果


//access_token	接口调用凭证
//expires_in	access_token接口调用凭证超时时间,单位(秒)
//refresh_token	用户刷新access_token
//openid	授权用户唯一标识
//scope	用户授权的作用域,使用逗号(,)分隔
//unionid	当且仅当该移动应用已获得该用户的userinfo授权时,才会出现该字段
{ 
"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID", 
"scope":"SCOPE",
"unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

请求的代码

 private void getAccessToken(String code) {
        //新建一个progressDialog,避免长时间白屏(因为在进行多次网络请求)造成卡死的假象
//        createProgressDialog();
/**
 *        access_token:接口调用凭证
 *        appid:应用唯一标识,在微信开放平台提交应用审核通过后获得。
 *        secret:应用密钥AppSecret,在微信开放平台提交应用审核通过后获得。
 *        code:填写第一步获取的code参数。
 *        grant_type:填authorization_code。
 */
        StringBuffer loginUrl = new StringBuffer();
        loginUrl.append("https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code")
                .append("?appid=")
                .append(Constants.APP_ID)
                .append("&secret=")
                .append(Constants.APP_SECRET)
                .append("&code=")
                .append(code)
                .append("&grant_type=authorization_code");
        Log.d("urlurl", loginUrl.toString());
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder()
                //传入url
                .url(loginUrl.toString())
                //默认也是发起get请求
                .get()
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure: Fail");

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String responseInfo = response.body().string();
                Log.d(TAG, "onResponse: Success");
                String access = null;
                String openId = null;
                //用json去解析返回来的access和token值
                try {
                    JSONObject jsonObject = new JSONObject(responseInfo);
                    access = jsonObject.getString("access_token");
                    openId = jsonObject.getString("openid");
                    Log.d(TAG, "onResponse:"+access + "  " + openId);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                getUserInfo(access, openId);
            }
        });
    }

access_token是调用授权关系接口的调用凭证,由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新,access_token刷新结果有两种:

  1. 若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;
  2. 若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。
    refresh_token拥有较长的有效期(30天),当refresh_token失效的后,需要用户重新授权。
    通过access_token调用接口,再通过getUserInfo(access, openId)方法获取用户信息
 //如果请求成功,我们通过JSON解析获取access和token值,再通过getUserInfo(access, openId)方法获取用户信息
    private void getUserInfo(String access,String openid){
        String getUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access + "&openid=" + openid;
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder()
                .url(getUserInfoUrl)
                .get()
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure: Fail(getUserInfo)");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String responseInfo = response.body().string();
                //用SharedPreference来缓存字符串
                SharedPreferences.Editor editor = getSharedPreferences("userInfo",MODE_PRIVATE).edit();
                editor.putString("responseInfo",responseInfo);
                editor.commit();
                finish();
            }
        });
    }

MainActivity,重写onResume()

  @Override
    protected void onResume() {
        super.onResume();
        String name = null;
        String sex = null;
        String city = null;
        SharedPreferences sharedPreferences = getSharedPreferences("userInfo", MODE_PRIVATE);
        String response = sharedPreferences.getString("responseInfo","");

        if (!response.isEmpty()){
            try {
                JSONObject jsonObject = new JSONObject(response);
                /**
                 * 这里可以返回如下数据
                 * openid	普通用户的标识,对当前开发者帐号唯一
                 * nickname	普通用户昵称
                 * sex	普通用户性别,1为男性,2为女性
                 * province	普通用户个人资料填写的省份
                 * city	普通用户个人资料填写的城市
                 * country	国家,如中国为CN
                 * headimgurl	用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
                 * privilege	用户特权信息,json数组,如微信沃卡用户为(chinaunicom)
                 * unionid	用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。
                 */
                name = jsonObject.getString("nickname");
                sex = jsonObject.getString("sex");
                city = jsonObject.getString("city");
            } catch (JSONException e) {
                e.printStackTrace();
            }
            tv_city.setText("城市:" + city);
            tv_sex.setText("性别:" + sex);
            tv_username.setText("用户名:" + name);
        }
    }

附上全部代码

import androidx.appcompat.app.AppCompatActivity;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import org.json.JSONException;
import org.json.JSONObject;

public class MainActivity extends AppCompatActivity {

    // IWXAPI 是第三方app和微信通信的openApi接口
    private IWXAPI api;
    private ImageView mImageView;
    private TextView tv_sex,tv_city,tv_username;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //onCreate里注册应用
        regToWx();
        //初始化控件
        initView();
        //点击按钮,拉起微信登录
        mImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //先判断用户的手机有没有安装微信,没有的话就弹个Toast
                if (!api.isWXAppInstalled()){
                    Toast.makeText(MainActivity.this,"你的设备没有安装微信,请先下载微信",Toast.LENGTH_SHORT).show();
                }else {
                    //如果有安装则直接发起请求
                    final SendAuth.Req req = new SendAuth.Req();
                    //scope是应用授权作用域,如获取用户个人信息则填写snsapi_userinfo
                    req.scope = "snsapi_userinfo";
                    //state用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击)
                    // 建议第三方带上该参数,可设置为简单的随机数加session进行校验
                    req.state = "wechat_sdk_demo_test";
                    //发起请求
                    api.sendReq(req);
                }
            }
        });
    }

    private void initView() {
        mImageView = findViewById(R.id.WeChat_Login);
        tv_sex = findViewById(R.id.Sex);
        tv_city = findViewById(R.id.City);
        tv_username = findViewById(R.id.User_id);
    }

    private void regToWx(){
        api = WXAPIFactory.createWXAPI(this,Constants.APP_ID,false);
        api.registerApp(Constants.APP_ID);
    }

    @Override
    protected void onResume() {
        super.onResume();
        String name = null;
        String sex = null;
        String city = null;
        SharedPreferences sharedPreferences = getSharedPreferences("userInfo", MODE_PRIVATE);
        String response = sharedPreferences.getString("responseInfo","");

        if (!response.isEmpty()){
            try {
                JSONObject jsonObject = new JSONObject(response);
                /**
                 * 这里可以返回如下数据
                 * openid	普通用户的标识,对当前开发者帐号唯一
                 * nickname	普通用户昵称
                 * sex	普通用户性别,1为男性,2为女性
                 * province	普通用户个人资料填写的省份
                 * city	普通用户个人资料填写的城市
                 * country	国家,如中国为CN
                 * headimgurl	用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
                 * privilege	用户特权信息,json数组,如微信沃卡用户为(chinaunicom)
                 * unionid	用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。
                 */
                name = jsonObject.getString("nickname");
                sex = jsonObject.getString("sex");
                city = jsonObject.getString("city");
            } catch (JSONException e) {
                e.printStackTrace();
            }
            tv_city.setText("城市:" + city);
            tv_sex.setText("性别:" + sex);
            tv_username.setText("用户名:" + name);
        }
    }
}

import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class WXEntryActivity extends AppCompatActivity implements IWXAPIEventHandler {

    private IWXAPI api;
    public static final String TAG = "Log:";
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //隐藏状态栏并获取wxapi
        getSupportActionBar().hide();
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
        //接收到分享以及登录的intent传递handleIntent方法,处理结果
        api = WXAPIFactory.createWXAPI(this,Constants.APP_ID,false);
        api.handleIntent(getIntent(),this);
    }


    @Override
    public void onReq(BaseReq baseReq) {

    }

    @Override
    //请求回调结果处理
    public void onResp(BaseResp baseResp) {
        //登录回调
        switch (baseResp.errCode){
            case BaseResp.ErrCode.ERR_OK:
                String code = ((SendAuth.Resp) baseResp).code;
                //获取accesstoken
                getAccessToken(code);
                break;
                //用户拒绝授权
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                finish();
                break;
                //用户取消授权
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                finish();
                break;
        }
    }

    private void getAccessToken(String code) {
        //新建一个progressDialog,避免长时间白屏(因为在进行多次网络请求)造成卡死的假象
//        createProgressDialog();
/**
 *        access_token:接口调用凭证
 *        appid:应用唯一标识,在微信开放平台提交应用审核通过后获得。
 *        secret:应用密钥AppSecret,在微信开放平台提交应用审核通过后获得。
 *        code:填写第一步获取的code参数。
 *        grant_type:填authorization_code。
 */
        StringBuffer loginUrl = new StringBuffer();
        loginUrl.append("https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code")
                .append("?appid=")
                .append(Constants.APP_ID)
                .append("&secret=")
                .append(Constants.APP_SECRET)
                .append("&code=")
                .append(code)
                .append("&grant_type=authorization_code");
        Log.d("urlurl", loginUrl.toString());
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder()
                //传入url
                .url(loginUrl.toString())
                //默认也是发起get请求
                .get()
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure: Fail");

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String responseInfo = response.body().string();
                Log.d(TAG, "onResponse: Success");
                String access = null;
                String openId = null;
                //用json去解析返回来的access和token值
                try {
                    JSONObject jsonObject = new JSONObject(responseInfo);
                    access = jsonObject.getString("access_token");
                    openId = jsonObject.getString("openid");
                    Log.d(TAG, "onResponse:"+access + "  " + openId);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                getUserInfo(access, openId);
            }
        });
    }
    //如果请求成功,我们通过JSON解析获取access和token值,再通过getUserInfo(access, openId)方法获取用户信息
    private void getUserInfo(String access,String openid){
        String getUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access + "&openid=" + openid;
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder()
                .url(getUserInfoUrl)
                .get()
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure: Fail(getUserInfo)");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String responseInfo = response.body().string();
                //用SharedPreference来缓存字符串
                SharedPreferences.Editor editor = getSharedPreferences("userInfo",MODE_PRIVATE).edit();
                editor.putString("responseInfo",responseInfo);
                editor.commit();
                finish();
            }
        });
    }
}


public class Constants {
    // APP_ID 替换为你的应用从官方网站申请到的合法appID
    public static final String APP_ID = "wxf380bfb3deb2735f";
    public static final String APP_SECRET = "cc25489c2e2ad9ccf0aeb4122d12a9f5";
}

别忘了权限

    <uses-permission android:name="android.permission.INTERNET" />

    <!-- for mta statistics, not necessary-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".WXEntryActivity"
            android:theme="@android:style/Theme.Translucent.NoTitleBar"
            android:configChanges="keyboardHidden|orientation|screenSize"
            android:exported="true"
            android:screenOrientation="portrait" />
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要实现微信登录,需要以下步骤: 1. 在微信开放平台上注册账户,创建应用,获取AppID和AppSecret等信息。 2. 在AndroidManifest.xml文件中添加以下内容: ``` <activity android:name=".wxapi.WXEntryActivity" android:exported="true" android:taskAffinity="${applicationId}" android:launchMode="singleTask"> <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <<data android:scheme="wx{AppID}"/> </intent-filter> </activity> ``` 其中,{AppID}为在微信开放平台上注册应用时获取到的AppID。 3. 创建WXEntryActivity类,并实现IWXAPIEventHandler接口,处理微信登录的响应结果。 ``` public class WXEntryActivity extends AppCompatActivity implements IWXAPIEventHandler { private IWXAPI api; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); api = WXAPIFactory.createWXAPI(this, "{AppID}", true); api.handleIntent(getIntent(), this); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); api.handleIntent(intent, this); } @Override public void onReq(BaseReq req) { } @Override public void onResp(BaseResp resp) { if (resp.getType() == ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX) { switch (resp.errCode) { case BaseResp.ErrCode.ERR_OK: // 登录成功 String code = ((SendAuth.Resp) resp).code; // TODO: 使用code向服务器请求access_token等信息 break; case BaseResp.ErrCode.ERR_USER_CANCEL: // 用户取消登录 break; case BaseResp.ErrCode.ERR_AUTH_DENIED: // 用户拒绝授权 break; default: // 登录失败 break; } } finish(); } } ``` 4. 在登录页面中添加微信登录的按钮,并在点击事件中调用以下代码: ``` SendAuth.Req req = new SendAuth.Req(); req.scope = "snsapi_userinfo"; req.state = "wechat_login"; api.sendReq(req); ``` 其中,api为IWXAPI对象,需要在登录页面中进行初始化。 5. 在服务器端实现微信登录的逻辑,使用code向微信服务器请求access_token等信息,并根据返回的用户信息完成用户的注册或登录等操作。 以上就是AndroidStudio实现微信登录的基本步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值