自定義cordova插件-進(jìn)階

前言

  • 本章是上一章自定義cordova插件-入門的續(xù)篇,沒有閱讀上一章的請(qǐng)移步

  • 本章需要在com.kit.cordova.nativeLocation插件上添加高德定位功能.所以請(qǐng)務(wù)必了解一下高德android定位sdk.需要閱讀的內(nèi)容如下

運(yùn)行高德定位demo

  • 本步可省略

  • 沒什么android開發(fā)經(jīng)驗(yàn)?沒事.下載demo,照貓畫虎也能做出來

  • 下載完解壓,找到AMapLocationDemo.用Studio打開,注意整個(gè)項(xiàng)目路徑不要有中文

  • 點(diǎn)擊刷新,然后在真機(jī)上運(yùn)行,可以看到許多定位demo,然后再對(duì)照著源碼學(xué)習(xí)

項(xiàng)目中添加定位功能

  • 用Studio打開android項(xiàng)目.你的app項(xiàng)目>platforms>android目錄

  • 根據(jù)官網(wǎng)文檔,定位功能只需要添加jar就行了

  • 解壓剛剛下載的AMapLocation.zip得到定位jar如下圖

  • 拷貝jar到Studio libs目錄,如下圖,拷貝完成記得刷新一下gradle

  • 在高德開發(fā)者控制臺(tái),給應(yīng)用申請(qǐng)app key.發(fā)布版和調(diào)試版的SHA1值都填debug版本的.如下圖,點(diǎn)擊提交就會(huì)生成一個(gè)android定位key.

關(guān)于申請(qǐng)key這里有更詳細(xì)介紹

  • 參考官網(wǎng)獲取定位數(shù)據(jù)小節(jié)給項(xiàng)目添加其他配置
  • AndroidManifest.xml中的<application>節(jié)點(diǎn)下配置service和key,如下圖
 <service android:name="com.amap.api.location.APSService"></service>
 <meta-data android:name="com.amap.api.v2.apikey" android:value="e36b642d723fd530a960eb1c5cf38953"/>
  • 然后在AndroidManifest.xml中的<manifest>節(jié)點(diǎn)下配置權(quán)限和app使用的sdk版本,如下圖

由于sdk版本大于23以上的app要?jiǎng)討B(tài)申請(qǐng)定位權(quán)限,所以這里使用sdk版本為22.默認(rèn)有app需要的所有權(quán)限

 <!--用于進(jìn)行網(wǎng)絡(luò)定位-->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  <!--用于訪問GPS定位-->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  <!--用于獲取運(yùn)營(yíng)商信息,用于支持提供運(yùn)營(yíng)商信息相關(guān)的接口-->
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  <!--用于訪問wifi網(wǎng)絡(luò)信息,wifi信息會(huì)用于進(jìn)行網(wǎng)絡(luò)定位-->
  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
  <!--用于獲取wifi的獲取權(quán)限,wifi信息會(huì)用來進(jìn)行網(wǎng)絡(luò)定位-->
  <!--用于訪問網(wǎng)絡(luò),網(wǎng)絡(luò)定位需要上網(wǎng)-->
  <uses-permission android:name="android.permission.INTERNET"/>
  <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
  <!--用于讀取手機(jī)當(dāng)前的狀態(tài)-->
  <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
  <!--用于寫入緩存數(shù)據(jù)到擴(kuò)展存儲(chǔ)卡-->
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <!--用于申請(qǐng)調(diào)用A-GPS模塊-->
  <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
  <!--用于申請(qǐng)獲取藍(lán)牙信息進(jìn)行室內(nèi)定位-->
  <uses-permission android:name="android.permission.BLUETOOTH"/>
  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
  <!--<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="25"/>-->
  <uses-sdk android:maxSdkVersion="22" android:minSdkVersion="16" android:targetSdkVersion="22" />
  • 找到NativeLocation.java文件實(shí)現(xiàn)定位功能,完整代碼已在下面貼出
package com.kit.cordova.nativeLocation;

import android.content.Context;
import android.util.Log;

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

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

import org.apache.cordova.CordovaWebView;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class NativeLocation extends CordovaPlugin {

  CallbackContext callbackContext = null;

  //聲明AMapLocationClient類對(duì)象
  AMapLocationClient mLocationClient = null;

  //聲明定位回調(diào)監(jiān)聽器
  AMapLocationListener mLocationListener = new AMapLocationListener() {
    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
      if (aMapLocation != null) {
        if (aMapLocation.getErrorCode() == 0) {
          int locationType = aMapLocation.getLocationType();//獲取當(dāng)前定位結(jié)果來源 定位類型對(duì)照表: http://lbs.amap.com/api/android-location-sdk/guide/utilities/location-type/
          Double latitude = aMapLocation.getLatitude();//獲取緯度
          Double longitude = aMapLocation.getLongitude();//獲取經(jīng)度
          JSONObject jo = new JSONObject();
          try {
            jo.put("locationType", locationType);
            jo.put("latitude", latitude);
            jo.put("longitude", longitude);
          } catch (JSONException e) {
            jo = null;
            e.printStackTrace();
          }
          Log.w("定位成功:", jo.toString());
          callbackContext.success(jo);
        } else {
          // 錯(cuò)誤碼對(duì)照表 http://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode/
          Log.e("定位失敗錯(cuò)誤碼:", aMapLocation.getAdCode());
          Log.e("定位失敗信息:", aMapLocation.getErrorInfo());
          callbackContext.error(aMapLocation.getErrorCode());
        }
      }
    }
  };

  @Override
  public void initialize(CordovaInterface cordova, CordovaWebView webView) {
    super.initialize(cordova, webView);
    Context context = this.cordova.getActivity().getApplicationContext();
    mLocationClient = new AMapLocationClient(context);
    mLocationClient.setLocationListener(mLocationListener);
    AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
    mLocationOption.setLocationPurpose(AMapLocationClientOption.AMapLocationPurpose.SignIn);// 使用簽到定位場(chǎng)景
    mLocationClient.setLocationOption(mLocationOption); // 設(shè)置定位參數(shù)
  }

  @Override
  public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
    this.callbackContext = callbackContext;
    if (action.equals("coolMethod")) {
      // 設(shè)置場(chǎng)景模式后最好調(diào)用一次stop,再調(diào)用start以保證場(chǎng)景模式生效
      mLocationClient.stopLocation();
      mLocationClient.startLocation(); // 啟動(dòng)定位
      PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
      r.setKeepCallback(true);
      callbackContext.sendPluginResult(r);
      return true;
    }
    return false;
  }
}

調(diào)試

  • 刷新項(xiàng)目,給成功失敗回調(diào)函數(shù)均打上斷點(diǎn).點(diǎn)擊debug調(diào)試按鈕

  • 點(diǎn)擊app頁面上的按鈕,在Studio控制臺(tái)看到定位日志.

  • 這里有定位錯(cuò)誤碼對(duì)照表,常見錯(cuò)誤有:

定位key配置錯(cuò)誤或key在AndroidManifest.xml文件位置不正確

app沒有定位權(quán)限,日志如下,錯(cuò)誤碼為12.設(shè)置sdk版本為22或者手動(dòng)在系統(tǒng)設(shè)置中打開app定位權(quán)限

  • 在chrome下調(diào)試,可以看到成功獲取到坐標(biāo)信息


  • 此時(shí)我們的定位功能開發(fā)完成

插件集成

  • 拷貝定位jar到插件目錄下.復(fù)制Studio的NativeLocation.java內(nèi)容到webstorm插件NativeLocation.java文件中

  • 修改插件的plugin.xml

<?xml version='1.0' encoding='utf-8'?>
<plugin id="com.kit.cordova.nativeLocation" version="0.0.1" xmlns="http://apache.org/cordova/ns/plugins/1.0"
        xmlns:android="http://schemas.android.com/apk/res/android">
  <name>nativeLocation</name>
  <js-module name="nativeLocation" src="www/nativeLocation.js">
    <clobbers target="cordova.plugins.nativeLocation"/>
  </js-module>
  <platform name="android">
    <config-file parent="/*" target="res/xml/config.xml">
      <feature name="nativeLocation">
        <!--這里的value是包名加類名-->
        <param name="android-package" value="com.kit.cordova.nativeLocation.NativeLocation"/>
      </feature>
    </config-file>

    <config-file target="AndroidManifest.xml" parent="/manifest">
      <!--用于進(jìn)行網(wǎng)絡(luò)定位-->
      <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
      <!--用于訪問GPS定位-->
      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
      <!--用于獲取運(yùn)營(yíng)商信息,用于支持提供運(yùn)營(yíng)商信息相關(guān)的接口-->
      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
      <!--用于訪問wifi網(wǎng)絡(luò)信息,wifi信息會(huì)用于進(jìn)行網(wǎng)絡(luò)定位-->
      <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
      <!--用于獲取wifi的獲取權(quán)限,wifi信息會(huì)用來進(jìn)行網(wǎng)絡(luò)定位-->
      <!--用于訪問網(wǎng)絡(luò),網(wǎng)絡(luò)定位需要上網(wǎng)-->
      <uses-permission android:name="android.permission.INTERNET"/>
      <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
      <!--用于讀取手機(jī)當(dāng)前的狀態(tài)-->
      <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
      <!--用于寫入緩存數(shù)據(jù)到擴(kuò)展存儲(chǔ)卡-->
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
      <!--用于申請(qǐng)調(diào)用A-GPS模塊-->
      <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
      <!--用于申請(qǐng)獲取藍(lán)牙信息進(jìn)行室內(nèi)定位-->
      <uses-permission android:name="android.permission.BLUETOOTH"/>
      <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    </config-file>

    <config-file target="AndroidManifest.xml" parent="/manifest/application">
      <!-- 定位需要的key -->
      <meta-data android:name="com.amap.api.v2.apikey" android:value="e36b642d723fd530a960eb1c5cf38966"/> 這里填你的key,哈哈
      <!-- 定位需要的服務(wù) -->
      <service android:name="com.amap.api.location.APSService" />
    </config-file>
    <source-file src="src/android/NativeLocation.java" target-dir="src/com/kit/cordova/nativeLocation"/>
    <source-file src="src/android/AMap_Location_V3.7.0_20171218.jar" target-dir="libs"/>
  </platform>
</plugin>
  • 修改config.xml指定sdk版本.
  <preference name="android-minSdkVersion" value="16"/>
  <preference name="android-maxSdkVersion" value="22"/>
  <preference name="android-targetSdkVersion" value="22"/>
  • 插件修改完畢,備份一下android項(xiàng)目.用cordova命令打包運(yùn)行
 cordova platform rm android
 cordova platform add android
 cordova run android
  • 在chrome調(diào)試看是否能輸出坐標(biāo)信息.如果不能輸出,請(qǐng)?jiān)赟tudio控制臺(tái)看日志

插件優(yōu)化

  • 優(yōu)化1.修改coolMethod函數(shù)名為getLocation
exports.getLocation = function (success, error) {
  exec(success, error, 'nativeLocation', 'getLocation');
};

  click(){
    // getLocation只有兩個(gè)參數(shù)了
    cordova.plugins.nativeLocation.getLocation(res => {
      console.log(res);
    }, err => {
      console.log(err);
    })
  }
  • 優(yōu)化2.把高德定位的key作為參數(shù).如下圖添加<preference name="API_KEY"/>

  • 拷貝插件到某目錄下,如我放在D盤根目錄

  • 項(xiàng)目中刪除插件并重新安裝插件,重新安裝需要帶參數(shù)API_KEY

cordova plugin rm com.kit.cordova.nativeLocation
cordova plugin add D:\com.kit.cordova.nativeLocation --variable API_KEY=e36b642d723fd530a960eb1c5cf38953
  • 打包運(yùn)行并調(diào)試,效果如下gif,能夠獲取到位置,插件全部開發(fā)完成
 cordova platform rm android
 cordova platform add android
 cordova run android
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容