前言
本章是上一章自定义cordova插件-入门的续篇,没有阅读上一章的请移步
-
本章需要在
com.kit.cordova.nativeLocation
插件上添加高德定位功能.所以请务必了解一下高德android定位sdk.需要阅读的内容如下
运行高德定位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
- 本插件已上传至github