精华内容
下载资源
问答
  • 第一次对接小程序授权的时候以为能一进入这个项目就要调用获取授权信息,后面写好逻辑之后提交审核,一直审核不通过,后面查了原因之后才发现不能一进入页面就调用授权,而且项目需要个人信息和手机号码两个都要获取...

    第一次对接小程序授权的时候以为能一进入这个项目就要调用获取授权信息,后面写好逻辑之后提交审核,一直审核不通过,后面查了原因之后才发现不能一进入页面就调用授权,而且项目需要个人信息和手机号码两个都要获取,所以我只能分开两个页面写两个点击按钮,要进行微信授权一定要有按钮给用户点击才能掉起微信的授权框

    获取用户个人信息

    html:

    //获取用户个人信息
    <button class="btn typography" open-type="getUserInfo" @getuserinfo="miniprogramlogin">微信授权</button>
    

    js: (为了方便我把每个步骤都分了一个方法写~)

    miniprogramlogin(e) {
    			var _this = this;
    			wx.login({
    				success(res) {
    					if (res.code) {
    						_this.miniprogramcode = res.code;
    						_this.getUserInfo(e);
    					} else {
    						console.log('登录失败!' + res.errMsg);
    					}
    				}
    			});
    	},
    	//获取微信个人信息
    		getUserInfo(e) {
    			var _this = this;
    			let params = { code: this.miniprogramcode };
    			let data = Api.apiCall('get', Api.weixin.miniprogramlogin, params);//请求后端接口
    			if (data) {
    				//这个接口我这边后端会返回两种格式,返回sessionKey是未授权过,所以得判断是否返回的是sessionKey和openid
    				if (data.sessionKey) {
    					this.sessionKey = data.sessionKey;
    					//未授权过直接调用微信API
    					wx.getUserInfo({
    						success: function(res) {
    							_this.getuserdata(res);//获取参数再调用接口传给后端
    							_this.signature = res.signature;
    							_this.rawData = res.rawData;
    						}
    					});
    				} else {
    					//已授权过直接保存接口返回的用户信息(看情况可不用这一步)
    					_this.login(data.userInfo);
    					uni.setStorageSync('userInfo', data.userInfo);
    					uni.setStorageSync('userInfos', data.userInfo);
    					uni.setStorageSync('token', data.tokenHead + data.token);
    					uni.switchTab({
    						url: '/pages/index/index'
    					});
    				}
    			}
    		},
    		//调用接扣传参解码
    		getuserdata(resdata) {
    			var _this = this;
    			uni.request({
    				url: '/api/wx/redirect/minAppInfo',
    				method: 'get',
    				header: {
    					'content-type': 'application/x-www-form-urlencoded'
    				},
    				data: {
    					encryptedData: resdata.encryptedData,
    					iv: resdata.iv,
    					sessionKey: _this.sessionKey,
    					signature: resdata.signature,
    					rawData: resdata.rawData
    				},
    				success: res => {
    					_this.wxuserinfo = JSON.parse(res.data);
    					//下面的看情况可删,因为我要获取两次授权所以用户信息授权完会直接跳到手机号授权页面
    					uni.setStorageSync('sessionKey', _this.sessionKey);
    					uni.setStorageSync('signature', resdata.signature);
    					uni.setStorageSync('rawData', resdata.rawData);
    					uni.navigateTo({
    						url: `/public/miniprogramgetphone`
    					});
    				}
    			});
    		}
    

    获取用户手机号码

    html:

    //获取用户微信绑定的手机号码
    <button class="btn typography" open-type="getPhoneNumber" @getphonenumber="getminiprogramcode">手机号授权</button>
    

    js:

    //小程序授权登录接口
    		getminiprogramcode(e) {
    			console.log(e)
    			var _this = this;
    			//检验session_key是否过期,过期就要重新调用wx.login获取session_key 
    			wx.checkSession({
    				success(res) {
    					//session_key 未过期,并且在本生命周期一直有效
    					console.log(uni.getStorageSync('sessionKey'));
    					//获取上个页面存进缓存里的信息
    					_this.sessionKey = uni.getStorageSync('sessionKey');
    					_this.signature = uni.getStorageSync('signature');
    					_this.rawData = uni.getStorageSync('rawData');
    					_this.getPhoneNumber(e);
    				},
    				fail() {
    					// session_key 已经失效,重新登录
    					console.log('重新登录1')
    					wx.login({
    						success(res) {
    							if (res.code) {
    								_this.miniappcode = res.code;
    								_this.getphonecode(e);
    							} else {
    								console.log('登录失败!' + res.errMsg);
    							}
    						}
    					});
    				}
    			});
    		},
    		getPhoneNumber(e) {
    			var _this = this;
    			console.log(e.detail.errMsg);
    			//授权后的处理
    			if (e.detail.errMsg == 'getPhoneNumber:ok') {
    				//点击获取的信息
    				let params = {
    					encryptedData: e.detail.encryptedData,
    					sessionKey: _this.sessionKey,
    					iv: e.detail.iv,
    					signature: _this.signature,
    					rawData: _this.rawData,
    				};
    				_this.getuserphonnumber(params,e);
    			}
    		},
    	  getuserphonnumber(paramsdata,e) {
    			var _this = this;
    			let params = {
    				encryptedData: paramsdata.encryptedData,
    				sessionKey: paramsdata.sessionKey,
    				iv: paramsdata.iv,
    				signature: paramsdata.signature,
    				rawData: paramsdata.rawData,
    			};
    			let data = await Api.apiCall('get', Api.weixin.getminprogramuserphone, params);
    			if (data) {
    			  //授权登录后保存信息改变登录状态并跳转首页
    				_this.login(data.userInfo);
    				uni.setStorageSync('userInfo', data.userInfo);
    				uni.setStorageSync('userInfos', data.userInfo);
    				uni.setStorageSync('token', data.tokenHead + data.token);
    				uni.switchTab({
    					url: '/pages/index/index'
    				});
    			}
    		}
    

    可能看着会有点乱,后期我会整理一下流程,主要因为我这个项目是要点击两次按钮获取授权信息,所以有些参数信息我只能获取之后存入缓存然后到另一个页面再获取

    展开全文
  • 在平时使用第三方微信小程序时,经常会有需要获取微信手机号码的情况,如下图所示: 那这种是怎样实现的呢?下面记录下获取微信手机号码的方法。 备注:需要有一个微信小程序号,并且这个号是经过企业认证的。...

    背景

    在平时使用第三方微信小程序时,经常会有需要获取微信手机号码的情况,如下图所示:

    那这种是怎样实现的呢?下面记录下获取微信手机号码的方法。

    备注:需要有一个微信小程序号,并且这个号是经过企业认证的。(获取手机号码的功能不对个人小程序号生效)

     

    那下面我们就一起开始,获取手机号码的编程之旅了。

    1、打开微信开发者工具新建工程

    在app.json文件中新增    "pages/getphonenumber/getphonenumber", 如下图所示:

    2、准备密文解析工具类

    通过微信小程序提供的接口获取手机号码,返回的数据是加密的,所以需要对返回的加密数据进行解密。

    2.1 添加密文解析工具类需要用到的库

    第一步、在微信开发者工具中,点击 "终端" ——> “新建终端” 如下图所示:

      

    第二步、执行  npm init 指令

    //执行npm init后需要你输入一些信息,直接一直点击 “回车”键就好

    如下图所示:

    第三步、依次执行  npm install crypto-js --save 、 npm install js-base64 --save

    如下图所示:

    第四步、在微信开发工具的菜单栏 选择 “工具” ——> “构建npm” 构建完成即可

    2.2 解析类实现

    在工程的utils文件夹下新建 WXBizDataCrypt.js文件,代码实现如下所示:

    var CryptoJS = require("crypto-js");
    var Base64 = require("js-base64");
    
    //解析加密数据
    function decode(sesionKey,iv,data) {
      var key = CryptoJS.enc.Base64.parse(sesionKey);
      var iv = CryptoJS.enc.Base64.parse(iv);
      var decrypt = CryptoJS.AES.decrypt(data, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
      });
      return Base64.decode(CryptoJS.enc.Base64.stringify(decrypt));
    }
    
    module.exports = {
     decode
    }
    

    3、getphonenumber的实现

    3.1 、getphonenumber.js的实现

    注意: appId、secret需要替换为自身小程序的

    // pages/getphonenumber/getphonenumber.js
    const WXBizDataCrypt = require('../../utils/WXBizDataCrypt');
    
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        phoneNum:'',
        sessionKey:'',
        openId:'',
      },
    
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad: function (options) {
        this.getSessionKey();
      },
    
      getPhoneNumber: function(e){
        if (e.detail.errMsg == "getPhoneNumber:fail user deny") {
          wx.showToast({
            title: '拒绝授权,无法获取用户手机号码!',
          }) 
          return;
        }
        //解密数据获取手机号码
        this.decryptData(this.data.sessionKey,e.detail.iv,e.detail.encryptedData);
      },
    
      //获取SessionKey
      getSessionKey: function(){
        wx.login({
          success:res =>{
            console.log('code:'+res.code);
            var data = {
              'appid':'***********',//注意appId、secret需要替换为自身小程序的
              'secret':'**************************',
              'js_code':res.code,
              'grant_type':'authorization_code'
            };
    
            wx.request({
              url:'https://api.weixin.qq.com/sns/jscode2session',
              data:data,
              method:'GET',
              success:res =>{
                console.log("jscode2session result: ",res);
                this.setData({
                  sessionKey:res.data.session_key,
                  openId: res.data.openId
                })
              },
              fail:function(res){
                console.log("获取jscodeSession fail: ",res);
              }
            })
          }
        })
      },
    
      //解密数据
      decryptData: function(key,iv,encryptedData){
        var processData = WXBizDataCrypt.decode(key,iv,encryptedData);
        console.log("解密数据: ",processData);
        var jsonObj = JSON.parse(processData);
        this.setData({
          phoneNum: jsonObj['phoneNumber']
        })
      },
    })
    

    3.2、getphonenumber.wxml 实现

    <!--pages/getphonenumber/getphonenumber.wxml-->
    <button type="primary"  bindgetphonenumber="getPhoneNumber" open-type='getPhoneNumber'>获取手机号码</button>
    <text>获取到的手机号码:{{phoneNum}}</text>
    

    好了,实现内容就这么多。

    备注:一般情况下 获取jscode2session 是放到服务器端去实现的,这里我把获取sessionKey全都放在小程序端去实现了。

    参考小程序官网链接:

    https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html

     

    4、运行效果图

    默认运行                                                                点击“获取手机号码”                                            点击 “允许”按钮

                  

    展开全文
  • Android跳转到通讯录获取用户名称和手机号码

    千次阅读 多人点赞 2015-04-02 17:54:03
    某些在线购买或者快递业务等App会涉及到添加用户地址功能,就需要编辑用户名称、手机号码。这里就来实现快速跳转到通讯录界面获取通讯录用户信息的功能。先看效果:思路: 1.点击跳转到通讯录界面 2.获取通讯录...

    看到App项目中有这样一个需求,自己花时间也做了下。某些在线购买或者快递业务等App会涉及到添加用户地址功能,就需要编辑用户名称、手机号码。这里就来实现快速跳转到通讯录界面获取通讯录用户信息的功能。

    先看效果:

    这里写图片描述

    思路:
    1.点击跳转到通讯录界面
    2.获取通讯录姓名和手机号码
    3.回调显示姓名和手机号码
    1首先是跳转到通讯录界面

     Uri uri = Uri.parse("content://contacts/people");
                    Intent intent = new Intent(Intent.ACTION_PICK, uri);
                    startActivityForResult(intent, 0);

    通过设置通讯录url跳转,可以看到我们用回调函数实现
    2.回调函数

     /*
        * 跳转联系人列表的回调函数
        * */
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            switch (requestCode){
                case 0:
                    if(data==null)
                    {
                        return;
                    }
                    //处理返回的data,获取选择的联系人信息
                    Uri uri=data.getData();
                    String[] contacts=getPhoneContacts(uri);
                    et_name.setText(contacts[0]);
                    et_tele.setText(contacts[1]);
                    break;
            }
            super.onActivityResult(requestCode, resultCode, data);
        }

    其中getPhoneContacts(uri)方法,因为手机的联系人和手机号并不再同一个数据库中,所以我们需要分别做处理

    private String[] getPhoneContacts(Uri uri){
            String[] contact=new String[2];
            //得到ContentResolver对象
            ContentResolver cr = getContentResolver();
            //取得电话本中开始一项的光标
            Cursor cursor=cr.query(uri,null,null,null,null);
            if(cursor!=null)
            {
                cursor.moveToFirst();
                //取得联系人姓名
                int nameFieldColumnIndex=cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
                contact[0]=cursor.getString(nameFieldColumnIndex);
                //取得电话号码
                String ContactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
                Cursor phone = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + ContactId, null, null);
                if(phone != null){
                    phone.moveToFirst();
                    contact[1] = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                }
                phone.close();
                cursor.close();
            }
            else
            {
                return null;
            }
            return contact;
        }

    3.别忘了加权限

     <!--获取通讯录权限-->
        <uses-permission android:name="android.permission.READ_CONTACTS" />
        <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    感觉这个体验还是挺好,估计以后会用到,记录在此
    感觉好别忘了点赞!!重点内容!!

    展开全文
  • 最近在研究小程序,现在有个需求是获取小程序的手机号码,这个获取接口的权限需要用小程序的企业账号操作可以 首先要进行解密之前获取到sessionKey的值 const APP_ID = 'XXXXXXXXX'; //输入小程序appid const ...

    最近在研究小程序,现在有个需求是获取小程序的手机号码,这个获取接口的权限需要用小程序的企业账号操作可以

    首先要进行解密之前获取到sessionKey的值

    const APP_ID = 'XXXXXXXXX'; //输入小程序appid 
    
    const APP_SECRET = 'xxxxxxxxxxxxxxxxxxxx'; //输入小程序app_secret 
    
    var OPEN_ID = '' //储存获取到openid 
    
    var SESSION_KEY = '' //储存获取到session_key
    
    Page({
    
      getOpenIdTap: function() {
    
        var that = this;
    
        wx.login({
    
          success: function(data) {
    
            console.log(data);
    
            wx.request({
    
              //获取openid接口
    
              url: 'https://api.weixin.qq.com/sns/jscode2session?appid=' + APP_ID + '&secret=' + APP_SECRET + '&js_code=' + data.code + '&grant_type=authorization_code',
    
              data: {},
    
              method: 'GET',
    
              success: function(res) {
    
                console.log(res.data)
    
                OPEN_ID = res.data.openid; //获取到的openid 
    
                SESSION_KEY = res.data.session_key; //获取到session_key 
    
                that.setData({
    
                  openid: OPEN_ID,
    
                  session_key: SESSION_KEY
    
                });
    
              }
    
            })
    
          }
    
        })
    
      }
    
    })

     

    获取到sessionKey以后,还需要在授权登录的时候获取到iv,这步我就省略了

    下面是加密方法,这个方法是

    public class AESCodeUtils {
    
        // 算法名
        public static final String KEY_NAME = "AES";
        // 加解密算法/模式/填充方式
        // ECB模式只用密钥即可对数据进行加密解密,CBC模式需要添加一个iv
        public static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
    
        /**
         * 微信 数据解密<br/>
         * 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充<br/>
         * 对称解密的目标密文:encrypted=Base64_Decode(encryptData)<br/>
         * 对称解密秘钥:key = Base64_Decode(session_key),aeskey是16字节<br/>
         * 对称解密算法初始向量:iv = Base64_Decode(iv),同样是16字节<br/>
         *
         * @param encrypted   目标密文
         * @param session_key 会话ID
         * @param iv          加密算法的初始向量
         */
        public static String wxDecrypt(String encrypted, String session_key, String iv) {
            String json = null;
            byte[] encrypted64 = Base64.decodeBase64(encrypted);
            byte[] key64 = Base64.decodeBase64(session_key);
            byte[] iv64 = Base64.decodeBase64(iv);
            byte[] data;
            try {
                init();
                json = new String(decrypt(encrypted64, key64, generateIV(iv64)));
            } catch (Exception e) {
                e.printStackTrace();
            }
            return json;
        }
    
        /**
         * 初始化密钥
         */
        public static void init() throws Exception {
            Security.addProvider(new BouncyCastleProvider());
            KeyGenerator.getInstance(KEY_NAME).init(128);
        }
    
        /**
         * 生成iv
         */
        public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
            // iv 为一个 16 字节的数组,这里采用和 iOS 端一样的构造方法,数据全为0
            // Arrays.fill(iv, (byte) 0x00);
            AlgorithmParameters params = AlgorithmParameters.getInstance(KEY_NAME);
            params.init(new IvParameterSpec(iv));
            return params;
        }
    
        /**
         * 生成解密
         */
        public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes, AlgorithmParameters iv)
                throws Exception {
            Key key = new SecretKeySpec(keyBytes, KEY_NAME);
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            // 设置为解密模式
            cipher.init(Cipher.DECRYPT_MODE, key, iv);
            return cipher.doFinal(encryptedData);
        }
    }

    在这之前需要在pom中添加

    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.57</version>
    </dependency>

    然后

    //获取解密的值
    String json = AESCodeUtils.wxDecrypt(req.getEncrypteData(), req.getSessionKey(), req.getIv());
    json的值为格式为

    {"phoneNumber":"13111111111","purePhoneNumber":"13111111111","countryCode":"86","watermark":{"timestamp":1595658760,"appid":"wx3f222f0140ad1d"}}

    然后json解析,获取到具体的手机号

    //获取手机号
    String phoneNo = "";
    if (StringUtils.isNotEmpty(json)) {
        JSONObject jsonObject = JSONObject.parseObject(json);
        if (ObjectUtils.isNotNull(jsonObject)) {
            phoneNo = jsonObject.getString("phoneNumber");
        }
    }

    然后后面就按照自己的业务处理问题就可以了

    展开全文
  • 按钮触发获取用户信息 uni-app中与微信小程序官网所写会不同 <button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber" withCredentials="true">点击获取手机号码</button> 事件触发...
  • 获取用户手机

    千次阅读 2013-06-21 11:00:10
    网上好多获取用户手机号的方法,不过都要用到私有api,app审核的话很可能 通不过,刚才在群里聊,有个兄弟给了个建议,先记下来吧,没试过呢,万一以后能用到 网上有人卖这种服务,很简单,启动是 访问 ...
  • 小程序获取手机号码 1、获取手机号码前提条件 该小程序为非个人开发者,且完成了认证的小程序开放(不包含海外主体)。需谨慎使用,若用户举报较多或被发现在不必要场景下使用,微信有权永久回收该小程序的该接口...
  • 1.最近在开发小程序的项目中,服务端需要配合前端获取当前用户与微信绑定的手机号;需要以下两步: 1.1根据前端所传的code通过服务端调微信接口获取openId,sessionkey; 1.2根据前端所传的encrypdata,ivdata,...
  • 如何模拟1000个手机用户登录? 现在很多APP或者网站都需要使用手机号进行登录,那么使用手机号进行...本文重点在获取短信验证码的接口功能,故无需检验手机号的各个号码段等格式,所以选择上述的第二种“采用Jmeter的
  • 2、网站或者APP按规则生成短信验证码,并将用户手机号码和验证码内容通过短信验证接口发送到验证码短信平台。 3、验证码短信平台对经过一系列的判断并通过之后(账户余额、内容是否合规、手机
  • 通过手机号码进行用户关系绑定,好友在落地页中填写手机号,然后下载APP,使用同一手机号码注册登录,后台通过落地页及APP注册时上传的手机号码进行配对,就能绑定用户之间邀请关系,发放奖励,但是需要用户需要填写...
  • 在我们的生活中,经常会遇到(www.yunxintong100.com)需要手机注册,手机验证,手机修改密码的时候,而... ...下一步小编为大家详细分析。 一、获取短信验证码的基本流程 1.注册网站帐号时,首先输入自己的手机号码,点击
  • 背景 针对网络数据安全这一问题,工信部刚刚印发《电信和互联网行业提升网络数据安全保护能力专项行动方案》(下称...因为没有办法通过抓包或者其他手段能够知道第三方的sdk到底有没有尝试去获取你的手机号码或者说mac
  • 访问www.mob.com 进入mobAPI --找到手机号码查询吉凶 获得到了API信息。其中key的值需要用户申请,点击右上角申请之后会获得一个申请码即可使用该接口。例如博主申请的是2aa181c026ff4 访问的请求示例:...
  • uni-app 三方登录授权

    2020-10-13 10:37:30
    然后点击getphoneNumber函数(微信自带的)去获取用户手机号码 以上是小程序的授权登录方式 app端登录就相对于比较简单了 执行getUserInfoByApp函数 由于需求要获取到用户的手机号码所以拿到用户基本...
  • 验证码现在可以在GetContact App中使用,因此我的脚本也无法通过验证:(请使用其他令牌 警告 该项目不适用于下载GetContact数据库。 该项目提供了通过电话号码接收信息的机会,每月请求一个令牌的请求数量有限。 ...
  • uni-app实现一键登录

    千次阅读 2021-01-26 16:01:56
    uni-app实现一键登录uni-app实现一键登录...2)进入基础配置配置相关的信息,我这个是已经配置好了,在获取用户手机号码时需要云服务用到的ApiKey和ApiSecret可在这里获取 3)添加服务空间 2、uni-app项目开通uniCl
  • uni-app微信小程序授权登录详解(带注释)

    万次阅读 多人点赞 2020-07-10 11:52:10
    (还有一种open-type为getPhoneNumber可以获取用户手机号码,但是此方法需要用户授权两次,因为此方法只能获取用户电话号码,你如果需要获取用户头像和名称需要调用getUserInfo,这就导致用户会有2次授权的操作个人...
  • 很多网站、APP应用、内部管理软件在使用过程中,都需要会员进行手机号码验证、登录验证、操作验证,在各种验证形式中,手机短信验证的方式...1、 手机号码真实性验证:用户注册会员时,为了获取用户真实的手机号码
  • 被邀请人填写完毕后,当新用户使用手机号码登录应用程序时,系统将知道谁邀请了新用户。 来。 只有在准确获得用户邀请的来源之后,我们才能根据双方之间的邀请关系发布相应的奖励。 这是平台的邀请码和邀请链接表格...
  • 用户需要用电子邮件和电话号码进行注册,注册成功后它会获取用户手机通讯录数据,从而确定其社交圈。你可以在上边秀幸福,也可以吐槽不满,但你的朋友们却无法知道发布人是谁,除非特别熟悉的朋友凭感觉猜测。如果有...
  • 手机登录:可以让用户通过输入手机号码和密码进行登录.3.注册:可以使用手机号获取验证码注册账号二:打开一对一直播APP首页打开APP,会显示启动图画面,然后进入首页,首页包括:顶部导航 、轮播广告 、主播预览 、...
  • APP短信注册流程

    2016-02-28 13:09:42
    使用短信注册获取验证码,会用到apple ISP(即因特网服务提供商,能提供拨号上网服务、网上浏览、下载文件、收发电子邮件等服务,是网络最终用户进入Internet的入口和桥梁)。其大概流程如下:首先客户端通过POST...
  • // openid、订单编号 用户手机号码 订单状态 订单金额 订单交易时间 public function sendMessage($touser, $no, $phone, $status, $sum, $date) { $appid = APPID; $appsecret = APPSECRET; $template_id = 自己的...

空空如也

空空如也

1 2 3 4 5 6
收藏数 112
精华内容 44
关键字:

手机app获取用户手机号码