美文网首页ionic2
自定义cordova插件-进阶

自定义cordova插件-进阶

作者: 昵称已被使用_ | 来源:发表于2018-02-13 16:32 被阅读643次

    前言

    运行高德定位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
    

    相关文章

      网友评论

      • _听风细雨:大神你好,我想请问一下ionic3打包以后一直显示白屏是因为什么
        8ab87127b427:ionic cordova run android --prod 你用这个命令编译能解决你的问题

      本文标题:自定义cordova插件-进阶

      本文链接:https://www.haomeiwen.com/subject/ildjtftx.html