自定义cordova插件-进阶

前言

运行高德定位demo

  • 本步可省略

  • 没什么android开发经验?没事.下载demo,照猫画虎也能做出来

  • 下载完解压,找到AMapLocationDemo.用Studio打开,注意整个项目路径不要有中文

  • 点击刷新,然后在真机上运行,可以看到许多定位demo,然后再对照着源码学习

项目中添加定位功能

  • 用Studio打开android项目.你的app项目>platforms>android目录

  • 根据官网文档,定位功能只需要添加jar就行了

  • 解压刚刚下载的AMapLocation.zip得到定位jar如下图

  • 拷贝jar到Studio libs目录,如下图,拷贝完成记得刷新一下gradle

  • 在高德开发者控制台,给应用申请app key.发布版和调试版的SHA1值都填debug版本的.如下图,点击提交就会生成一个android定位key.

关于申请key这里有更详细介绍

  • 参考官网获取定位数据小节给项目添加其他配置
  • AndroidManifest.xml中的<application>节点下配置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>节点下配置权限和app使用的sdk版本,如下图

由于sdk版本大于23以上的app要动态申请定位权限,所以这里使用sdk版本为22.默认有app需要的所有权限

 <!--用于进行网络定位-->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  <!--用于访问GPS定位-->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  <!--用于获取运营商信息,用于支持提供运营商信息相关的接口-->
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  <!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
  <!--用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
  <!--用于访问网络,网络定位需要上网-->
  <uses-permission android:name="android.permission.INTERNET"/>
  <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
  <!--用于读取手机当前的状态-->
  <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
  <!--用于写入缓存数据到扩展存储卡-->
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <!--用于申请调用A-GPS模块-->
  <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
  <!--用于申请获取蓝牙信息进行室内定位-->
  <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文件实现定位功能,完整代码已在下面贴出
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类对象
  AMapLocationClient mLocationClient = null;

  //声明定位回调监听器
  AMapLocationListener mLocationListener = new AMapLocationListener() {
    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
      if (aMapLocation != null) {
        if (aMapLocation.getErrorCode() == 0) {
          int locationType = aMapLocation.getLocationType();//获取当前定位结果来源 定位类型对照表: http://lbs.amap.com/api/android-location-sdk/guide/utilities/location-type/
          Double latitude = aMapLocation.getLatitude();//获取纬度
          Double longitude = aMapLocation.getLongitude();//获取经度
          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 {
          // 错误码对照表 http://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode/
          Log.e("定位失败错误码:", 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);// 使用签到定位场景
    mLocationClient.setLocationOption(mLocationOption); // 设置定位参数
  }

  @Override
  public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
    this.callbackContext = callbackContext;
    if (action.equals("coolMethod")) {
      // 设置场景模式后最好调用一次stop,再调用start以保证场景模式生效
      mLocationClient.stopLocation();
      mLocationClient.startLocation(); // 启动定位
      PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
      r.setKeepCallback(true);
      callbackContext.sendPluginResult(r);
      return true;
    }
    return false;
  }
}

调试

  • 刷新项目,给成功失败回调函数均打上断点.点击debug调试按钮

  • 点击app页面上的按钮,在Studio控制台看到定位日志.

  • 这里有定位错误码对照表,常见错误有:

定位key配置错误或key在AndroidManifest.xml文件位置不正确

app没有定位权限,日志如下,错误码为12.设置sdk版本为22或者手动在系统设置中打开app定位权限

  • 在chrome下调试,可以看到成功获取到坐标信息


  • 此时我们的定位功能开发完成

插件集成

  • 拷贝定位jar到插件目录下.复制Studio的NativeLocation.java内容到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">
      <!--用于进行网络定位-->
      <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
      <!--用于访问GPS定位-->
      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
      <!--用于获取运营商信息,用于支持提供运营商信息相关的接口-->
      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
      <!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
      <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
      <!--用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
      <!--用于访问网络,网络定位需要上网-->
      <uses-permission android:name="android.permission.INTERNET"/>
      <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
      <!--用于读取手机当前的状态-->
      <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
      <!--用于写入缓存数据到扩展存储卡-->
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
      <!--用于申请调用A-GPS模块-->
      <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
      <!--用于申请获取蓝牙信息进行室内定位-->
      <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,哈哈
      <!-- 定位需要的服务 -->
      <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项目.用cordova命令打包运行
 cordova platform rm android
 cordova platform add android
 cordova run android
  • 在chrome调试看是否能输出坐标信息.如果不能输出,请在Studio控制台看日志

插件优化

  • 优化1.修改coolMethod函数名为getLocation
exports.getLocation = function (success, error) {
  exec(success, error, 'nativeLocation', 'getLocation');
};

  click(){
    // getLocation只有两个参数了
    cordova.plugins.nativeLocation.getLocation(res => {
      console.log(res);
    }, err => {
      console.log(err);
    })
  }
  • 优化2.把高德定位的key作为参数.如下图添加<preference name="API_KEY"/>

  • 拷贝插件到某目录下,如我放在D盘根目录

  • 项目中删除插件并重新安装插件,重新安装需要带参数API_KEY

cordova plugin rm com.kit.cordova.nativeLocation
cordova plugin add D:\com.kit.cordova.nativeLocation --variable API_KEY=e36b642d723fd530a960eb1c5cf38953
  • 打包运行并调试,效果如下gif,能够获取到位置,插件全部开发完成
 cordova platform rm android
 cordova platform add android
 cordova run android
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容