使用plugman开发cordova 高德地图定位插件

在开发的过程中我们更多的是使用别人开发的cordova插件,但是在使用的过程中经常会遇到一些不合自己心意的问题,那么我们就来使用plugman开发一个属于自己的cordova插件吧。
源码地址 : https://github.com/DaiHuaXieHuaKai/GaoDeLocation.git
下面就以开发一个高德地图的定位插件为例:

第一步:检查是否具备开发环境

检查是否有cordova和plugman的环境
分别执行cordova -v和plugman -v查看是否有版本号出现,如果没有安装这两个环境请按照以下步骤安装:
安装crodva和plugman都需要使用nodejs的npm管理工具,所以我们先要安装nodejs,nodejs下载地址,下载安装后执行npm -v出现版本号即安装成功。

安装cordova:
npm install -g cordova
安装plugman:
npm install -g plugman

然后分别执行cordova -v和plugman -v检查是否环境搭建成功。

第二步:使用plugman创建插件模板

//创建插件 (GaoDeLocation为插件名称, com.zhaoying.GaoDeLocation为插件id
plugman create --name GaoDeLocation --plugin_id com.zhaoying.GaoDeLocation--plugin_version 1.0.0

//进入GaoDeLocation 目录
cd GaoDeLocation 

//为插件添加android平台(此处只添加了安卓,如果要开发ios插件请执行plugman platform add --platform_name ios)
plugman platform add --platform_name android

模板创建成功后目录格式如下:


这里写图片描述

第三步:修改配置模板

元素 描述
id 插件id,创建插件的时候设定,该id可用于添加插件,如:cordova plugin add com.zhaoying.GaoDeLocation
name 插件名称
js-module 这里指定clobbers ,然后通过它来调用GaoDeLocation.js,此处应该对应GaoDeLocation.js中exports的对象
preference 指定参数,比如这里设定了API_KEY这个参数,在添加插件的时候就必须加上--variable API_KEY=your key
config-file 这里主要是填写一些配置信息,比如高德定位的获取定位权限等等
source-file 用于指定引用的libs的资源和路径

1、修改plugin.xml
plugin.xml的配置非常重要,以下是几个重要的地方:

元素 描述
id 插件id,创建插件的时候设定,该id可用于添加插件,如:cordova plugin add com.zhaoying.GaoDeLocation
name 插件名称
js-module 这里指定clobbers ,然后通过它来调用GaoDeLocation.js,此处应该对应GaoDeLocation.js中exports的对象
preference 指定参数,比如这里设定了API_KEY这个参数,在添加插件的时候就必须加上--variable API_KEY=your key
config-file 这里主要是填写一些配置信息,比如高德定位的获取定位权限等等
source-file 用于指定引用的libs的资源和路径

我们修改后的plugin.xml如下:

<?xml version='1.0' encoding='utf-8'?>
<plugin id="com.zhaoying.GaoDeLocation" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0"
        xmlns:android="http://schemas.android.com/apk/res/android">
    <name>GaoDeLocation</name>
    <js-module name="GaoDe" src="www/GaoDeLocation.js">
        <clobbers target="GaoDe"/>
    </js-module>
    <preference name="API_KEY" />
    <platform name="android">
        <config-file parent="/*" target="res/xml/config.xml">
            <feature name="GaoDeLocation">
                <param name="android-package" value="com.zhaoying.GaoDeLocation.GaoDeLocation"/>
            </feature>
        </config-file>

        <!--以下配置完全按照高德的指南进行配置,详见:http://lbs.amap.com/api/android-location-sdk/gettingstarted/-->
        <config-file target="AndroidManifest.xml" parent="/manifest/application">
            <!--在AndroidManifest.xml的application标签中配置Key:-->
            <meta-data android:name="com.amap.api.v2.apikey" android:value="$API_KEY">
            </meta-data>
            <!--在application标签中声明service组件:-->
            <service android:name="com.amap.api.location.APSService"></service>
        </config-file>

        <config-file parent="/*" target="AndroidManifest.xml">
            <!--用于进行网络定位-->
            <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
            <!--用于访问GPS定位-->
            <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
            <!--获取运营商信息,用于支持提供运营商信息相关的接口-->
            <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
            <!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
            <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
            <!--这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
            <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
            <!--用于访问网络,网络定位需要上网-->
            <uses-permission android:name="android.permission.INTERNET"></uses-permission>
            <!--用于读取手机当前的状态-->
            <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
            <!--写入扩展存储,向扩展卡写入数据,用于写入缓存定位数据-->
            <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
            <!--用于申请调用A-GPS模块-->
            <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission>
            <!--用于申请获取蓝牙信息进行室内定位-->
            <uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
            <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission>
        </config-file>
        <source-file src="src/android/GaoDeLocation.java" target-dir="src/com/zhaoying/GaoDeLocation"/>
        <source-file src="libs/android/AMap_Location_V3.3.0.jar" target-dir="libs" />
    </platform>
</plugin>

此处我们要注意需要将:

  <source-file src="src/android/GaoDeLocation.java" target-dir="src/com/zhaoying/GaoDeLocation/GaoDeLocation"/>

修改为:

        <source-file src="src/android/GaoDeLocation.java" target-dir="src/com/zhaoying/GaoDeLocation"/>

如果不修改的话会找不到GaoDeLocation.js.

第四步:添加高德SDK,修改GaoDeLocation.js

首先在http://lbs.amap.com/api/android-location-sdk/download/下载需要用到的jar包,这里我们只需要下载定位的jar即可。
下载完成后将其解压,并将jar包引入插件项目,这里需要我们在插件项目中创建一个libs文件夹来放jar包,最终结构如下:

这里写图片描述

然后我们先要修改GaoDeLocation.js文件,将其修改为:

var exec = require('cordova/exec');

var GaoDe = {
    getCurrentPosition:function (successFn,errorFn) {
        exec(successFn,errorFn,'GaoDeLocation','getCurrentPosition',[]);
    }
};

module.exports = GaoDe;

然后我们需要修改GaoDeLocation.java文件,修改为:(具体的方法可以参照官方demo进行添加或修改)

package com.zhaoying.GaoDeLocation;

import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.PluginResult;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;


import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationClientOption.AMapLocationMode;
import com.amap.api.location.AMapLocationClientOption.AMapLocationProtocol;
import com.amap.api.location.AMapLocationListener;

/**
 * @author zhaoying
 */
public class GaoDeLocation extends CordovaPlugin {
    //声明AMapLocationClient类对象
    public AMapLocationClient locationClient = null;
    //声明定位参数
    public AMapLocationClientOption locationOption = null;
    /**
     * JS回调接口对象
     */
    public static CallbackContext cb = null;

    /*
    * 程序入口
    * */
    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if (action.equals("getCurrentPosition")) {
            cb = callbackContext;
            PluginResult pluginResult = new PluginResult(PluginResult.Status.NO_RESULT);
            pluginResult.setKeepCallback(true);
            cb.sendPluginResult(pluginResult);
            this.getCurrentPosition();
            return true;
        }
        return false;
    }
    /**
     * 获取定位
     *
     * @author zhaoying
     */
    private void getCurrentPosition() {
        if (locationClient == null) {
            this.initLocation();
        }
        this.startLocation();
    }


    /**
     * 初始化定位
     *
     * @author zhaoying
     */
    private void initLocation() {
        //初始化client
        locationClient = new AMapLocationClient(this.webView.getContext());
        //设置定位参数
        locationClient.setLocationOption(getDefaultOption());
        // 设置定位监听
        locationClient.setLocationListener(locationListener);
    }

    /**
     * 默认的定位参数
     *
     * @author zhaoying
     */
    private AMapLocationClientOption getDefaultOption() {
        AMapLocationClientOption mOption = new AMapLocationClientOption();
        mOption.setLocationMode(AMapLocationMode.Hight_Accuracy);//可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        mOption.setGpsFirst(false);//可选,设置是否gps优先,只在高精度模式下有效。默认关闭
        mOption.setHttpTimeOut(30000);//可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.setInterval(2000);//可选,设置定位间隔。默认为2秒
        mOption.setNeedAddress(true);//可选,设置是否返回逆地理地址信息。默认是true
        mOption.setOnceLocation(false);//可选,设置是否单次定位。默认是false
        mOption.setOnceLocationLatest(false);//可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用
        AMapLocationClientOption.setLocationProtocol(AMapLocationProtocol.HTTP);//可选, 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
        mOption.setSensorEnable(false);//可选,设置是否使用传感器。默认是false
        mOption.setWifiScan(true); //可选,设置是否开启wifi扫描。默认为true,如果设置为false会同时停止主动刷新,停止以后完全依赖于系统刷新,定位位置可能存在误差
        mOption.setLocationCacheEnable(true); //可选,设置是否使用缓存定位,默认为true
        return mOption;
    }

    /**
     * 定位监听
     */
    AMapLocationListener locationListener = new AMapLocationListener() {
        @Override
        public void onLocationChanged(AMapLocation location) {
            try {
                JSONObject json = new JSONObject();
                if (null != location) {
                    //解析定位结果
                    //errCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明
                    if (location.getErrorCode() == 0) {
                        json.put("status", "定位成功");
                        //定位类型
                        json.put("type", location.getLocationType());
                        //纬度
                        json.put("latitude", location.getLatitude());
                        //经度
                        json.put("longitude", location.getLongitude());
                        //精度
                        json.put("accuracy", location.getAccuracy());
                        //角度
                        json.put("bearing", location.getBearing());
                        // 获取当前提供定位服务的卫星个数
                        //星数
                        json.put("satellites", location.getSatellites());
                        //国家
                        json.put("country", location.getCountry());
                        //省
                        json.put("province", location.getProvince());
                        //市
                        json.put("city", location.getCity());
                        //城市编码
                        json.put("citycode", location.getCityCode());
                        //区
                        json.put("district", location.getDistrict());
                        //区域码
                        json.put("adcode", location.getAdCode());
                        //地址
                        json.put("address", location.getAddress());
                        //兴趣点
                        json.put("poi", location.getPoiName());
                        //兴趣点
                        json.put("time", location.getTime());
                    } else {
                        json.put("status", "定位失败");
                        json.put("errcode", location.getErrorCode());
                        json.put("errinfo", location.getErrorInfo());
                        json.put("detail", location.getLocationDetail());
                    }
                    //定位之后的回调时间
                    json.put("backtime",System.currentTimeMillis());
                } else {

                }
                PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, json);
                pluginResult.setKeepCallback(true);
                cb.sendPluginResult(pluginResult);
            } catch (JSONException e) {
                PluginResult pluginResult = new PluginResult(PluginResult.Status.ERROR, e.getMessage());
                pluginResult.setKeepCallback(true);
                cb.sendPluginResult(pluginResult);
            } finally {
                locationClient.stopLocation();
            }
        }
    };

    /**
     * 开始定位
     *
     * @author zhaoying
     */
    private void startLocation() {
        // 启动定位
        locationClient.startLocation();
    }

    /**
     * 停止定位
     *
     * @author zhaoying
     */
    private void stopLocation() {
        // 停止定位
        locationClient.stopLocation();
    }

    /**
     * 销毁定位
     *
     * @author zhaoying
     */
    private void destroyLocation() {
        if (null != locationClient) {
            /**
             * 如果AMapLocationClient是在当前Activity实例化的,
             * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
             */
            locationClient.onDestroy();
            locationClient = null;
            locationOption = null;
        }
    }

}

第五步:添加插件,调用定位

首先新建一个ionic项目(具体方法参照ionic官网文档)
项目新建完成后,添加刚刚新建完成的插件:

cordova plugin add C:\Users\HD\GaoDeLocation --variable API_KEY=yourkey

这里需要用到API_KEY,该key需要在高德地图的控制台去申请,具体参照

添加完成后就可以在页面中调用定位方法了:

    GaoDe.getCurrentPosition(function (success) {
      console.log(success);
    },function (error) {
      console.log(error)
    })
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容