android开发第三方微信登录授权且获取用户信息

今天给小伙伴们奉上一篇第三方微信登录的实现

android开发第三方微信登录授权且获取用户信息_第1张图片

android开发第三方微信登录授权且获取用户信息_第2张图片

工程结构

android开发第三方微信登录授权且获取用户信息_第3张图片

因为是一个demo做的比较简陋,望小伙伴们见谅

准备工作。我们首先需要去微信平台申请的app应用,绑定一个app,并去申请功能的使用权限

在微信平台的申请的那个app,打包后(非debug包),在打包后的app应用软件里面下载一个app签名工具,在app签名工具里面输入appmanifest里面的包名,包名是package里面的,一定要是这个包名,别把包名弄混了,最后生成一个签名,放在微信开放平台的信息输入框里面)

android开发第三方微信登录授权且获取用户信息_第4张图片

 然后就是调用微信的回调类: WXEntryActivity 而且这个类名必须是这个,而这个类名必须在.wxapi包名下,不然微信无法掉起,并在AndroidManifest.xml配置(小伙伴们包名要用自己的包名哟)

 
     

然后去自己申请的app里面拿到appid和secret这两个key(如果小伙伴们的没有申请成功,可以使用我的key)

android开发第三方微信登录授权且获取用户信息_第5张图片

下面就开始看干货了

WXEntryActivity

package com.example.weixindemo.wxapi;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentSkipListMap;

import org.json.JSONObject;

import okhttp3.Call;
import okhttp3.Response;

import com.example.weixindemo.App;
import com.example.weixindemo.MainActivity;
import com.example.weixindemo.NetUtils;
import com.example.weixindemo.NetUtils.MyNetCall;
import com.example.weixindemo.bean.WeixinBean;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
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.modelmsg.WXTextObject;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
	private IWXAPI api;
	private BaseResp resp = null;
	public static String WX_APP_ID = "wx712ebdaa2ff851b6";
	// 获取第一步的code后,请求以下链接获取access_token
	private String GetCodeRequest = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
	// 获取用户个人信息
	private String GetUserInfo = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
	private String WX_APP_SECRET = "67bc80cf2ee42da9fdcb1d3509fec472";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		api = WXAPIFactory.createWXAPI(this, WX_APP_ID, false);
		api.handleIntent(getIntent(), this);
	}

	// 微信发送请求到第三方应用时,会回调到该方法
	@Override
	public void onReq(BaseReq req) {
		finish();
	}

	// 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
	@Override
	public void onResp(BaseResp resp) {
		String result = "";
		if (resp != null) {
			resp = resp;
		}
		switch (resp.errCode) {
		case BaseResp.ErrCode.ERR_OK:
			result = "发送成功";
			Toast.makeText(this, result, Toast.LENGTH_LONG).show();
			String code = ((SendAuth.Resp) resp).code;
			Log.i("TGA", code + "------------");
			/*
			 * 将你前面得到的AppID、AppSecret、code,拼接成URL 获取access_token等等的信息(微信)
			 */
			String get_access_token = getCodeRequest(code);
			Map reqBody = new ConcurrentSkipListMap<>();
			NetUtils netUtils = NetUtils.getInstance();
			netUtils.postDataAsynToNet(get_access_token, reqBody,
					new NetUtils.MyNetCall() {
						@Override
						public void success(Call call, Response response)
								throws IOException {

							String responseData = response.body().string();
							parseJSONWithGSON(responseData);

						}

						@Override
						public void failed(Call call, IOException e) {

						}

					});

			finish();
			break;
		case BaseResp.ErrCode.ERR_USER_CANCEL:
			result = "发送取消";
			Toast.makeText(this, result, Toast.LENGTH_LONG).show();
			finish();
			break;
		case BaseResp.ErrCode.ERR_AUTH_DENIED:
			result = "发送被拒绝";
			Toast.makeText(this, result, Toast.LENGTH_LONG).show();
			finish();
			break;
		default:
			result = "发送返回";
			Toast.makeText(this, result, Toast.LENGTH_LONG).show();
			finish();
			break;
		}
	}

	/**
	 * 通过拼接的用户信息url获取用户信息
	 * 
	 * @param user_info_url
	 */
	private void getUserInfo(String user_info_url) {
		Map reqBody = new ConcurrentSkipListMap<>();
		NetUtils netUtils = NetUtils.getInstance();
		netUtils.postDataAsynToNet(user_info_url, reqBody,
				new NetUtils.MyNetCall() {
					@Override
					public void success(Call call, Response response) throws IOException{
						String str = response.body().string();
						parseJSONUser(str);
					
					}

					@Override
					public void failed(Call call, IOException e) {

					}

				});

	}

	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		setIntent(intent);
		api.handleIntent(intent, this);
		finish();
	}

	/**
	 * 获取access_token的URL(微信)
	 * 
	 * @param code
	 *            授权时,微信回调给的
	 * @return URL
	 */
	private String getCodeRequest(String code) {
		String result = null;
		GetCodeRequest = GetCodeRequest.replace("APPID",
				urlEnodeUTF8(WX_APP_ID));
		GetCodeRequest = GetCodeRequest.replace("SECRET",
				urlEnodeUTF8(WX_APP_SECRET));
		GetCodeRequest = GetCodeRequest.replace("CODE", urlEnodeUTF8(code));
		result = GetCodeRequest;
		return result;
	}

	/**
	 * 获取用户个人信息的URL(微信)
	 * 
	 * @param access_token
	 *            获取access_token时给的
	 * @param openid
	 *            获取access_token时给的
	 * @return URL
	 */
	private String getUserInfo(String access_token, String openid) {
		String result = null;
		GetUserInfo = GetUserInfo.replace("ACCESS_TOKEN",
				urlEnodeUTF8(access_token));
		GetUserInfo = GetUserInfo.replace("OPENID", urlEnodeUTF8(openid));
		result = GetUserInfo;
		return result;
	}

	private String urlEnodeUTF8(String str) {
		String result = str;
		try {
			result = URLEncoder.encode(str, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	// 解析返回的数据
	private void parseJSONWithGSON(String jsonData) {
		// 使用轻量级的Gson解析得到的json
		Gson gson = new Gson();
		WeixinBean appList = gson.fromJson(jsonData,
				new TypeToken() {
				}.getType());
		// 控制台输出结果,便于查看
		String str = getUserInfo(appList.getAccess_token(), appList.getOpenid());
		getUserInfo(str);
	}

	// 解析用户信息
	private void parseJSONUser(String jsonData) {
		// 使用轻量级的Gson解析得到的json
		Gson gson = new Gson();
		WeixinBean appList = gson.fromJson(jsonData,
				new TypeToken() {
				}.getType());
		// 控制台输出结果,便于查看
		Intent intent=new Intent(WXEntryActivity.this,MainActivity.class);
		String str=appList.getSex()==1?"   性别:男" : "   性别:女";
		
		intent.putExtra("username", "微信昵称:"+appList.getNickname());
		intent.putExtra("sex", str);
		startActivity(intent);
	}
}

MainActivity

package com.example.weixindemo;

import com.example.weixindemo.wxapi.WXEntryActivity;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

	private Button btnlogin;
	private TextView txt;
	// 微信api
	private IWXAPI api;

	// 官方网站申请的appid
//	private static final String APP_ID = "wx712ebdaa2ff851b6";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 启动activity时不自动弹出软键盘
        getWindow().setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		btnlogin = (Button) findViewById(R.id.btnlogin);
		txt= (TextView) findViewById(R.id.txt);
		btnlogin.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				wxLogin();
			}
		});
	}

	// 调用微信登录
	public void wxLogin() {
		// 通过WXAPIFactory工厂获取IWXApI的示例
		api = WXAPIFactory.createWXAPI(this, WXEntryActivity.WX_APP_ID, true);
		// 将应用的appid注册到微信
		api.registerApp(WXEntryActivity.WX_APP_ID);
		
		
		 if (api != null && api.isWXAppInstalled()) {
			 SendAuth.Req req = new SendAuth.Req();
				req.scope = "snsapi_userinfo";
				req.state = "wechat_sdk_demo";
				api.sendReq(req);
	        } else{
	        	Toast.makeText(this, "用户未安装微信", Toast.LENGTH_SHORT).show();
	        }
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		App.username=getIntent().getStringExtra("username");
		App.sex=getIntent().getStringExtra("sex");
		if(!"".equals(App.username) && App.username!=null){
			txt.setText(App.username+App.sex);
		}
		
	}
	
}

NetUtils(okhttp网络访问工具类)

package com.example.weixindemo;
import java.io.IOException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

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


public class NetUtils {
    private static final byte[] LOCKER = new byte[0];
    private static NetUtils mInstance;
    private OkHttpClient mOkHttpClient;

    private NetUtils() {
        okhttp3.OkHttpClient.Builder ClientBuilder=new okhttp3.OkHttpClient.Builder();
        ClientBuilder.readTimeout(20, TimeUnit.SECONDS);//读取超时
        ClientBuilder.connectTimeout(6, TimeUnit.SECONDS);//连接超时
        ClientBuilder.writeTimeout(60, TimeUnit.SECONDS);//写入超时
        //支持HTTPS请求,跳过证书验证
        ClientBuilder.sslSocketFactory(createSSLSocketFactory());
        ClientBuilder.hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });
        mOkHttpClient=ClientBuilder.build();
    }

    /**
     * 单例模式获取NetUtils
     * @return
     */
    public static NetUtils getInstance() {
        if (mInstance == null) {
            synchronized (LOCKER) {
                if (mInstance == null) {
                    mInstance = new NetUtils();
                }
            }
        }
        return mInstance;
    }

    /**
     * get请求,同步方式,获取网络数据,是在主线程中执行的,需要新起线程,将其放到子线程中执行
     * @param url
     * @return
     */
    public  Response getDataSynFromNet(String url) {
        //1 构造Request
        Request.Builder builder = new Request.Builder();
        Request request=builder.get().url(url).build();
        //2 将Request封装为Call
        Call call = mOkHttpClient.newCall(request);
        //3 执行Call,得到response
        Response response = null;
        try {
            response = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }
    /**
     * post请求,同步方式,提交数据,是在主线程中执行的,需要新起线程,将其放到子线程中执行
     * @param url
     * @param bodyParams
     * @return
     */
    public  Response postDataSynToNet(String url,Map bodyParams) {
        //1构造RequestBody
        RequestBody body=setRequestBody(bodyParams);
        //2 构造Request
        Request.Builder requestBuilder = new Request.Builder();
        Request request = requestBuilder.post(body).url(url).build();
        //3 将Request封装为Call
        Call call = mOkHttpClient.newCall(request);
        //4 执行Call,得到response
        Response response = null;
        try {
            response = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }
    /**
     * 自定义网络回调接口
     */
    public interface MyNetCall{
        void success(Call call, Response response) throws IOException;
        void failed(Call call, IOException e);
    }

    /**
     * get请求,异步方式,获取网络数据,是在子线程中执行的,需要切换到主线程才能更新UI
     * @param url
     * @param myNetCall
     * @return
     */
    public  void getDataAsynFromNet(String url, final MyNetCall myNetCall) {
        //1 构造Request
        Request.Builder builder = new Request.Builder();
        Request request=builder.get().url(url).build();
        //2 将Request封装为Call
        Call call = mOkHttpClient.newCall(request);
        //3 执行Call
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                myNetCall.failed(call,e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                myNetCall.success(call,response);

            }
        });
    }

    /**
     * post请求,异步方式,提交数据,是在子线程中执行的,需要切换到主线程才能更新UI
     * @param url
     * @param bodyParams
     * @param myNetCall
     */
    public  void postDataAsynToNet(String url, Map bodyParams, final MyNetCall myNetCall) {
        //1构造RequestBody
        RequestBody body=setRequestBody(bodyParams);
        //2 构造Request
        Request.Builder requestBuilder = new Request.Builder();
        Request request = requestBuilder.post(body).url(url).build();
        //3 将Request封装为Call
        Call call = mOkHttpClient.newCall(request);
        //4 执行Call
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                myNetCall.failed(call,e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                myNetCall.success(call,response);

            }
        });
    }
    /**
     * post的请求参数,构造RequestBody
     * @param BodyParams
     * @return
     */
    private RequestBody setRequestBody(Map BodyParams){
        RequestBody body=null;
        okhttp3.FormBody.Builder formEncodingBuilder=new okhttp3.FormBody.Builder();
        if(BodyParams != null){
            Iterator iterator = BodyParams.keySet().iterator();
            String key = "";
            while (iterator.hasNext()) {
                key = iterator.next().toString();
                formEncodingBuilder.add(key, BodyParams.get(key));
            }
        }
        body=formEncodingBuilder.build();
        return body;

    }


    /**
     * 生成安全套接字工厂,用于https请求的证书跳过
     * @return
     */
    public SSLSocketFactory createSSLSocketFactory() {
        SSLSocketFactory ssfFactory = null;
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());
            ssfFactory = sc.getSocketFactory();
        } catch (Exception e) {
        }
        return ssfFactory;
    }
    /**
     * 用于信任所有证书
     */
    class TrustAllCerts implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
        }
        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

        }
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }
}

最后我把清单文件也贴一下




    

    
    
    
    
    

    
        
            
                

                
            
        
        
          
     
    

到此今天的文章就结束啦,感谢大家支持。

我的博客主页

附demo下载地址

你可能感兴趣的:(移动开发)