前言
本章是上一章自定義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
- 本插件已上傳至github