微信开发者手册 调用第三方地图

2017-08-08 15:06:06 kamiyuntech 阅读数 36174

首先你得是服务号,并且是经过认证的.这样微信会给你很多第三方接口的权限,如果是订阅号或者没有认证的服务号那就不用想了!

  

一、开启开发者模式

开始你需要进入微信公众平台开启开发模式,并且填写oauth2的回调地址,地址填写你项目的域名就可以了.比如:www.baidu.com或zhidao.baidu.com.如果你的项目在二级域名就写二级域名,前端url授权地址,在url中填写appid与你项目中方法中的oauth的地址,具体在下面的代码中可以看到.

<a href="https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=http://www.xxxxxx.com/action/function/oauth2&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect">授权</a>


再说后台逻辑,首先调用微信接口的SDK.(后面会有)

include('class_weixin_adv.php');

之后填入微信官方给的的appid与secret

$weixin=new class_weixin_adv("appid", "secret");

初始化SDK的类,取到code,利用获取到的code在获取出openid 看下面代码注释!

$url="https://api.weixin.qq.com/sns/oauth2/access_token?appid=appid&secret=secret&code=".$_GET['code']."&grant_type=authorization_code";
$res = $weixin->https_request($url);//调用SDK方法获取到res 从中可以得到openid
$res=(json_decode($res, true));//转换成array 方便调用openid

继续调用SDK方法,获取到用户信息.此时$row已经获得用户信息了 可以var_dump下看看键值方便存入数据库

$row=$weixin->get_user_info($res['openid']);

获取用户信息就大功告成了,但这还不够.我们需要的是无需注册!所以需要利用openid,openid属于唯一凭证,每个用户对不同的公众号都有不同的openid.可以理解成用户账号的感觉.我这里用的是把openid存入cookie的解决方案,类似用户登陆的感觉,一些关键数据验证只需要与数据库中的openid进行对比.其他的一些利用方法可以发挥大家的想象!可以跟我留言交流!

关于之前的a链接的授权,大家也可以判断cookie是否存在openid,从而让未授权用户直接跳转到该地址,省却了用户的一步操作.

下面是完整逻辑代码,大家可以参考下!

public function oauth2(){
           include('class_weixin_adv.php');
            $weixin=new class_weixin_adv("appid", "secret");
            if (isset($_GET['code'])){
                $url="https://api.weixin.qq.com/sns/oauth2/access_token?appid=appid&secret=secret&code=".$_GET['code']."&grant_type=authorization_code";
                $res = $weixin->https_request($url);
                $res=(json_decode($res, true));
                $row=$weixin->get_user_info($res['openid']);
                
                if ($row['openid']) {
                   //这里写上逻辑,存入cookie,数据库等操作
                    cookie('weixin',$row['openid'],25920000);
                   
                }else{
                    $this->error('授权出错,请重新授权!');
                }
            }else{
                echo "NO CODE";
            }
            $this->display();
        }

SDK代码:微信官方有手册,我就不多讲了,自己研究,很简单的!.

<?php
/**
 * 微信SDK 
 */
class class_weixin_adv
{
    var $appid = "";
    var $appsecret = "";

    //构造函数,获取Access Token
    public function __construct($appid = NULL, $appsecret = NULL)
    {
        if($appid){
            $this->appid = $appid;
        }
        if($appsecret){
            $this->appsecret = $appsecret;
        }

        
        $this->lasttime = 1395049256;
        $this->access_token = "nRZvVpDU7LxcSi7GnG2LrUcmKbAECzRf0NyDBwKlng4nMPf88d34pkzdNcvhqm4clidLGAS18cN1RTSK60p49zIZY4aO13sF-eqsCs0xjlbad-lKVskk8T7gALQ5dIrgXbQQ_TAesSasjJ210vIqTQ";

        if (time() > ($this->lasttime + 7200)){
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$this->appid."&secret=".$this->appsecret;
            $res = $this->https_request($url);
            $result = json_decode($res, true);
            
            $this->access_token = $result["access_token"];
            $this->lasttime = time();
        }
    }//获取用户基本信息
    public function get_user_info($openid)
    {
        $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=".$this->access_token."&openid=".$openid."&lang=zh_CN";
        $res = $this->https_request($url);
        return json_decode($res, true);
    }

//https请求
    public function https_request($url, $data = null)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)){
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }
}

2017-02-09 15:14:59 Wshiduo 阅读数 3392

微信第三方登录

步骤:

1.申请你的AppID

请到微信开放平台https://open.weixin.qq.com/注册成为开发者,然后创建应用并提交审核,只有审核通过的应用才能进行开发。

2.下载SDK及API文档

Android Studio环境下:

在build.gradle文件中,添加如下依赖即可:

dependencies {
    compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:1.0.2'
}

dependencies {
    compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:1.0.2'
}

(其中,前者包含统计功能)

3.在代码中使用开发工具包

[1] 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"/>


[2] 注册到微信

要使你的程序启动后微信终端能响应你的程序,必须在代码中向微信终端注册你的id。(如下图所示,可以在程序入口Activity的onCreate回调函数处,或其他合适的地方将你的应用id注册到微信。注册函数示例如下图所示。

[3] 发送请求或响应到微信

现在,你的程序要发送请求或发送响应到微信终端,可以通过IWXAPI的 sendReq 和 sendResp 两个方法来实现。

boolean sendReq(BaseReq req);

sendReq是第三方app主动发送消息给微信,发送完成之后会切回到第三方app界面。

boolean sendResp(BaseResp resp);

sendResp是微信向第三方app请求数据,第三方app回应数据之后会切回到微信界面。

sendReq的实现示例,如下图所示:

需要注意的是,SendMessageToWX.Req的scene成员,如果scene填WXSceneSession,那么消息会发送至微信的会话内。如果scene填WXSceneTimeline(微信4.2以上支持,如果需要检查微信版本支持API的情况, 可调用IWXAPI的getWXAppSupportAPI方法,0x21020001及以上支持发送朋友圈),那么消息会发送至朋友圈。scene默认值为WXSceneSession。

sendResp的实现与SendReq类似,如下图所示:

具体要发送的内容由第三方app开发者定义,这里需要说一下,为了实现第三方登陆,这里请求是这样的:

微信登录的官方文档将微信登录分为3个步骤:

{
    // send oauth request 
     Final SendAuth.Req req = new SendAuth.Req();
     req.scope = "snsapi_userinfo";
     req.state = "wechat_sdk_demo_test";
     api.sendReq(req);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

用这段代码向微信开放平台请求授权码code,可拉起微信并打开授权登录页(前提是你安装了微信应用并已登录,未登录的会引导你先登录),如下图:

1.如果微信授权页不显示,请检查你的APP签名是否和你在腾讯开放平台的APP签名一致,不一致可修改腾讯开放平台中的APP签名,修改后重装微信或清除微信数据后重试。

2.在你的包名相应目录下新建一个wxapi目录,并在该wxapi目录下新增一个WXEntryActivity类,该类继承自Activity(例如应用程序的包名为net.sourceforge,则新的包名为:net.sourceforge.wxapi),此处应注意包名不要弄错,新增类的名字必须为WXEntryActivity,如下图示:

并在manifest文件里面加上exported属性,设置为true,例如:

返回说明 
用户点击授权后,微信客户端会被拉起,跳转至授权界面,用户在该界面点击允许或取消,SDK通过SendAuth的Resp返回数据给调用方。通过IWXAPIEventHandler接口的onReq方法进行回调,类似的,应用请求微信的响应结果将通过onResp回调,如下:

@Override
    public void onResp(BaseResp resp) {
        int errorCode = resp.errCode;
        switch (errorCode) {
        case BaseResp.ErrCode.ERR_OK:
            //用户同意
            String code = ((SendAuth.Resp) resp).code;  //code:授权码
            break;
        case BaseResp.ErrCode.ERR_AUTH_DENIED:
            //用户拒绝
            break;
        case BaseResp.ErrCode.ERR_USER_CANCEL:
            //用户取消
            break;
        default:
            break;
        }
        ToastUtil.showMessageLong(this, resp.errStr);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

客户端收到授权码后,向自己的服务器发起登录请求,并附带收到的授权码code ,可以通过code获取access_token(建议在自己服务器端获取)

获取access_token链接为

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

得到的Json对象解析为:

 		JSONObject object = new JSONObject(sb.toString().trim());
                accessToken = object.getString("access_token");
                openID = object.getString("openid");
                refreshToken = object.getString("refresh_token");
                expires_in = object.getLong("expires_in");

参数说明:

参数        是否必须        说明 
appid       是        应用唯一标识,在微信开放平台提交应用审核通过后获得

secret      是      应用密钥AppSecret,在微信开放平台提交应用审核通过后获得

code        是       填写第一步获取的code参数

grant_type  是      填authorization_code回说明**

正确的返回:

{ 
"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID", 
"scope":"SCOPE",
"unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
    参数                              说明
access_token                    接口调用凭证
expires_in  access_token        接口调用凭证超时时间,单位(秒)
refresh_token                   用户刷新access_token
openid                          授权用户唯一标识
scope                           用户授权的作用域,使用逗号(,)分隔
unionid          只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
错误返回样例:
{"errcode":40029,"errmsg":"invalid code"}
客户端可利用access_token获取微信用户信息,但进行接口调用,有以下前提:
  1. access_token有效且未超时;
  2. 微信用户已授权给第三方应用帐号相应接口作用域(scope)。
授权作用域(scope)             接口                接口说明
snsapi_base       /sns/oauth2/access_token     通过code换取              access_token、refresh_token和已授权scope
                    /sns/oauth2/refresh_token  刷新或续期access_token使用
                    /sns/auth                  检查access_token有效性
snsapi_userinfo    /sns/userinfo               获取用户个人信息

其中snsapi_base属于基础接口,若应用已拥有其它scope权限,则默认拥有snsapi_base的权限。使用snsapi_base可以让移动端网页授权绕过跳转授权登录页请求用户授权的动作,直接跳转第三方网页带上授权临时票据(code),但会使得用户已授权作用域(scope)仅为snsapi_base,从而导致无法获取到需要用户授权才允许获得的数据和基础功能。

以获取用户信息举例:

private void getUserInfo() {
        if (isAccessTokenIsInvalid() && System.currentTimeMillis() < expires_in) {
            String uri = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openID;
            HttpClient client = new DefaultHttpClient();
            HttpGet get = new HttpGet(URI.create(uri));
            try {
                HttpResponse response = client.execute(get);
                if (response.getStatusLine().getStatusCode() == 200) {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
                    StringBuilder builder = new StringBuilder();
                    for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
                        builder.append(temp);
                    }
                    JSONObject object = new JSONObject(builder.toString().trim());
                    String nikeName = object.getString("nickname");
                }
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

重复登录

假设用户已经获得授权,则下次登录时只需要验证access_token是否有效,无效则重新获取授权,有效则无需重新获得授权。

1.用户向自己的服务器请求登录,登录方式为微信登录,附带上次登录返回的的access_token

2.服务器收到用户的登录请求,向微信开放平台发送access_token是否有效的验证请求如下

private boolean isAccessTokenIsInvalid() {
        String url = "https://api.weixin.qq.com/sns/auth?access_token=" + accessToken + "&openid=" + openID;
        URI uri = URI.create(url);
        HttpClient client = new DefaultHttpClient();
        HttpGet get = new HttpGet(uri);
        HttpResponse response;
        try {
            response = client.execute(get);
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();

                BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
                StringBuilder sb = new StringBuilder();

                for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
                    sb.append(temp);
                }
                JSONObject object = new JSONObject(sb.toString().trim());
                int errorCode = object.getInt("errcode");
                if (errorCode == 0) {
                    return true;
                }
            }
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return false;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

返回说明

正确的Json返回结果:
{ 
"errcode":0,"errmsg":"ok"
}
错误的Json返回示例:
{ 
"errcode":40003,"errmsg":"invalid openid"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

如果access_token有效,服务端将信息返回给客户端,客户端成功登录。

如果access_token无效,服务端向微信开放平台发送刷新access_token的请求如下:

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失效的后,需要用户重新授权。

private void refreshAccessToken() {
        String uri = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + ShareUtil.APP_ID + "&grant_type=refresh_token&refresh_token="
                + refreshToken;
        HttpClient client = new DefaultHttpClient();
        HttpGet get = new HttpGet(URI.create(uri));
        try {
            HttpResponse response = client.execute(get);
            if (response.getStatusLine().getStatusCode() == 200) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
                StringBuilder builder = new StringBuilder();
                for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
                    builder.append(temp);
                }
                JSONObject object = new JSONObject(builder.toString().trim());
                accessToken = object.getString("access_token");
                refreshToken = object.getString("refresh_token");
                openID = object.getString("openid");
                expires_in = object.getLong("expires_in");
            }
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

返回说明

正确的返回:
{ 
"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN", 
"openid":"OPENID", 
"scope":"SCOPE" 
}
参数                    说明
access_token       接口调用凭证
expires_in        access_token接口调用凭证超时时间,单位(秒)
refresh_token     用户刷新access_token
openid           授权用户唯一标识
scope          用户授权的作用域,使用逗号(,)分隔

错误返回样例:
{
"errcode":40030,"errmsg":"invalid refresh_token"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

3.服务端获取到新的access_token等信息,并返回给客户端,客户端成功登录或者重新获取授权。

注意事项

[1]如果需要混淆代码,为了保证sdk的正常使用,需要在proguard.cfg加上下面两行配置:


-keep class com.tencent.mm.opensdk.** {

   *;

}

-keep class com.tencent.wxop.** {

   *;

}

-keep class com.tencent.mm.sdk.** {

   *;

}

[2]如果需要运行SDK Sample工程,需要通过指定的debug.keystore来进行签名:

Android Studio环境下:

signingConfigs {
    debug {
        storeFile file("../debug.keystore")
    }
}


Eclipse环境下:

请查阅文档《如何运行SDK Demo工程


至此,你已经能使用微信Android开发工具包的API内容了。如果想更详细了解每个API函数的用法,请查阅 Android 平台参考手册 或自行下载阅读微信SDK Sample Demo源码。

微信SDK Sample Demo源码

参考博文:http://blog.csdn.net/luoyan973387349/article/details/49815225

官网接口地址:开发前需要知道的那些事   、   集成前资源配置    、    授权后接口调用(重)

2018-03-29 16:46:46 xialong_927 阅读数 12345

微信公众号关联网页获取位置信息,可以参照《微信公众平台技术文档-> 微信JS-SDK说明文档,官方链接地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

步骤一:绑定域名

先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。注:该域名不包括端口号,并且必须是备案过的域名。

备注:登录后可在“开发者中心”查看对应的接口权限。

步骤二:引入JS文件

在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js

备注:支持使用 AMD/CMD 标准模块加载方法加载

步骤三:通过config接口注入权限验证配置

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。签名算法见文末的附录1,所有JS接口列表见文末的附录2

[html] view plain copy
  1. wx.config({  
  2.     debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。  
  3.     appId: '', // 必填,公众号的唯一标识  
  4.     timestamp: , // 必填,生成签名的时间戳  
  5.     nonceStr: '', // 必填,生成签名的随机串  
  6.     signature: '',// 必填,签名  
  7.     jsApiList: [] // 必填,需要使用的JS接口列表  
  8. });  

步骤四:通过ready接口处理成功验证

[html] view plain copy
  1. wx.ready(function(){  
  2.     // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。  
  3. });  

步骤五:通过error接口处理失败验证

[html] view plain copy
  1. wx.error(function(res){  
  2.     // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。  
  3. });  

地理位置

使用微信内置地图查看位置接口

wx.openLocation({
latitude: 0, // 纬度,浮点数,范围为90 ~ -90
longitude: 0, // 经度,浮点数,范围为180 ~ -180。
name: '', // 位置名
address: '', // 地址详情说明
scale: 1, // 地图缩放级别,整形值,范围从1~28。默认为最大
infoUrl: '' // 在查看位置界面底部显示的超链接,可点击跳转
});

获取地理位置接口

wx.getLocation({
type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
var speed = res.speed; // 速度,以米/每秒计
var accuracy = res.accuracy; // 位置精度
}
});

代码示例:

nav.js

//获取浏览器信息
var browser = {
	ua : function() {
		var u = navigator.userAgent;
		var isChrome = u.match(/Chrome\/([\d.]+)/)
				|| u.match(/CriOS\/([\d.]+)/);
		var isAndroid = u.match(/(Android);?[\s\/]+([\d.]+)?/);
		var iosVersion = function() {
			if (/iP(hone|od|ad)/.test(navigator.platform)) {
				var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
				return [ parseInt(v[1], 10), parseInt(v[2], 10),
						parseInt(v[3] || 0, 10) ];
			}
		}();
		var chromeVersion = function() {
			var chrome = navigator.userAgent.match(/Chrome\/(\d+)\./);
			if (chrome) {
				return parseInt(chrome[1], 10);
			}
		}();
		var ios9 = iosVersion && iosVersion[0] >= 9;
		var chrome18 = isChrome && isAndroid && chromeVersion
				&& chromeVersion > 18;
		return { // 移动终端浏览器版本信息
			trident : u.indexOf('Trident') > -1, // IE内核
			presto : u.indexOf('Presto') > -1, // opera内核
			webKit : u.indexOf('AppleWebKit') > -1, // 苹果、谷歌内核
			gecko : u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, // 火狐内核
			mobile : !!u.match(/AppleWebKit.*Mobile.*/), // 是否为移动终端
			iOS : !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), // ios终端
			android : u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, // android终端或uc浏览器
			iPhone : u.indexOf('iPhone') > -1, // 是否为iPhone或者QQHD浏览器
			iPad : u.indexOf('iPad') > -1, // 是否iPad
			webApp : u.indexOf('Safari') == -1, // 是否web应该程序,没有头部与底部
			weChat : u.indexOf('MicroMessenger') > -1,
			UC : u.indexOf('UCBrowser') > -1,
			u3 : u.indexOf('U3') > -1,
			chrome : u.indexOf('Chrome') > -1,
			windowsPhone : u.indexOf("Windows Phone") > -1,
			samsung : u.indexOf("Samsung") > -1,
			QQ : (u.match(/\sQQ/i) != null ? u.match(/\sQQ/i).toLowerCase() == " qq"
					: false),
			isChrome : isChrome,
			isAndroid : isAndroid,
			iosVersion : iosVersion,
			chromeVersion : chromeVersion,
			ios9 : ios9,
			chrome18 : chrome18
		};
	}()
}
var ua = browser.ua;

// 打开地图App,开始导航
function openMapApp(lat, lng, addr) {
	// 地图uri api数组
	var uri = new Array();
	if (ua.android) {
		// 百度地图uri api
		uri[0] = "bdapp://map/navi?location=" + lat + "," + lng + "&query="
				+ addr;
		// 高德地图uri api
		uri[1] = "androidamap://navi?sourceApplication=xlwx&poiname=" + addr
				+ "&lat=" + lat + "&lon=" + lng + "&dev=1&style=2";
		// 腾讯地图uri api
		uri[2] = "qqmap://map/marker?marker=coord:" + lat + "," + lng
				+ ";title:" + addr + "&referer=xlwx";
	} else if (ua.iOS) {
		// 百度地图uri api
		uri[0] = "baidumap://map/navi?location=" + lat + "," + lng + "&query="
				+ addr;
		// 高德地图uri api
		uri[1] = "iosamap://navi?sourceApplication=xlwx&poiname=" + addr
				+ "&lat=" + lat + "&lon=" + lng + "&dev=1&style=2";
		// 腾讯地图uri api
		uri[2] = "qqmap://map/marker?marker=coord:" + lat + "," + lng
				+ ";title:" + addr + "&referer=xlwx";
		// 苹果地图uri api
		uri[3] = "http://maps.apple.com/?sll=" + lat + "," + lng + "&address="
				+ addr;
	}
	//调用uri	
	if(uri.length == 0){
		return;
	}
	window.location.href = uri[0];
	//启动定时器time1
	var time1 = setTimeout(function() {
		// 若启动应用,则js会被中断较长时间,超出此范围
		window.location.href = uri[1];
	}, 2000);
	//启动定时器time2
	var time2 = setTimeout(function() {
		// 若启动应用,则js会被中断较长时间,超出此范围
		window.location.href = uri[2];
	}, 4000);
	//清除定时器
	window.beforeunload = function() {
		if(time1 != null){
			clearTimeout(time1);
		}
		if(time2 != null){
			clearTimeout(time2);
		}		
	}
	window.pagehide = function() {
		if(time1 != null){
			clearTimeout(time1);
		}
		if(time2 != null){
			clearTimeout(time2);
		}
	}
	window.onblur = function() {
		if(time1 != null){
			clearTimeout(time1);
		}
		if(time2 != null){
			clearTimeout(time2);
		}
	}
}
map.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*,com.wx.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<title>获取位置信息</title>
<link href="${pageContext.request.contextPath }/css/app_comm.css" rel="stylesheet" type="text/css" />
<link href="${pageContext.request.contextPath }/css/app_style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/app_comm.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/common.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/navigation/nav.js"></script>
<script charset="utf-8" src="http://map.qq.com/api/js?v=2.exp&libraries=convertor"></script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

<%  
Map<String, String> ret = new HashMap<String, String>();  
String url = request.getScheme() + "://" + request.getServerName() + "/map";
ret = JsSignUtil.sign(url);
%>

<script type="text/javascript">
//全局变量
var map = null;
//驾驶服务
var drivingService = null;
//信息窗口
var infoWindow = null;
//驾驶策略
var policys = ["LEAST_TIME","LEAST_DISTANCE","AVOID_HIGHWAYS","REAL_TRAFFIC"];
//当前位置的marker
var curr_marker = null;
//当前位置坐标
var curr = null;

//就绪时执行
$(function(){
	//初始化地图
	init();
});

//初始化
function init(){
	//初始化导航窗口
    initNavWindow();
	//加载腾讯地图
    initMap();
    //获取用户当前状态
    getUserChargeStatus(); 
    //初始化导航按钮
    initNavClick();
    //初始化微信定位接口
    initWxLocation();
}

//初始化微信定位接口
function initWxLocation(){
	//配置微信定位功能 start
	wx.config({  
	    debug: false,  
	    appId: '<%=ret.get("appId")%>',  
	    timestamp:'<%=ret.get("timestamp")%>',  
	    nonceStr:'<%=ret.get("nonceStr")%>',  
	    signature:'<%=ret.get("signature")%>',  
	    jsApiList : [ 'checkJsApi', 'openLocation', 'getLocation' ]  
	});//end_config  
	  
	wx.error(function(res) {  
	    alert("出错了:" + res.errMsg);  
	});  
	  
	wx.ready(function() { 
	    //判断当前客户端版本是否支持指定JS接口 
	    wx.checkJsApi({  
	        jsApiList : ['getLocation'],  
	        success : function(res) {  
	        }  
	    }); 
	        
	    //获取位置信息        
	    wx.getLocation({
	    	type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
	        success: function (res) {
	            var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
	            var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
	            var speed = res.speed; // 速度,以米/每秒计
	            var accuracy = res.accuracy; // 位置精度
	            //alert("纬度:" + latitude + ", 经度:" + longitude);
	            //循环定位,每隔一段时间会自动定位一次
	            //转换gps坐标为腾讯坐标
	            //curr = new qq.maps.LatLng(latitude, longitude);
		        qq.maps.convertor.translate(new qq.maps.LatLng(latitude, longitude), 1, function(res){
		        	curr = res[0];
		        	if(curr_marker == null){
		            	panPointAndGetPlants();
		            }else{
		            	curr_marker.setPosition(curr);
		            }
			    });	            
	        },
	        cancel: function (res) {
	            alert('用户拒绝授权,获取地理位置失败');
	        },
	        fail: function(error) {
	            alert('获取地理位置失败,请确保开启GPS且允许微信获取您的地理位置!');
	        }
	    });    
	}); //配置微信定位功能 end
}

//平移中心点,获取列表
function panPointAndGetPlants(){
	//平移中心点到定位位置
    panToPoint(curr);      
    //获取附近的列表
    getPlants();
}

//初始化地图
function initMap(){
	//设置c_map高度
	$("#c_map").height($(window).height() - 55);
	//初始位置天安门
	var center = new qq.maps.LatLng(39.908860, 116.397390);
    map = new qq.maps.Map(document.getElementById("c_map"), {
        center: center,
        zoom: 10,
      	//启用比例尺
        scaleControl: true,
        scaleControlOptions: {
            //设置控件位置相对右下角对齐,向左排列
            position: qq.maps.ControlPosition.BOTTOM_RIGHT
        },
        //启用缩放控件
        zoomControl: true,
        //设置缩放控件的位置和样式
        zoomControlOptions: {
            //设置缩放控件的位置为相对左方中间位置对齐.
            position: qq.maps.ControlPosition.LEFT_TOP,
            //设置缩放控件样式为仅包含放大缩小两个按钮
            style: qq.maps.ZoomControlStyle.SMALL
        }
    });
}

//平移地图中心点,定位位置
function panToPoint(point){
	if(map != null){
		//panTo()将地图中心移动到指定的经纬度坐标。
        map.panTo(point);
        //zoomTo()将地图缩放到指定的级别。
        map.zoomTo(13);
        //绘制当前位置marker
        curr_marker = new qq.maps.Marker({
            //设置Marker的位置坐标
            position: point,
            //设置Marker被添加到Map上时的动画效果为落下
            animation: qq.maps.MarkerAnimation.DOWN,
            //设置显示Marker的地图
            map: map,
            //自定义Marker图标为大头针样式
            icon: new qq.maps.MarkerImage("images/zb_curr.png")
        });
	}
}

function getPlants(){
	if(curr == null){
		return;
	}
	ajaxSyncRequest('${pageContext.request.contextPath}/wx/pileList',{"latitude":curr.getLat(),"longitude":curr.getLng()},function(res){
	       if(res.success){
	    	   //将JSON字符串转换为JavaScript对象	    	   
	    	   drawerMarker($.parseJSON(res.datas));
	       }else{
	    	   alert(res.msg);
	       }
	});
}

//获取用户当前状态
function getUserChargeStatus(){
    ajaxSyncRequest('${pageContext.request.contextPath}/wx/getUserInfo',{},function(data){
       if(data.success){
           if(data.user.useStatus == 1){
               window.location.href="show";
               return;
           }	      
           if(data.user.billNotified == 1){
               //notifybill接口被调用,数据没复位
               window.location.href="show";
               return;
           }     	
       }
    });
}

//绘制附近的marker
//[{"id":1,"plantName":demo,"address":"深圳","distance":800,"num":2,"driver":10}]
function drawerMarker(datas){	
	$.each(datas, function(i, data){		
		//转换百度坐标为腾讯坐标
		qq.maps.convertor.translate(new qq.maps.LatLng(data.latitude, data.longitude), 3, function(res){
			var point = res[0];
			//创建一个Marker
	    	var marker = new qq.maps.Marker({
		        //设置Marker的位置坐标
		        position: point,
		        //设置Marker被添加到Map上时的动画效果为从天而降
		        animation:qq.maps.MarkerAnimation.DROP,
		        //设置显示Marker的地图
		        map: map,
		        //自定义Marker图标为大头针样式
		        icon: new qq.maps.MarkerImage("images/zb.png")
	    	});	
	    	//添加信息窗口
	    	getInfoWindow();
			//info窗口内容
			var html = '<div class="app_infowindow">';
			html = html + '<ul><li>';
			html = html + '<p><font class="app_infowindow_name">';
			html = html + data.plantName;
			html = html + '</font><i><font class="col_or">';
			html = html + data.num;
			html = html + '</font>可用</i></p><p>';			
			html = html + data.address;
	        html = html + '</p></li></ul></div>';
	        html = html + '<div class="app_infoicon" onclick="routeplan(';
	        html = html + point.getLat() + "," + point.getLng() + ",'" + data.address + '\')">';
	        html = html + '<img src="images/arrow.png"><br/>';
	        html = html + '<a href="#">去这里<a/>';
	        html = html + '</div>';
	        //标记Marker点击事件
	        qq.maps.event.addListener(marker, 'click', function(){
	        	infoWindow.open();		            
	        	infoWindow.setContent(html);
	        	infoWindow.setPosition(marker.getPosition());	        	
	        });	
		});
	});
}

//路线规划
function routeplan(lat, lng, addr){
	//保存数据,切换策略时用
	$("#to_lat").val(lat);
	$("#to_lng").val(lng);
	$("#to_addr").val(addr);
	//起始位置
	var from = curr;
	//目的地
	var to = new qq.maps.LatLng(lat, lng);
	//驾驶策略
	var policy = policys[parseInt($("#to_policy").val())];	
	//设置获取驾车线路方案的服务
    getDrivingService();
	//清空当前结果在map和panel中的展现。
    drivingService.clear();
    //设置驾车方案
    drivingService.setPolicy(qq.maps.DrivingPolicy[policy]);
    //设置驾车的区域范围
    //drivingService.setLocation("北京");
    //设置回调函数
    drivingService.setComplete(function(result) {
        if (result.type == qq.maps.ServiceResultType.MULTI_DESTINATION) {
            //起终点不唯一
            var d = result.detail;
            drivingService.search(d.start[0], d.end[0]);
        }else{
        	$(".tab_title").text(addr);
        	var dis = parseFloat(result.detail.distance) / 1000;
        	$("#dist").text(dis.toFixed(1));
        	$("#dur").text(result.detail.duration);
        }
    });
    //设置检索失败回调函数
    drivingService.setError(function(data) {
        alert(data);
    });
    //设置驾驶路线的起点和终点
    drivingService.search(from, to);
    //关闭infowindow
    infoWindow.close();
    //弹出导航窗口
    if($("#info").is(":hidden")){
    	$("#info").slideToggle(300);   	
    }	
}

//获取驾驶服务
function getDrivingService(){
	if(drivingService == null){
		drivingService = new qq.maps.DrivingService({
	        map: map,
	        //展现结果,自定义
	        //panel: document.getElementById('info')
	    });
	}
}

//获取info window
function getInfoWindow(){
	if(infoWindow == null){
		infoWindow = new qq.maps.InfoWindow({
	        map: map
	    });
	}
}

//初始化导航窗口
function initNavWindow(){
	//初始化导航窗口为隐藏状态
	$("#info").hide();
	//初始化导航tab
	$(".tab_bar ul li").click(function(){
		$(".tab_bar ul li").removeClass("tab_bar_curr");
		$(this).addClass("tab_bar_curr");
		$("#to_policy").val($(this).index());
		var lat = $("#to_lat").val();
		var lng = $("#to_lng").val();
		var addr = $("#to_addr").val();
		routeplan(lat, lng, addr);
	});
}

//初始化导航按钮
function initNavClick(){
	$(".tab_right").click(function(){
		var lat = $("#to_lat").val();
		var lng = $("#to_lng").val();
	    var addr = $("#to_addr").val();	
		openMapApp(lat, lng, addr);
	});
}

</script>
<style type="text/css">
	.app_infowindow{ float:left; margin:0px 10px 0px 0px}
	.app_infowindow li p{ line-height:16px; font-size:8px; color:#999;}
	.app_infowindow li p i{ padding:0 5px; border-radius:5px; background:#eee;}
	.app_infowindow_name{ font-weight:bold; font-size:12px; color:#333;}
	.app_infoicon{ float:left; padding:0px 0px 0px 10px; height:100%; border-left:1px #eee solid }
	.app_infoicon img{ width:28px; height:28px;}
	.app_infoicon a{font-size:12px; color:#67bcf2;}
	.app_panel{width:100%; height:100px; background:#edebe8; bottom:55px; position:fixed;}
	.tab_bar{width:100%; height:30px; background:#fff; bottom:135px; position:fixed;}
	.tab_bar ul{padding-top:6px;}	
	.tab_bar_li{width:25%; float:left; text-align:center; font-size:12px; position:relative; color:#b5b5b5}
	.tab_bar_curr{color:#068cfb;}
	.tab_context{width:100%; height:70px; bottom:55px; position:fixed; padding:0px 0px 0px 10px;}
	.tab_context .tab_left{width:80%; float:left; position:relative;}
	.tab_context .tab_right{width:20%; float:left; position:relative;}
	.tab_left p{line-height:28px;}
	.tab_title{ font-weight:bold; font-size:16px; color:#333;}
	.tab_text{ font-size:14px; color:#999;}
	.ico_nav{ width:32px; height:32px; text-align:center;}
	.nav_text{ font-size:14px; color:#068cfb;}
	.app_map{height:650px}
</style>
</head>

<body>

<div class="w_all app_main">
    <!-- 存储数据 -->
	<input type="hidden" id="to_lat" value=""/>
    <input type="hidden" id="to_lng" value=""/>	
    <input type="hidden" id="to_addr" value=""/>
    <input type="hidden" id="to_policy" value="0"/>
    <!-- map -->	
	<div class="app_map" id="c_map"></div>
	<div class="app_panel" id="info">
		<div class="tab_bar">
		    <ul> 
		        <li class="tab_bar_li tab_bar_curr">最少时间</li>
		        <li class="tab_bar_li">最短距离</li>
		        <li class="tab_bar_li">不走高速</li>
		        <li class="tab_bar_li">躲避拥堵</li>	        
		    </ul>
		</div>
		<div class="tab_context">
			<div class="tab_left">
				<p class="tab_title">北京</p>
				<p class="tab_text"><span id="dist">2.0</span>公里 | <span id="dur">12</span>分钟</p>
			</div>
			<div class="tab_right">
			    <img src="images/navigation.png" class="ico_nav"/>
			    <p class="nav_text">导航</p>
			</div>
		</div>
	</div>	
    <div class="app_menu">
    </div>
</div>

</body>
</html>

完!!!

2017-10-11 11:15:32 xiaoyu11081 阅读数 3170

首先这个坑是工作遇到的问题,正好需要分享链接有小图,于是各种百度,发现这里第三方网址需要接入微信的东西,才能正常的显示出小图等。

 

对于想了解如何操作的,觉得我的博客看不太懂的,可以参考 慕课网—微信相关视频学习、

 

前期准备工作    1.公众号  2.了解微信公众号开发  3.打开网址看微信公众平台开发者手册   

 

微信公众平台开发者手册:https://mp.weixin.qq.com/  

 

什么是JS-SDK  ??  是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包

 

微信JS-SDK 开发步骤:

步骤一:绑定域名 (登录微信公众平台)   例如下图:

 

步骤二:引入JS文件

步骤三:通过config接口注入权限验证配置

步骤四:通过ready接口处理成功验证

步骤五:通过error接口处理失败验证

 

 

 

 

 

注意事项!!!一下代码部分 关于appid  appsecret 以及 分享 图标 标题 链接 均空出,请填写好你们自己需要填写的!!!!!

 

关于微信的分享接口

代码实现部分,首先创建一个php文件,写入下面的代码。 这里还是结合了TP框架来的,所以有一些写法是TP框架中的。

 

//获取token
function wx_get_token() {
    $token = S('access_token');
    if (!$token) {
        $appid='';
        $appsecret='';
        $res = file_get_contents('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$appsecret);
        $res = json_decode($res, true);
        $token = $res['access_token'];
        // 注意:这里需要将获取到的token缓存起来(或写到数据库中)
        // 不能频繁的访问https://api.weixin.qq.com/cgi-bin/token,每日有次数限制
        // 通过此接口返回的token的有效期目前为2小时。令牌失效后,JS-SDK也就不能用了。
        // 因此,这里将token值缓存1小时,比2小时小。缓存失效后,再从接口获取新的token,这样
        // 就可以避免token失效。
        // S()是ThinkPhp的缓存函数,如果使用的是不ThinkPhp框架,可以使用你的缓存函数,或使用数据库来保存。
        S('access_token', $token, 3600);
    }
    return $token;
}

//获取ticket
function wx_get_jsapi_ticket(){
    $ticket = "";
    do{
        $ticket = S('wx_ticket');
        if (!empty($ticket)) {
            break;
        }
        $token = S('access_token');
        if (empty($token)){
            wx_get_token();
        }
        $token = S('access_token');
        if (empty($token)) {
            logErr("get access token error.");
            break;
        }
        $url2 = sprintf("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi",
            $token);
        $res = file_get_contents($url2);
        $res = json_decode($res, true);
        $ticket = $res['ticket'];
        // 注意:这里需要将获取到的ticket缓存起来(或写到数据库中)
        // ticket和token一样,不能频繁的访问接口来获取,在每次获取后,我们把它保存起来。
        S('wx_ticket', $ticket, 3600);
    }while(0);
    return $ticket;
}
//获取16位随机编码
function getRandCode( $length = 16 ) {
 $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
 $tmpstr ='';
    for ( $i = 0; $i < $length; $i++ )
    {
    // 这里提供两种字符获取方式
    // 第一种是使用 substr 截取$chars中的任意一位字符;
    // 第二种是取字符数组 $chars 的任意元素
    // $password .= substr($chars, mt_rand(0, strlen($chars) – 1), 1);
        $tmpstr .= $chars[ mt_rand(0, strlen($chars) - 1) ];
    }
return $tmpstr;
}

//分享朋友圈
public function  shareWx(){
    //1.获取jsapi_ticket票据
    $ticket=$this->wx_get_jsapi_ticket();
    $timestamp=time();
    $nonceStr=$this->getRandCode();
    $url='';
    //按照微信的要求排序拼接组合
    $signature = sprintf("jsapi_ticket=%s&noncestr=%s×tamp=%s&url=%s",
        $ticket, $nonceStr, $timestamp, $url
    );
    $signature= sha1($signature);
    $this->assign('timestamp',$timestamp);
    $this->assign('noncestr',$nonceStr);
    $this->assign('signature',$signature);
    $this->display('index');
}

 
********************************分隔线,接下来是前台部分*************************************************
1.首先在我们需要分享链接的HTML页面 引入必要的文件、

 
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

2.然后接下来我们写入js分享部分的代码,我是在另外一个Js文件中写入,然后html文件加载。懒一点的同学也可以直接在html

页面的<script></script>标签中去写。

 
<script src="__PUBLIC__/js/shareWX.js"></script>
代码部分如下所示:

 
// 微信配置 wx.config({ debug: false, appId: "", timestamp: '<{$timestamp}>', nonceStr: '<{$noncestr}>', signature: '<{$signature}>', jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage'] // 功能列表,我们要使用JS-SDK的什么功能 }); // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在 页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready 函数中。 wx.ready(function(){ // 获取“分享到朋友圈”按钮点击状态及自定义分享内容接口  wx.onMenuShareTimeline({ title: '沈阳宏大', // 分享标题  link:"",//分享的url,以http或https开头  imgUrl: "" // 分享图标  }); // 获取“分享给朋友”按钮点击状态及自定义分享内容接口  wx.onMenuShareAppMessage({ title: '沈阳宏大', // 分享标题  desc: "低投入高效率", // 分享描述  link:"", imgUrl: "", // 分享图标  type: 'link', // 分享类型,music、video或link,不填默认为link  }); });

 


 

 

 

2019-05-31 16:28:39 songzi1228 阅读数 613

微信官网开发文档

Android资源下载

相关文章:android实现微信联合登录开发

目录

一、申请你的AppID

二、下载SDK及API文档

三、在代码中使用开发工具包

1、AndroidManifest.xml 设置

四、开发

1、新建 WXEntryActivity

2、注意:debug状态下调试

3、代码编写:

第一步:请求CODE:移动应用微信授权登录

第二步:通过code获取access_token

第三步:通过access_token调用接口

第四步:获取用户个人信息(UnionID机制)


一、申请你的AppID

微信开放平台申请AppID,注意:因为涉及到登录功能,必须企业注册的开发者账号才能申请登录功能。个人开发者账号只能使用分享功能。

二、下载SDK及API文档

在build.gradle文件中,添加如下依赖即可:

dependencies {
    compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
}

dependencies {
    compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
}

(其中,前者包含统计功能)

三、在代码中使用开发工具包

1、AndroidManifest.xml 设置

添加必要的权限支持(其中网络权限如果没有使用扫码登录功能非必要;后三个权限,如果没有使用mta,也非必要,即使有使用mta,去掉也不影响功能):

<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"/>

其他具体看这里

四、开发

1、新建 WXEntryActivity

新建一个包,名为wxapi,然后在此包下新建WXEntryActivity

2、注意:debug状态下调试

微信支付和微信的第三方登录一样,测试的时候必须是正式包,不能是debug的,来进行测试,这样就没有办法调试了,感觉很不爽。所以提供一个办法来拯救一下嘿嘿:

在build.gradle文件中设置debug环境和relealse环境的签名相同就可以解决这个文通了,已经试过了,可以的。

3、代码编写:

第一步:请求CODE:移动应用微信授权登录

Android平台应用授权登录接入代码示例(请参考Android接入指南):

{
    // send oauth request
    Final SendAuth.Req req = new SendAuth.Req();
    req.scope = "snsapi_userinfo";
    req.state = "wechat_sdk_demo_test";
    api.sendReq(req);
}

参数说明

参数 是否必须 说明
appid 应用唯一标识,在微信开放平台提交应用审核通过后获得
scope 应用授权作用域,如获取用户个人信息则填写snsapi_userinfo( 什么是授权域? )
state 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验

返回示例:

appid: wxd477edab60670232
scope: snsapi_userinfo
state: wechat_sdk_demo

我的代码: 

private SendAuth.Req req;

//请求微信OAuth2.0授权登录
    private void sendAuth() {
        req = new SendAuth.Req();
        req.scope = WEIXIN_SCOPE;
        req.state = WEIXIN_STATE;
        api.sendReq(req);
    }

    @Override
    public void onResp(BaseResp baseResp) {
        int type = baseResp.getType();
        if (type == 1) {
            // 登录
            SendAuth.Resp sendAuthResp = (SendAuth.Resp) baseResp;
            String wxCode = sendAuthResp.code;
            String state = ((SendAuth.Resp) baseResp).state;
            int errCode = baseResp.errCode;

            getWxAccessToken(wxCode);

        }
    }

可拉起微信打开授权登录页:

 

返回说明

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

返回值 说明
ErrCode ERR_OK = 0(用户同意) ERR_AUTH_DENIED = -4(用户拒绝授权) ERR_USER_CANCEL = -2(用户取消)
code 用户换取access_token的code,仅在ErrCode为0时有效
state 第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传,state字符串长度不能超过1K
lang 微信客户端当前语言
country 微信用户当前国家信息

 

第二步:通过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 应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
code 填写第一步获取的code参数
grant_type 填authorization_code

正确的返回:

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

我的代码: 

private void getWxAccessToken(String wxCode) {
        RequestCenter.getWxAccesstoken(Constants.WX_APP_ID, Constants.WX_APP_SECRET, wxCode, new DisposeDataListener() {
            @Override
            public void onSuccess(Object responseObj) {
                LogUtils.json(responseObj.toString());
                WxAccessBean wxAccessBean = new Gson().fromJson(responseObj.toString(), WxAccessBean.class);

            }

            @Override
            public void onFailure(Object reasonObj) {

            }
        });
    }

第三步:通过access_token调用接口

此处不细说,具体看文档。

第四步:获取用户个人信息(UnionID机制)

接口说明

此接口用于获取用户个人信息。开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。请注意,在用户修改微信头像后,旧的微信头像URL将会失效,因此开发者应该自己在获取用户信息后,将头像图片保存下来,避免微信头像URL失效后的异常情况。

请求说明

http请求方式: GET
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

参数说明

参数 是否必须 说明
access_token 调用凭证
openid 普通用户的标识,对当前开发者帐号唯一
lang 国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN

返回说明

正确的Json返回结果:

{
"openid":"OPENID",
"nickname":"NICKNAME",
"sex":1,
"province":"PROVINCE",
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
"privilege":[
"PRIVILEGE1",
"PRIVILEGE2"
],
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
参数 说明
openid 普通用户的标识,对当前开发者帐号唯一
nickname 普通用户昵称
sex 普通用户性别,1为男性,2为女性
province 普通用户个人资料填写的省份
city 普通用户个人资料填写的城市
country 国家,如中国为CN
headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
privilege 用户特权信息,json数组,如微信沃卡用户为(chinaunicom)
unionid 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。

建议:

开发者最好保存unionID信息,以便以后在不同应用之间进行用户信息互通。

错误的Json返回示例:

{
"errcode":40003,"errmsg":"invalid openid"
}

调用频率限制

接口名 频率限制
通过code换取access_token 5万/分钟
获取用户基本信息 5万/分钟
刷新access_token 10万/分钟