使用plugman開發(fā)cordova 高德地圖定位插件

在開發(fā)的過程中我們更多的是使用別人開發(fā)的cordova插件,但是在使用的過程中經(jīng)常會遇到一些不合自己心意的問題,那么我們就來使用plugman開發(fā)一個屬于自己的cordova插件吧。
源碼地址 : https://github.com/DaiHuaXieHuaKai/GaoDeLocation.git
下面就以開發(fā)一個高德地圖的定位插件為例:

第一步:檢查是否具備開發(fā)環(huán)境

檢查是否有cordova和plugman的環(huán)境
分別執(zhí)行cordova -v和plugman -v查看是否有版本號出現(xiàn),如果沒有安裝這兩個環(huán)境請按照以下步驟安裝:
安裝crodva和plugman都需要使用nodejs的npm管理工具,所以我們先要安裝nodejs,nodejs下載地址,下載安裝后執(zhí)行npm -v出現(xiàn)版本號即安裝成功。

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

然后分別執(zhí)行cordova -v和plugman -v檢查是否環(huán)境搭建成功。

第二步:使用plugman創(chuàng)建插件模板

//創(chuàng)建插件 (GaoDeLocation為插件名稱, com.zhaoying.GaoDeLocation為插件id
plugman create --name GaoDeLocation --plugin_id com.zhaoying.GaoDeLocation--plugin_version 1.0.0

//進(jìn)入GaoDeLocation 目錄
cd GaoDeLocation 

//為插件添加android平臺(此處只添加了安卓,如果要開發(fā)ios插件請執(zhí)行plugman platform add --platform_name ios)
plugman platform add --platform_name android

模板創(chuàng)建成功后目錄格式如下:


這里寫圖片描述

第三步:修改配置模板

元素 描述
id 插件id,創(chuàng)建插件的時候設(shè)定,該id可用于添加插件,如:cordova plugin add com.zhaoying.GaoDeLocation
name 插件名稱
js-module 這里指定clobbers ,然后通過它來調(diào)用GaoDeLocation.js,此處應(yīng)該對應(yīng)GaoDeLocation.js中exports的對象
preference 指定參數(shù),比如這里設(shè)定了API_KEY這個參數(shù),在添加插件的時候就必須加上--variable API_KEY=your key
config-file 這里主要是填寫一些配置信息,比如高德定位的獲取定位權(quán)限等等
source-file 用于指定引用的libs的資源和路徑

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

元素 描述
id 插件id,創(chuàng)建插件的時候設(shè)定,該id可用于添加插件,如:cordova plugin add com.zhaoying.GaoDeLocation
name 插件名稱
js-module 這里指定clobbers ,然后通過它來調(diào)用GaoDeLocation.js,此處應(yīng)該對應(yīng)GaoDeLocation.js中exports的對象
preference 指定參數(shù),比如這里設(shè)定了API_KEY這個參數(shù),在添加插件的時候就必須加上--variable API_KEY=your key
config-file 這里主要是填寫一些配置信息,比如高德定位的獲取定位權(quán)限等等
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>

        <!--以下配置完全按照高德的指南進(jìn)行配置,詳見:http://lbs.amap.com/api/android-location-sdk/gettingstarted/-->
        <config-file target="AndroidManifest.xml" parent="/manifest/application">
            <!--在AndroidManifest.xml的application標(biāo)簽中配置Key:-->
            <meta-data android:name="com.amap.api.v2.apikey" android:value="$API_KEY">
            </meta-data>
            <!--在application標(biāo)簽中聲明service組件:-->
            <service android:name="com.amap.api.location.APSService"></service>
        </config-file>

        <config-file parent="/*" target="AndroidManifest.xml">
            <!--用于進(jìn)行網(wǎng)絡(luò)定位-->
            <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
            <!--用于訪問GPS定位-->
            <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
            <!--獲取運(yùn)營商信息,用于支持提供運(yùn)營商信息相關(guān)的接口-->
            <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
            <!--用于訪問wifi網(wǎng)絡(luò)信息,wifi信息會用于進(jìn)行網(wǎng)絡(luò)定位-->
            <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
            <!--這個權(quán)限用于獲取wifi的獲取權(quán)限,wifi信息會用來進(jìn)行網(wǎng)絡(luò)定位-->
            <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
            <!--用于訪問網(wǎng)絡(luò),網(wǎng)絡(luò)定位需要上網(wǎng)-->
            <uses-permission android:name="android.permission.INTERNET"></uses-permission>
            <!--用于讀取手機(jī)當(dāng)前的狀態(tài)-->
            <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
            <!--寫入擴(kuò)展存儲,向擴(kuò)展卡寫入數(shù)據(jù),用于寫入緩存定位數(shù)據(jù)-->
            <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
            <!--用于申請調(diào)用A-GPS模塊-->
            <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission>
            <!--用于申請獲取藍(lán)牙信息進(jìn)行室內(nèi)定位-->
            <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包引入插件項(xiàng)目,這里需要我們在插件項(xiàng)目中創(chuàng)建一個libs文件夾來放jar包,最終結(jié)構(gòu)如下:

這里寫圖片描述

然后我們先要修改GaoDeLocation.js文件,將其修改為:

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

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

module.exports = GaoDe;

然后我們需要修改GaoDeLocation.java文件,修改為:(具體的方法可以參照官方demo進(jìn)行添加或修改)

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;
    //聲明定位參數(shù)
    public AMapLocationClientOption locationOption = null;
    /**
     * JS回調(diào)接口對象
     */
    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());
        //設(shè)置定位參數(shù)
        locationClient.setLocationOption(getDefaultOption());
        // 設(shè)置定位監(jiān)聽
        locationClient.setLocationListener(locationListener);
    }

    /**
     * 默認(rèn)的定位參數(shù)
     *
     * @author zhaoying
     */
    private AMapLocationClientOption getDefaultOption() {
        AMapLocationClientOption mOption = new AMapLocationClientOption();
        mOption.setLocationMode(AMapLocationMode.Hight_Accuracy);//可選,設(shè)置定位模式,可選的模式有高精度、僅設(shè)備、僅網(wǎng)絡(luò)。默認(rèn)為高精度模式
        mOption.setGpsFirst(false);//可選,設(shè)置是否gps優(yōu)先,只在高精度模式下有效。默認(rèn)關(guān)閉
        mOption.setHttpTimeOut(30000);//可選,設(shè)置網(wǎng)絡(luò)請求超時時間。默認(rèn)為30秒。在僅設(shè)備模式下無效
        mOption.setInterval(2000);//可選,設(shè)置定位間隔。默認(rèn)為2秒
        mOption.setNeedAddress(true);//可選,設(shè)置是否返回逆地理地址信息。默認(rèn)是true
        mOption.setOnceLocation(false);//可選,設(shè)置是否單次定位。默認(rèn)是false
        mOption.setOnceLocationLatest(false);//可選,設(shè)置是否等待wifi刷新,默認(rèn)為false.如果設(shè)置為true,會自動變?yōu)閱未味ㄎ?,持續(xù)定位時不要使用
        AMapLocationClientOption.setLocationProtocol(AMapLocationProtocol.HTTP);//可選, 設(shè)置網(wǎng)絡(luò)請求的協(xié)議??蛇xHTTP或者HTTPS。默認(rèn)為HTTP
        mOption.setSensorEnable(false);//可選,設(shè)置是否使用傳感器。默認(rèn)是false
        mOption.setWifiScan(true); //可選,設(shè)置是否開啟wifi掃描。默認(rèn)為true,如果設(shè)置為false會同時停止主動刷新,停止以后完全依賴于系統(tǒng)刷新,定位位置可能存在誤差
        mOption.setLocationCacheEnable(true); //可選,設(shè)置是否使用緩存定位,默認(rèn)為true
        return mOption;
    }

    /**
     * 定位監(jiān)聽
     */
    AMapLocationListener locationListener = new AMapLocationListener() {
        @Override
        public void onLocationChanged(AMapLocation location) {
            try {
                JSONObject json = new JSONObject();
                if (null != location) {
                    //解析定位結(jié)果
                    //errCode等于0代表定位成功,其他的為定位失敗,具體的可以參照官網(wǎng)定位錯誤碼說明
                    if (location.getErrorCode() == 0) {
                        json.put("status", "定位成功");
                        //定位類型
                        json.put("type", location.getLocationType());
                        //緯度
                        json.put("latitude", location.getLatitude());
                        //經(jīng)度
                        json.put("longitude", location.getLongitude());
                        //精度
                        json.put("accuracy", location.getAccuracy());
                        //角度
                        json.put("bearing", location.getBearing());
                        // 獲取當(dāng)前提供定位服務(wù)的衛(wèi)星個數(shù)
                        //星數(shù)
                        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());
                        //區(qū)
                        json.put("district", location.getDistrict());
                        //區(qū)域碼
                        json.put("adcode", location.getAdCode());
                        //地址
                        json.put("address", location.getAddress());
                        //興趣點(diǎn)
                        json.put("poi", location.getPoiName());
                        //興趣點(diǎn)
                        json.put("time", location.getTime());
                    } else {
                        json.put("status", "定位失敗");
                        json.put("errcode", location.getErrorCode());
                        json.put("errinfo", location.getErrorInfo());
                        json.put("detail", location.getLocationDetail());
                    }
                    //定位之后的回調(diào)時間
                    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是在當(dāng)前Activity實(shí)例化的,
             * 在Activity的onDestroy中一定要執(zhí)行AMapLocationClient的onDestroy
             */
            locationClient.onDestroy();
            locationClient = null;
            locationOption = null;
        }
    }

}

第五步:添加插件,調(diào)用定位

首先新建一個ionic項(xiàng)目(具體方法參照ionic官網(wǎng)文檔)
項(xiàng)目新建完成后,添加剛剛新建完成的插件:

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

這里需要用到API_KEY,該key需要在高德地圖的控制臺去申請,具體參照

添加完成后就可以在頁面中調(diào)用定位方法了:

    GaoDe.getCurrentPosition(function (success) {
      console.log(success);
    },function (error) {
      console.log(error)
    })
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容