在公司实习做网页,需要做app的微信授权登陆,由于没有人做过android,有过有一点经验的我就瞬间转战android了,废话不多说,直接上干货。    看微信开放平台的微信授权接入指南其实一切都已经足够了,个人觉得微信的文档写得实在有点蛋疼,对于一个初做者的话,感觉有点迷茫,下面我就仔细分析一下过程吧。1.在微信开放平台上申请appid。到管理中心->创建移动应用,微信上说一个周申请成功,一般只要一天就可以通过了。申请的时候,有两个东西可能会不好理解,一个是应用包名,如下图:或者也可以到AndroidManifest.xml文件中查看,具体位置如代码:
<?xml version="1.0" encoding="utf-8"?>
另外一个需要填写的是应用签名,这个官网上说了,有专门的签名生成工具,你可以先把自己的app安装到自己的手机,然后下载安装签名生成工具,即可根据包名生成相应的签名。填写好这些信息之后等待审核即可。
2.下载微信终端开发工具包,开发包中主要含有3部分,然后只有 libammsdk.jar是必须的,下载好了之后把这个文件复制到自己工程的libs目录下面,如果没有这个目录,则自己新建一个,然后配置文件路径,右键点击工程,选择Build Path中的Configure Build Path...,选中Libraries这个tab,并通过Add Jars...导入工程libs目录下的libammsdk.jar文件。这个jar包里面包含了将要使用到的微信终端api。然后对AndroidManifest.xml 进行设置,代码如下:
  
 
到这里,相关配置就基本上完成了,接下来就可以相关代码的处理了。
3.微信授权处理一般单独进行封装,在你的工程/src/ 目录下新建一个包名,一般以自己的“应用包名+.wxapi" 作为包名,当然也不一定非得这样,自己定义也是可以的。在新建的包下面新建一个类 WXEntryActivity 作为微信授权处理的类,继承于Activity和IWXAPIEventHandler,代码如下(解释详见注释):  
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对象,获取IWXAPI 实例               api = WXAPIFactory.createWXAPI(this, Constants.APP_ID, false);               }                                         // 根据在微信开放;平台注册的appid注册app    api.registerApp(Constants.APP_ID); 
                             //我在做微信授权功能的时候就是因为下面这句话的位置没有放对,然后一直导致的结果是能够拉起微信授权的页面,但是一旦点击确定授权之后就什么都没////有了,后来通过各种调试,才发现在 发送请求到微信之前就必须调用这个函数,目的是将将接收到的intent及实现了IWXAPIEventHandler接口的对象传递给IWX//API接口,所以必须在接下来的发送页面请求之前调用,切记。。。    api.handleIntent(getIntent(),this); if (!api.isWXAppInstalled()){  //判断用户是否安装了微信客户端        Toast.makeText(WXEntryActivity.this,"你还没有安装微信,请安装合适版本的微信",Toast.LENGTH_LONG).show();          return;        } //发送启动页面请求,我在实际做的时候又遇到了问题,我做了两个app,但是在使用
//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);   
//到此,微信授权页面就可以拉起了}@Overrideprotected void onNewIntent(Intent intent) {      super.onNewIntent(intent);      setIntent(intent);        api.handleIntent(intent, this);}//下面的函数是微信授权的时候等待用户确认调用的,微信会自动调用,因此不需要自己显示调用@Overridepublic 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;}}//以下函数微信在授权成功后会自动调用,我们如果需要拉去微信信息的话,就可以在case BaseResp.ErrCode.ERR_OK:后面添加代码@Overridepublic 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,好吧,不过,虽然长相不一一样,但是//功能却是相同的
//不要以为现在你就已经大工告成了,下面的这个问题一定会让你欲哭无泪的,那就是android访问网路一定要新开线程,也就是说不能在主线程中进行访问网络或者画图等比////较耗时的操作,一定要注意这个啊,我因为这个研究了一整天        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 blocke1.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





更多相关文章

  1. 如何在代码中为组件设置dip,sp值
  2. 史上最全Android开发资料:资源、UI、函数库、测试、构建全套教程
  3. Android实战技巧之四十五:复用原有C代码的方案
  4. 这本《第三行代码》,让大家久等了!
  5. 《第一行代码Android》读书笔记
  6. Android NDK开发篇(六):Java与原生代码通信(异常处理)
  7. android代码混淆个人总结及踩坑
  8. 代码中进行RelativeLayout布局的修改添加
  9. 让你的代码量减少3倍!使用kotlin开发Android(一)

随机推荐

  1. Android应用程序四大组件
  2. Android(安卓)SQLite详解
  3. Android(安卓)Graphics专题(1)--- Canvas基
  4. ActivityThread
  5. Android:开发自己的Launcher简单demo
  6. Google Android开发精华教程
  7. android是什么?
  8. Android(安卓)数据库SQLite的使用简单Dem
  9. android中Webview与javascript的交互(互相
  10. android 的handler 机制