Android 微信授权登陆

</pre>在公司实习做网页,需要做app的微信授权登陆,由于没有人做过android,有过有一点经验的我就瞬间转战android了,废话不多说,直接上干货。</h2><div><span style="white-space:pre">	</span>    看微信开放平台的微信授权接入指南其实一切都已经足够了,个人觉得微信的文档写得实在有点蛋疼,对于一个初做者的话,感觉有点迷茫,下面我就仔细分析一下过程吧。</div><div></div><div>1.在微信开放平台上申请appid。到管理中心->创建移动应用,微信上说一个周申请成功,一般只要一天就可以通过了。申请的时候,有两个东西可能会不好理解,一个是应用包名,如下图:</div><div><img src="https://img-blog.csdn.net/20150811164119404?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="600" height="200" alt="" /></div><div></div><div>或者也可以到AndroidManifest.xml文件中查看,具体位置如代码:</div><div></div><div><pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cm.senguo"
    android:versionCode="1"
    android:versionName="1.0" >
另外一个需要填写的是应用签名,这个官网上说了,有专门的签名生成工具,你可以先把自己的app安装到自己的手机,然后下载安装签名生成工具,即可根据包名生成相应的签名。填写好这些信息之后等待审核即可。

2.下载微信终端开发工具包,开发包中主要含有3部分,然后只有 libammsdk.jar是必须的,下载好了之后把这个文件复制到自己工程的libs目录下面,如果没有这个目录,则自己新建一个,然后配置文件路径,右键点击工程,选择Build Path中的Configure Build Path...,选中Libraries这个tab,并通过Add Jars...导入工程libs目录下的libammsdk.jar文件。这个jar包里面包含了将要使用到的微信终端api。然后对AndroidManifest.xml 进行设置,代码如下:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> 
<uses-permission android:name="android.permission.READ_PHONE_STATE"/> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
到这里,相关配置就基本上完成了,接下来就可以相关代码的处理了。

3.微信授权处理一般单独进行封装,在你的工程/src/ 目录下新建一个包名,一般以自己的“应用包名+.wxapi" 作为包名,当然也不一定非得这样,自己定义也是可以的。在新建的包下面新建一个类 WXEntryActivity 作为微信授权处理的类,继承于Activity和IWXAPIEventHandler,代码如下(解释详见注释):
 
</pre><pre name="code" class="java">public class WXEntryActivity extends Activity implements IWXAPIEventHandler{
   // IWXAPI 是第三方app和微信进行通信的openapi接口
    public static  IWXAPI api;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
               if(api==null){         /  / 创建微信api对象,获取<span style="font-family: Arial, Helvetica, sans-serif;">IWXAPI 实例</span>
            	   api = WXAPIFactory.createWXAPI(this, Constants.APP_ID, false);
               }
    	        
                             // 根据在微信开放;平台注册的appid注册app
			    api.registerApp(Constants.APP_ID); 
<strong>                          <span style="background-color: rgb(255, 255, 51);">   //我在做微信授权功能的时候就是因为下面这句话的位置没有放对,然后一直导致的结果是能够拉起微信授权的页面,但是一旦点击确定授权之后就什么都没有了,后来通过各种调试,才发现在 发送请求到微信之前就必须调用这个函数,目的是将<span style="color: rgb(34, 34, 34); font-family: 'Hiragino Sans GB', 'Microsoft YaHei', 黑体, Helvetica, Arial, Tahoma, sans-serif; font-size: 14px; line-height: 22.3999996185303px;">将接收到的intent及实现了IWXAPIEventHandler接口的对象传递给IWX//API接口,所以必须在接下来的发送页面请求之前调用,切记。。。</span></span></strong>
			    api.handleIntent(getIntent(),this);
				 if (!api.isWXAppInstalled()){  //判断用户是否安装了微信客户端
			        	Toast.makeText(WXEntryActivity.this,"你还没有安装微信,请安装合适版本的微信",Toast.LENGTH_LONG).show();
			          return;
			        }
				 
//发送启动页面请求,我在实际做的时候又遇到了问题,我做了两个app,但是在使用<pre name="code" class="java">//req.openId=Constants.APP_ID;
//这句代码的时候发现了一个奇怪的现象,我这句话不能调用,找了半天发现问题在于我自动导入包的时候两个app导入的包不一样:
 
  
//其中一个是:
//import com.tencent.mm.sdk.constants.ConstantsAPI;
//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.cm.senguoadmin.Constants;
//import com.tencent.mm.sdk.openapi.BaseReq;
//import com.tencent.mm.sdk.openapi.BaseResp;
//import com.tencent.mm.sdk.openapi.ConstantsAPI;
//import com.tencent.mm.sdk.openapi.IWXAPI;

//你发现区别了吗?后来我在网上查到了有人也遇到过这种问题,因为最新的包并不需要这个openid,好吧,自己注意吧~
		        final SendAuth.Req req=new SendAuth.Req();
		        req.openId=Constants.APP_ID;
		        req.scope="snsapi_userinfo";
		        req.state="carjob_wx_login";
		        api.sendReq(req);   
//到此,微信授权页面就可以拉起了
			}
	@Override
	protected void onNewIntent(Intent intent) {
		      super.onNewIntent(intent);
		      setIntent(intent);
        api.handleIntent(intent, this);
	}

	//下面的函数是微信授权的时候等待用户确认调用的,微信会自动调用,因此不需要自己显示调用
	@Override
	public void onReq(BaseReq req) {
		switch (req.getType()) {
		case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX:
			break;
		case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX:
			break;
//			授权
		case ConstantsAPI.COMMAND_SENDAUTH:
			break;
		default:
			break;
		}
	}
//以下函数微信在授权成功后会自动调用,我们如果需要拉去微信信息的话,就可以在<span style="font-family: Arial, Helvetica, sans-serif;">case BaseResp.ErrCode.ERR_OK:后面添加代码</span>

	@Override
	public void onResp(BaseResp resp) {
		int result = 0;
		 Bundle bundle=new Bundle();
		switch (resp.errCode) {
		case BaseResp.ErrCode.ERR_OK:
			result = R.string.errcode_success;
			resp.toBundle(bundle);
	        Resp sp=new Resp(bundle);
	        final  String code=sp.code;   //针对具体导入的包不同,这里会有所不同,我做的时候一个需要sp.code,但是一个却是sp.token,好吧,不过,虽然长相不一一样,但是//功能却是相同的
<strong style="background-color: rgb(255, 255, 51);">//不要以为现在你就已经大工告成了,下面的这个问题一定会让你欲哭无泪的,那就是android访问网路一定要新开线程,也就是说不能在主线程中进行访问网络或者画图等比较耗时的操作,一定要注意这个啊,我因为这个研究了一整天</strong>
	        new Thread(){
	        	@Override
	        	public void run(){
//这个函数是我封装的获取微信信息的函数,见后面的代码
	        	goToGetMsg(code);
	        		
	        	}
	        }.start();
	        this.finish();
	        break;
		case BaseResp.ErrCode.ERR_USER_CANCEL:
			break;
		case BaseResp.ErrCode.ERR_AUTH_DENIED:
			break;
		case ConstantsAPI.COMMAND_SENDAUTH:
            break;
		default:
			result = R.string.errcode_unknown;
			break;
		}
	}
对于goToGetMsg(code)函数,主要就是根据code获取微信个人信息,具体分为两步:
通过code获取access_token

获取第一步的code后,请求以下链接获取access_token:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

APPID和SECRET都是注册app的时候获得的,此处不多说。
通过access_token调用接口
获取access_token后,进行接口调用,

httpUrl="https://api.weixin.qq.com/sns/userinfo?access_token="+ACCESS_TOKEN+"&openid="+OPENID;

到此,微信信息就可以获取了,然后可以对得到的返回数据进行处理,返回数据识json格式,具体处理过程此处步详细叙述了。最后,附上代码片段:

private void goToGetMsg(String code) {
		String result = null;
		 // http地址
        URL url = null;
        HttpURLConnection connection = null;
        InputStreamReader in = null;
        try {
            url = new URL("https://api.weixin.qq.com/sns/oauth2/access_token?appid="+Constants.APP_ID+"&secret="+Constants.APP_SECRET+"&code="+code+"&grant_type=authorization_code");
            connection = (HttpURLConnection) url.openConnection();
            in = new InputStreamReader(connection.getInputStream());
            BufferedReader bufferedReader = new BufferedReader(in);
            StringBuffer strBuffer = new StringBuffer();
            String line = null;
            while ((line = bufferedReader.readLine()) != null) {
                strBuffer.append(line);
            }
            result = strBuffer.toString();
            Log.v("str",result);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
 
        }
        String ACCESS_TOKEN=null;
        String OPENID=null;
           try {
			JSONObject datajson=new JSONObject(result);
			ACCESS_TOKEN=datajson.getString("access_token");
		 OPENID=datajson.getString("unionid");
		} catch (JSONException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
          
		         String httpUrl="https://api.weixin.qq.com/sns/userinfo?access_token="+ACCESS_TOKEN+"&openid="+OPENID;
//      		  String httpUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+Constants.APP_ID+"&secret="+Constants.APP_SECRET+"&code="+code+"&grant_type=authorization_code";
      		  // HttpGet连接对象
      		  HttpGet httpRequest = new HttpGet(httpUrl);
      		  try 
      		  {
      		   // 取得HttpClient对象
      		   HttpClient httpclient = new DefaultHttpClient();
      		   // 请求HttpClient,取得HttpResponse
      		   HttpResponse httpResponse = httpclient.execute(httpRequest);
      		   // 请求成功
      		   if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) 
      		   {
      		     // 取得返回的字符串
      		     String strResult = EntityUtils.toString(httpResponse.getEntity());
      		   JSONObject  user;
      			String unionid = null;
      			String openid = null;
      			String country=null;
      			String province=null;
      			String city=null;
      			String headimgurl=null;
      			String nickname=null;
      			int sex=0;
      		   try {
      			   user=new JSONObject(strResult);
      			   unionid=user.getString("unionid");
      		      openid=user.getString("openid");
      				country=user.getString("country");
      				province=user.getString("province");
      				 city=user.getString("city");
      				 headimgurl=user.getString("headimgurl");
      				 nickname=user.getString("nickname");
      			    sex=user.getInt("sex");
      			} catch (JSONException e) {
      				// TODO Auto-generated catch block
      				e.printStackTrace();
      			}
      		   String info="http://test123.senguo.cc/customer/weixinphoneadmin?openid="+openid+"&unionid="+unionid+"&country="+country+"&province="+
   				province+"&city="+city+"&headimgurl="+headimgurl+"&nickname="+nickname+"&sex="+sex;
      		    finish();
      		   Intent intent=new Intent(WXEntryActivity.this,Senguo_admin.class);
            	Bundle bundle=new Bundle();
            	bundle.putCharSequence("URL", info);
            	intent.putExtras(bundle);
            	startActivity(intent);
      		   } 
      		  else 
      		   {
      		     Log.e("error","请求错误!");
      		   }
      		  } 
      		catch (ClientProtocolException e) 
      		  {
      		   Log.e("duizhan",e.getMessage().toString());
      		  } 
      		catch (IOException e) 
      		  {
      			Log.e("duizhan",e.getMessage().toString());
      		  } 
      		catch (Exception e) 
      		  {
      			Log.e("duizhan",e.getMessage().toString());
      		  }
	}

总结:具体需要注意的东西在过程中都一一记录了,以前做android都没有涉及到种调用第三方api的内容,经过这次实践,最深的体会就是要仔细看相关api的文档。说点别的吧,这是我的第一篇博客,写得有点粗糙,以后慢慢改进吧,不过技术这种东西,干活为主吧。希望自己以后越走越好~~good luck





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值