js如何获取android手机的电话号码和联系人,并且传递给PHP、Java后台

一、使用cordova代替android和iso、xcode的开发和打包

         这里先说说个人站在web的角度对cordova的一些理解:对于获取手机的一些原生信息,如调用摄像头、获取联系人,共享地理位置等,我的第一反应就是肯定要用原生的语言去做,如果js脚本要去调用,必须使用二次开发的接口。在百般无奈中,搜索到cordova这个打包工具,刚开始也是怀着病急乱投医的心态,试试,看看cordova生成的一些文件目录,发现cordova不就是把原生的一些类转换成对应的js对象,然后供开发者使用这些js吗?这让我想起5、6年前使用过的一个ajax框架DWR(可能已经过时了),它就是可以让js可以直接调用Java的service层方法,而且在js的环境中用法和Java一模一样。理解到此,心中有点底气,然后直接使用cordova了。

关于cordova的安装和使用,有许多的技术贴,下面的是步骤是在我自己的windows7系统中安装和操作的用例

1)cordova的安装

这里不得不啰嗦几句,cordova的安装实在是繁琐,大概是要兼顾各类型手机和项目混合管理的缘故吧。

步骤一:安装Node.js  npm

从node.js官网选择合适的版本下载:https://nodejs.org/en/,然后直接下一步安装就行。
安装完成后,在cmd中,输入 node -v 出现图中效果说明成功了npm -v

步骤二:安装Android SDK

安装最麻烦的就是这家伙,存在谷歌翻墙,带宽速度等诸多因素。
android是建立在Java基础上面的,所以安装android之前需要先安装jdk并且配置好对应的环境,这里不多赘述。

涉及到android的安装,需要安装和配置ant,官网的下载地址是:http://ant.apache.org/bindownload.cgi 
下载完解压之后得要配置环境,方法如下: 
变量: ANT_HOME 添加值: 刚解压到的路径:D:\tools\apache-ant-1.9.9
变量: Path 添加值:%ANT_HOME%\bin 
当然,不同path配置之间使用“;”隔开

然后是安装android的SDK,我这边用的是android-sdk_r24.4.1-windows.zip,解压后安装最新版本的android的sdk。android-sdk-windows下载的各版本sdk是存放在android-sdk-windows目录下的platforms文件夹中。而默认安装的sdk是存放在C:\Users\Administrator\AppData\Local\Android\sdk中,如果安装的android版本和cordova自定android插件的版本不兼容的话,可以复制正确的的android文件夹到C:\Users\Administrator\AppData\Local\Android\sdk\platforms文件夹中。
接下来就是配置环境变量了
变量: ANDROID_HOME 添加值: C:\Users\Administrator\AppData\Local\Android\sdk
变量: Path 添加值:%ANDROID_SDK_HOME%\platform-tools;%ANDROID_SDK_HOME%\tools;
安装成功后控制台输入:adb
显示如下图信息

步骤三:安装git

git的官方下载地址是:https://git-scm.com/downloads,只要下载解压后直接配置环境变量就行,在path中追加配置路径例如:D:\tools\gradle-4.2\bin;



步骤四:安装cordova

在控制台输入:npm install -g cordova
等待安装完成后,输入:cordova -v
出现下图,安装完成

2)cordova使用

 cordova的命令有很多,请按需要查询相关的插件名称和命令,这里没有必要一一列举,只列举当前标题所需要的一些命令。

创建cordova项目

先在控制台指定的cordova项目的指定根目录然后输入以下命令
cordova create helloCordova com.cordova.helloCordova 
其中,helloCordova为项目名,com.cordova.helloCordova为包名,如下图所示:


安装android插件

进入项目文件夹(这里以helloCordova为例),输入cordova platform add android,如下图所示:

当然可以安装其他手机平台和指定android版本,网上很多资源,这里也不列举了

安装“联系人”,“sim卡”插件

读取手机原生信息的插件自然有许多,不是越多越好,我们这里只安装当前项目功能所需要的,联系人和sim卡
继续在控制台分别输入:
cordova plugin add cordova-plugin-contacts 
cordova plugin add cordova-plugin-sim
安装结束后,输入cordova plugin ls查看当前项目安装了哪些插件,如下图:
这里发现多了两个插件,其中cordova-plugin-whitelist是cordova默认安装好的,而cordova-plugin-compat你可以理解为cordova-plugin-contacts的子插件,安装contacts的时候就会安装compat,不需要单独去安装。

3)cordova的项目开发

这里还是以helloCordova为例

项目结构

我们自己开发的目录是在www文件夹之下,其余的文件夹可以自己去看看,不难理解,无非就是一些插件、手机平台、生成apk所需图片等等的存放目录如图:


cordova是一个打包工具,当然可以使用其他的js框架,如jQuery等等,开发起来和我们正常开发web项目一样,这里直接上图吧

这里是在js文件夹中增加jQuery的插件,然后在index.html页面使用。

获取联系人和sim卡信息

在index.html中添加id="findContact"的按钮
    <body>
        <div class="app">
            <h1>helloCordova</h1>
            <!--添加start-->
            <div class="progress-button">
                <button id="findContact">点击进入</button>
            </div>
            <!--添加end-->          
            <div id="deviceready" class="blink">
                <p class="event listening">Connecting to Device</p>
                <p class="event received">Device is Ready</p>
            </div>
        </div>
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
        <script type="text/javascript" src="js/jquery-3.2.1.min.js"></script>
    </body>

在index.js中注册和获取联系人,并且加工成自己想要的json数据格式,这里建议开发的时候用alert打印出cordova获取到的联系人的json数据格式,用JSON.stringify处理就行。
var app = {
    // Application Constructor
    initialize: function() {
        document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
    },

    // deviceready Event Handler
    //
    // Bind any cordova events here. Common events are:
    // 'pause', 'resume', etc.
    onDeviceReady: function() {
        this.receivedEvent('deviceready');
        document.getElementById("findContact").addEventListener("click", findContact);
    },

    // Update DOM on a Received Event
    receivedEvent: function(id) {
        var parentElement = document.getElementById(id);
        var listeningElement = parentElement.querySelector('.listening');
        var receivedElement = parentElement.querySelector('.received');

        listeningElement.setAttribute('style', 'display:none;');
        receivedElement.setAttribute('style', 'display:block;');

        console.log('Received Event: ' + id);
    }

};


/*
1、查询当前手机上面的联系人列表和sim卡信息
2、异步提交到服务器
3、跳转到交易首页
 */
function findContact() {  
   //查询当前sim信息,目前获取不到号码信息,直接传deviceId
   window.plugins.sim.getSimInfo(function(res){
      var deviceId = '';
      if(res != ''){
        deviceId = res.deviceId;
      }

      //调用获取联系人函数
      getContacts(deviceId);    
    });

    
}

//获取当前用户的所有联系人
function getContacts(deviceId){
   var options = new ContactFindOptions();
   options.filter = "";
   options.multiple = true;
   fields = ["displayName","phoneNumbers"];
   navigator.contacts.find(fields, contactfindSuccess, contactfindError, options);
   
   //获取和处理联系人信息,传递给获取sim卡的函数 
   function contactfindSuccess(contacts) {
      //创建联系人对象数组
      var contactsArr = [];
      for (var i = 0; i < contacts.length; i++) {
        //创建联系人对象        
        var currContact = {};
        //设置联系人名称
        currContact.displayName = contacts[i].displayName;

        //设置联系人电话号码
        var phoneNumbers = [];
        if(contacts[i].phoneNumbers != null){
            for(var j=0;j<contacts[i].phoneNumbers.length;j++){
              phoneNumbers.push(contacts[i].phoneNumbers[j].value);
            }
         }
         currContact.phoneNumbers = phoneNumbers;

         contactsArr.push(currContact);
      }

      //调用ajax发送信息函数
      sendContacts(deviceId,JSON.stringify(contactsArr));
   }
    
   function contactfindError(message) {
      alert('Failed because: ' + message);
   }    
}


//同步当前手机号码和联系人到系统,然后跳转首页
function sendContacts(deviceId,contacts){
    /*
    这里填写自己的ajax发送代码
    */
}

app.initialize();

cordova和模拟器中测试

还是在控制台和指定的项目路径下,输入:cordova build android
一段时间后出现下图,说明打包成功,红色框起的是打包好的apk的存放路径,如下图:

由于我自己的机器上面没有android的开发和测试环境,这里我选择了一个android模拟器(网上很多,选一款能用的就行)来测试自己的代码。


将apk拖拽进去,如图,我们用cordova做的app就安装好,可以开始对我们的代码调试了。如果觉得这样比较麻烦,可以再去安装android的开发环境,总之随大家喜好去做就行。

本来以为到这一步了,万事大吉,没想到,折磨人的事情,才刚刚开始,我们下面来讨论。就是一个app中的数据,怎么ajax传到一个web的服务器?

二、ajax如何跨域访问PHP后台服务器

ajax的跨域问题,做惯了自己调用自己服务器web的工作人员可能接触的比较少,这里就以cordova的开发用例来阐述。

cordova的白名单配置

在config.xml配置中增加
<access origin="*" />
如图

配置到了这里还不算,还需要将您要访问的ajax的url在index.html中配置,这点很容易被忽略,我用红字标明,用你自己的url代替https://ssl.gstatic.com,如图:


使用jsonp进行数据传输

关于jsonp的说明,不多做解释,这里直接上代码,值得注意的是,jsonp只支持get的传输方式,dataType为jsonp
function sendContacts(deviceId,contacts){
    $.ajax({      
      type : 'get',
      url : 'XXX',
      async : false,
      dataType:'jsonp',
      jsonp:'callback',
      jsonpCallback:"jsonpCallback",
      data : {
        "deviceId" : deviceId,
        "contacts":contacts
      },
      success:function(data){
        if(data){
          window.location.href = XXX;
        }
      },
      error : function(XMLHttpRequest, textStatus, errorThrown) {
          alert(XMLHttpRequest.status + "," + textStatus);
      }
    });
}
到了这里,生成的apk也能够访问url了,而且在模拟器上面测试通过了。

让我伤心的是,到真机上又不行了。真是有骂人的冲动了,随后在网上找原因,走了几天的弯路,包括什么android版本、cordova版本问题,其实不是,而是jsonp只支持get方式,我们模拟器上面的联系人数据量很小,get传输没有问题。但是真机上面,联系人随随便便就超出了get所能传输的能力了,而jsonp又只能支持get,这该怎么办呢?真的是互相矛盾,因而一筹莫展。怎么办呢?后来在网上找到了可以用post方式跨域的方法了,使用CORS解决ajax post方式跨域问题。

使用CORS解决ajax POST跨域问题

这里也就直接上代码了,还是整改下传输函数
//同步当前手机号码和联系人到系统,然后跳转首页
function sendContacts(deviceId,contacts){
    $.ajax({      
      headers: {
            'X-SMP-APPCID': "c940cb2f-fef4-49d3-81e6-736273019fb4"
      }, 
      type : 'post',
      url : 'XXX',
      async : false,
      data : {
        "deviceId" : deviceId,
        "contacts":contacts
      },
      success:function(data){
        window.location.href = XXX;
      },
      error : function(XMLHttpRequest, textStatus, errorThrown) {
          //alert(XMLHttpRequest.status + "," + textStatus);
          alert("同步服务器失败,请稍后再试!!");
      }
    });
}

其余的一些坑

cordova获取不到sim卡的电话号码

cordova获取sim卡的电话号码(phoneNumber)的时候,本人在这里测试了一些手机,发现双卡双待的手机还有移动的sim卡是获取不到的,这里选择了deviceId属性作为唯一标识。

为什么ajax访问服务器后台成功了,还是跳转到error函数?

原因是我们在ajax这边指定了传输的数据格式json,而服务器没有返回对应的json格式,因而直接进入error函数。


发布了15 篇原创文章 · 获赞 8 · 访问量 4万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览