转载注明:http://blog.csdn.net/ning_gg/article/details/52367130
去年做过微信支付,当时用的登陆是第三方的shareSDK。记得当初做微信支付的时候发现很坑,但是距今时隔久远记不清坑在哪里了。当shareSDK的密码忘了又只需要微信一个登陆接口的话,所以就想自己来实现微信登陆了。发现又重蹈覆辙,又入坑了,当入坑了才想起MD以前也入了这坑。所以这次记录下来,防止下回又坑。
这坑是微信会缓存我的登陆信息,所以第一次没有调成功的话需要清除微信缓存,不是聊天缓存而是数据库缓存。从手机设置的应用管理里面去清除应用数据。(当然这会清除所有的聊天记录,所以建议用模拟器来调试程序)。
附上微信登陆的代码,以后要用的话直接拷贝即可使用
在包名下面新建一个wxapi的包
然后事先准备的appket 与app_secret就不说了
app的签名签名是MD5不是SHA码(切记切记)
WXEntryActivity.class
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.imapedia.MainActivity;
import com.imapedia.R;
import com.tencent.mm.sdk.modelbase.BaseReq;
import com.tencent.mm.sdk.modelbase.BaseResp;
import com.tencent.mm.sdk.modelmsg.SendAuth;
import com.tencent.mm.sdk.modelmsg.SendAuth.Resp;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import org.apache.http.client.ClientProtocolException;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
/**
* Created by pailiao on 2016/8/29.
*/
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
private String TAG=WXEntryActivity.class.getSimpleName();
protected static final int RETURN_OPENID_ACCESSTOKEN = 0;// 返回openid,accessToken消息码
protected static final int RETURN_NICKNAME_UID = 1; // 返回昵称,uid消息码
public static final String APP_ID = "lalalalalalal";// 微信开放平台申请到的app_id
public static final String APP_SECRET = "lalalalalalalla";// 微信开放平台申请到的app_id对应的app_secret
private static final String WEIXIN_SCOPE = "snsapi_userinfo";// 用于请求用户信息的作用域
private static final String WEIXIN_STATE = "login_state"; // 自定义
private IWXAPI api;
private SendAuth.Req req;
private Button login;
private Handler handler =new Handler( new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case RETURN_OPENID_ACCESSTOKEN:
Bundle bundle1 = (Bundle) msg.obj;
String accessToken = bundle1.getString("access_token");
String openId = bundle1.getString("open_id");
getUID(openId, accessToken);
break;
case RETURN_NICKNAME_UID:
Bundle bundle2 = (Bundle) msg.obj;
String nickname = bundle2.getString("nickname");
String uid = bundle2.getString("unionid");
Log.e( TAG,"昵称=="+nickname+",uid=="+uid );
Toast.makeText( WXEntryActivity.this,"欢迎进来=="+nickname,Toast.LENGTH_SHORT ).show();
startActivity( new Intent( WXEntryActivity.this, MainActivity.class ) );
finish();
break;
default:
break;
}
return false;
}
} );
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_wxentry);
api = WXAPIFactory.createWXAPI(this, APP_ID, false);
api.registerApp(APP_ID);//
api.handleIntent(getIntent(), this);
login=(Button) findViewById( R.id.login );
login.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
req = new SendAuth.Req();
req.scope = WEIXIN_SCOPE;
req.state = WEIXIN_STATE;
api.sendReq(req);
finish();
}
} );
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent( intent );
Log.e( TAG,"onNewIntent" );
setIntent( intent );
api.handleIntent(intent, this);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult( requestCode, resultCode, data );
Log.e( TAG,"在这里回调的" );
}
@Override
public void onReq(BaseReq baseReq) {
}
/**
* Title: onResp
*
* API:https://open.weixin.qq.com/ cgi- bin/showdocument ?action=dir_list&t=resource/res_list&verify=1&id=open1419317853 &lang=zh_CN
* Description:在此处得到Code之后调用https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
* 获取到token和openID。之后再调用https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID 获取用户个人信息
*
* @param arg0
* @see com.tencent.mm.sdk.openapi.IWXAPIEventHandler#onResp(com.tencent.mm.sdk.openapi.BaseResp)
*/
@Override
public void onResp(BaseResp baseResp) {
int result = 0;
SendAuth.Resp sendAuthResp = (Resp) baseResp;// 用于分享时不要有这个,不能强转
String code = sendAuthResp.code;
switch (baseResp.errCode) {
case BaseResp.ErrCode.ERR_OK:
result = R.string.errcode_success;
getResult(code);
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
result = R.string.errcode_cancel;
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
result = R.string.errcode_deny;
break;
default:
result = R.string.errcode_unknown;
break;
}
Toast.makeText(this, result, Toast.LENGTH_LONG).show();
}
/**
* 获取openid accessToken值用于后期操作
* @param code 请求码
*/
private void getResult(final String code) {
new Thread() {// 开启工作线程进行网络请求
public void run() {
String path = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
+ APP_ID
+ "&secret="
+ APP_SECRET
+ "&code="
+ code
+ "&grant_type=authorization_code";
try {
JSONObject jsonObject = JsonUtils
.initSSLWithHttpClinet(path);// 请求https连接并得到json结果
if (null != jsonObject) {
String openid = jsonObject.getString("openid")
.toString().trim();
String access_token = jsonObject
.getString("access_token").toString().trim();
Log.i(TAG, "openid = " + openid);
Log.i(TAG, "access_token = " + access_token);
Message msg = handler.obtainMessage();
msg.what = RETURN_OPENID_ACCESSTOKEN;
Bundle bundle = new Bundle();
bundle.putString("openid", openid);
bundle.putString("access_token", access_token);
msg.obj = bundle;
handler.sendMessage(msg);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return;
};
}.start();
}
/**
* 获取用户唯一标识
* @param openId
* @param accessToken
*/
private void getUID(final String openId, final String accessToken) {
new Thread() {
@Override
public void run() {
String path = "https://api.weixin.qq.com/sns/userinfo?access_token="
+ accessToken + "&openid=" + openId;
JSONObject jsonObject = null;
try {
jsonObject = JsonUtils.initSSLWithHttpClinet(path);
String nickname = jsonObject.getString("nickname");
String unionid = jsonObject.getString("unionid");
Log.i(TAG, "nickname = " + nickname);
Log.i(TAG, "unionid = " + unionid);
Message msg = handler.obtainMessage();
msg.what = RETURN_NICKNAME_UID;
Bundle bundle = new Bundle();
bundle.putString("nickname", nickname);
bundle.putString("unionid", unionid);
msg.obj = bundle;
handler.sendMessage(msg);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
};
}.start();
}
}
HTTPSTrustManager.class
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
/**
* @description 有一个信任管理器类负责决定是否信任远端的证书 X509TrustManager
* @charset UTF-8
* Created by pailiao on 2016/8/29.
* @version
*/
public class HTTPSTrustManager implements X509TrustManager {
private static TrustManager[] trustManagers;
private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[] {};
/**
* 该方法检查客户端的证书,若不信任该证书则抛出异常。由于我们不需要对客户端进行认证,
* 因此我们只需要执行默认的信任管理器的这个方法。JSSE中,默认的信任管理器类为TrustManager。
*/
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {
// To change body of implemented methods use File | Settings | File
// Templates.
}
/**
* 该方法检查服务器的证书,若不信任该证书同样抛出异常。通过自己实现该方法,可以使之信任我们指定的任何证书。在实现该方法时,
* 也可以简单的不做任何处理,即一个空的函数体,由于不会抛出异常,它就会信任任何证书。
*/
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {
// To change body of implemented methods use File | Settings | File
// Templates.
}
public boolean isClientTrusted(X509Certificate[] chain) {
return true;
}
public boolean isServerTrusted(X509Certificate[] chain) {
return true;
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return _AcceptedIssuers;
}
public static void allowAllSSL() {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
SSLContext context = null;
if (trustManagers == null) {
trustManagers = new TrustManager[] { new HTTPSTrustManager() };
}
try {
context = SSLContext.getInstance("TLS");
context.init(null, trustManagers, new SecureRandom());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
HttpsURLConnection.setDefaultSSLSocketFactory(context
.getSocketFactory());
}
}
JsonUtils.class
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
/**
* @description jison工具类
* @charset UTF-8
*Created by pailiao on 2016/8/29.
* @version
*/
public class JsonUtils {
public static JSONObject initSSLWithHttpClinet(String path)
throws ClientProtocolException, IOException {
HTTPSTrustManager.allowAllSSL();
JSONObject jsonObject = null;
int timeOut = 30 * 1000;
HttpParams param = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(param, timeOut);
HttpConnectionParams.setSoTimeout(param, timeOut);
HttpConnectionParams.setTcpNoDelay(param, true);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory .getSocketFactory(), 80));
registry.register(new Scheme("https", TrustAllSSLSocketFactory .getDefault(), 443));
ClientConnectionManager manager = new ThreadSafeClientConnManager( param, registry);
DefaultHttpClient client = new DefaultHttpClient(manager, param);
HttpGet request = new HttpGet(path);
// HttpGet request = new HttpGet("https://www.alipay.com/");
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
BufferedReader reader = new BufferedReader(new InputStreamReader( entity.getContent()));
StringBuilder result = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
result.append(line);
try {
jsonObject = new JSONObject(line);
} catch (JSONException e) {
e.printStackTrace();
}
}
Log.e("HTTPS TEST", result.toString());
return jsonObject;
}
}
TrustAllSSLSocketFactory.class
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.conn.scheme.SocketFactory;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import android.os.Build;
/**
*
* @description ssl安全链接工厂
* @charset UTF-8
* Created by pailiao on 2016/8/29.
* @version
*/
public class TrustAllSSLSocketFactory extends SSLSocketFactory {
private javax.net.ssl.SSLSocketFactory factory;
private static TrustAllSSLSocketFactory instance;
private TrustAllSSLSocketFactory() throws KeyManagementException, UnrecoverableKeyException,
NoSuchAlgorithmException, KeyStoreException {
super(null);
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[] { new TrustAllManager() }, null);
factory = context.getSocketFactory();
setHostnameVerifier(new X509HostnameVerifier() {
@Override
public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
}
@Override
public void verify(String host, X509Certificate cert) throws SSLException {
}
@Override
public void verify(String host, SSLSocket ssl) throws IOException {
}
@Override
public boolean verify(String host, SSLSession session) {
return true;
}
});
}
public static SocketFactory getDefault() {
if (instance == null) {
try {
instance = new TrustAllSSLSocketFactory();
} catch (Exception e) {
e.printStackTrace();
}
}
return instance;
}
@Override
public Socket createSocket() throws IOException {
return factory.createSocket();
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
throws IOException, UnknownHostException {
if (Build.VERSION.SDK_INT < 11) { // 3.0
injectHostname(socket, host);
}
return factory.createSocket(socket, host, port, autoClose);
}
private void injectHostname(Socket socket, String host) {
try {
Field field = InetAddress.class.getDeclaredField("hostName");
field.setAccessible(true);
field.set(socket.getInetAddress(), host);
} catch (Exception ignored) {
}
}
public class TrustAllManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
}
代码就这些了,最后带上manifast文件中WXEntryActivity的声明
<activity android:name=".wxapi.WXEntryActivity"
android:exported="true"
android:launchMode="singleTop"
android:label="@string/app_name"
/>
add:
private IWXAPI api;
api = WXAPIFactory.createWXAPI(this, APP_ID, false);
//可以判断用户是否已经安装微信
api.isWXAppInstalled()
除了每次调试要清除微信应用缓存其实没什么难的。
转载注明:http://blog.csdn.net/ning_gg/article/details/52367130