mui混合开发————获取手机经纬度信息

mui框架针对手机获取经纬度信息,其实做的可以,华为荣耀系列手机以及小米手机可以正常通过

plus.geolocation.getCurrentPosition

进行获取经纬度信息,但对于其他类型手机Android版本为5.1的则会存在不兼容的情况,导致调用上面的代码直接进入失败回调。

针对不同手机型号和系统版本,本宝宝做了个插件,测试还行,但手上机型不多,还请大家广提建议,现在上代码

package com.demo.maps;

import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;

import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import io.dcloud.common.DHInterface.IWebview;
import io.dcloud.common.DHInterface.StandardFeature;
import io.dcloud.common.util.JSUtil;

/**
 * 测试获取手机经纬度信息插件
 * 
 * @author 香蕉不拿拿
 * @date 2018年6月19日 上午9:45:34
 */
public class Get_Longitude_Latitude extends StandardFeature{
	private static final String TAG = "Get_Longitude_Latitude";
	private Location location;
	String callbackid;
	IWebview pWebviews;
	Activity activity;
	// 位置管理器
	LocationManager locationManager;
	private String locationProvider;

	public void getLongitudeAndLatitude(IWebview pWebview, JSONArray array) {
		Log.i("成功进入--->", "getLongitudeAndLatitude");
		pWebviews = pWebview;
		activity = pWebview.getActivity();
		callbackid = array.optString(0);
		JSONArray jsonArray = null;
		try {
			jsonArray = new JSONArray(array.optString(1));

			checkAndGetLocation();
		} catch (JSONException e) {
			// json数据异常
			Log.i(TAG, "json数据异常");
			e.printStackTrace();
		}
	}

	public void checkAndGetLocation() {
		// 1.获取位置信息管理器
		locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
		if(locationManager == null) {
			Log.i(TAG, "locationManager不存在");
			return;
		}
		// 2.获取位置信息提供器,Gps或network
		List<String> providers = locationManager.getProviders(true);
		if (providers.contains(LocationManager.NETWORK_PROVIDER)) {
			// 如果是网络定位
			Log.i(TAG, "网络定位");
			locationProvider = LocationManager.NETWORK_PROVIDER;
		} else if (providers.contains(LocationManager.GPS_PROVIDER)) {
			// 如果是GPS定位
			Log.i(TAG, "GPS定位");
			locationProvider = LocationManager.GPS_PROVIDER;
		} else {
			Log.i(TAG, "没有可用的位置提供器");
			//若不开启位置服务   则会导致无法获取手机当前的经纬度信息(使用回调提示用户手动开启位置服务)
			return;
		}

		// 3.获取上次的位置,一般第一次运行,此值为null
		Log.i(TAG, "开始进行第一次获取");
		Location location = locationManager.getLastKnownLocation(locationProvider);
		if (location != null) {
			setLocation(location);
		}else {
			Log.i(TAG, "开始进行第二次获取");
			SystemClock.sleep(1000);
			Log.i(TAG, "第二次获取依旧为null");
			location = locationManager.getLastKnownLocation(locationProvider);
			if (location != null) {
				setLocation(location);
			}else {
				//quit操作
				Log.i(TAG, "第二次获取依旧为null");
			}
		}
		
		// 监视地理位置变化,第二个和第三个参数分别为更新的最短时间minTime和最短距离minDistace
		//locationManager.requestLocationUpdates(locationProvider, 5000, 3, locationListener);
	}

	private void setLocation(Location location) {
		this.location = location;
		String address = "纬度:" + location.getLatitude() + "经度:" + location.getLongitude();
		Log.i(TAG, address);
		JSUtil.execCallback(pWebviews, callbackid, address, JSUtil.OK, true);
	}

	/**
	 * LocationListern监听器 参数:地理位置提供器、监听位置变化的时间间隔、位置变化的距离间隔、LocationListener监听器
	 */

	LocationListener locationListener = new LocationListener() {

		/**
		 * 当某个位置提供者的状态发生改变时
		 */
		@Override
		public void onStatusChanged(String provider, int status, Bundle arg2) {

		}

		/**
		 * 某个设备打开时
		 */
		@Override
		public void onProviderEnabled(String provider) {

		}

		/**
		 * 某个设备关闭时
		 */
		@Override
		public void onProviderDisabled(String provider) {

		}

		/**
		 * 手机位置发生变动
		 */
		@Override
		public void onLocationChanged(Location location) {
			location.getAccuracy();// 精确度
			setLocation(location);
		}
	};
}

我注释掉了监听位置改变的代码,这个对于混合开发个人觉得不需要,原生app开发需要的。

测试如果发现未进入网络获取信息或者gps位置信息,直接进入else判断流程,一般情况下是用户关闭了位置服务,这时需要手动或自动开启位置服务!

针对app有位置权限,但用户手动关闭了位置服务时,代码需要使用如下所示:

 
 
package com.demo.maps;

import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import io.dcloud.common.DHInterface.IWebview;
import io.dcloud.common.DHInterface.StandardFeature;
import io.dcloud.common.util.JSUtil;

/**
 * 测试获取手机经纬度信息插件
 * 传值getlocation表示获取经纬度信息
 * @author 香蕉不拿拿先生
 * @date 2018年6月19日 上午9:45:34
 * 
 */
@SuppressLint("NewApi")
public class Get_Longitude_Latitude extends StandardFeature {
	private static final String TAG = "Get_Longitude_Latitude";
	private Location location;
	String callbackid;
	IWebview pWebviews;
	Activity activity;
	// 位置管理器
	LocationManager locationManager;
	private String locationProvider;

	public void getLongitudeAndLatitude(IWebview pWebview, JSONArray array) {
		Log.i("成功进入--->", "getLongitudeAndLatitude");
		pWebviews = pWebview;
		activity = pWebview.getActivity();
		callbackid = array.optString(0);
		JSONArray jsonArray = null;
		try {
			jsonArray = new JSONArray(array.optString(1));
			String operateName = jsonArray.getString(0);
			Log.i(TAG, operateName);
			if (checkPermission()) {
				if ("getlocation".equals(operateName)) {
					// 当有位置权限信息 且 用户未主动关闭位置权限时,可以调用此方法获取经纬度信息
					getLocation();
				}
			} else {
				// 在checkPermission()中有对false的返回进行相关的提示操作
			}

		} catch (JSONException e) {
			// json数据异常
			Log.i(TAG, "json数据异常");
			JSUtil.execCallback(pWebviews, callbackid, "JAON_EXCEPTION", JSUtil.OK, true);
			e.printStackTrace();
		}
	}

	// 个人觉得在使用定位插件之前 优先判断用户是否给予了位置权限
	public boolean checkPermission() {
		// 0
		/*
		 * if (activity.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
		 * == PackageManager.PERMISSION_DENIED) { // -1 Log.i(TAG, "无权限"); return false;
		 * }
		 */
		// 1.获取位置信息管理器
		locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
		if (locationManager == null) {
			Log.i(TAG, "locationManager不存在");
			JSUtil.execCallback(pWebviews, callbackid, "NO_LOCATIONMANAGER", JSUtil.OK, true);
			return false;
		}
		boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
		Log.i(TAG, String.valueOf(gps));
		boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
		Log.i(TAG, String.valueOf(network));
		// 当用户未开启位置服务时(有权限,但用户在手机管理中进行了关闭操作),则会出现无法定位的问题
		if (!(gps || network)) {
			// 提示用户开启位置服务
			JSUtil.execCallback(pWebviews, callbackid, "REMAIN_OPEN_LOCATION_SERVICE", JSUtil.OK, true);
			return false;
		} else {
			return true;
		}
	}

	// 获取位置信息
	public void getLocation() {
		// 2.获取位置信息提供器,Gps或network(优先网络定位)
		List<String> providers = locationManager.getProviders(true);
		if (providers.contains(LocationManager.NETWORK_PROVIDER) || providers.contains(LocationManager.GPS_PROVIDER)) {
			if (providers.contains(LocationManager.NETWORK_PROVIDER)) {
				// 如果是网络定位
				Log.i(TAG, "网络定位");
				JSUtil.execCallback(pWebviews, callbackid, "NET_WORK", JSUtil.OK, true);
				locationProvider = LocationManager.NETWORK_PROVIDER;
			}
			//gps放在后面是因为若用户开启了高精度gps定位,就采用gps
			if (providers.contains(LocationManager.GPS_PROVIDER)) {
				// 如果是GPS定位
				Log.i(TAG, "GPS定位");
				JSUtil.execCallback(pWebviews, callbackid, "GPS", JSUtil.OK, true);
				locationProvider = LocationManager.GPS_PROVIDER;
			}
		} else {
			Log.i(TAG, "没有可用的位置提供器");
			// 若不开启位置服务 则会导致无法获取手机当前的经纬度信息
			JSUtil.execCallback(pWebviews, callbackid, "NO_LOCATION_SERVICE", JSUtil.OK, true);
			return;
		}

		// 3.获取上次的位置,一般第一次运行,此值为null
		Log.i(TAG, "开始进行第一次获取");
		Location location = locationManager.getLastKnownLocation(locationProvider);
		if (location != null) {
			setLocation(location);
		} else {
			Log.i(TAG, "开始进行第二次获取");
			SystemClock.sleep(1000);
			Log.i(TAG, "第二次获取依旧为null");
			location = locationManager.getLastKnownLocation(locationProvider);
			if (location != null) {
				setLocation(location);
			} else {
				// 第二次还是null  判断最开始使用的是gps还是网络   如果是gps就改为网络  继续定位
				if(locationProvider == LocationManager.GPS_PROVIDER) {
					//开始为gps,但对象为null  改用网络 定位(考虑到室内开gps后  location对象为null的情况)
					locationProvider = LocationManager.NETWORK_PROVIDER;
				}else{
					Log.i(TAG, "第二次获取依旧为null");
					JSUtil.execCallback(pWebviews, callbackid, "LOCATION_NULL", JSUtil.OK, true);
					return;
				}
				location = locationManager.getLastKnownLocation(locationProvider);
			}
		}

		/**
		 * 调用位置监听 参数一:位置提供器的类型(gps、网络等) 参数二:监听位置变化的时间间隔,以ms为单位 参数三:监听位置变化的距离间隔,以m为单位
		 * 参数四:回调函数
		 */
		locationManager.requestLocationUpdates(locationProvider, 3000, (float) 0.5, locationListener);
		
		//插件是异步的  ,退出H5页面后(插件调用了的) 此监听依旧在进行-----设置时间段
		new Handler().postDelayed(new Runnable() {
			@Override
			public void run() {
				Log.i(TAG, "定时器执行");
				//locationListener为null是出现:java.lang.IllegalArgumentException
				if(locationManager != null && locationListener != null) {
					//移除监听器  
		            locationManager.removeUpdates(locationListener); 
				}
			}
		}, 1000*10);
	}

	private void setLocation(Location location) {
		this.location = location;
		String address = "LATIDUTE-" + location.getLatitude() + "==LONGTIDUTE-" + location.getLongitude();
		Log.i(TAG, address);
		// JSUtil.execCallback(pWebviews, callbackid, address, JSUtil.OK, true);
	}

	/**
	 * LocationListern监听器 参数:地理位置提供器、监听位置变化的时间间隔、位置变化的距离间隔、LocationListener监听器
	 */
	LocationListener locationListener = new LocationListener() {

		/**
		 * 当某个位置提供者的状态发生改变时
		 */
		@Override
		public void onStatusChanged(String provider, int status, Bundle arg2) {

		}

		/**
		 * 某个设备打开时
		 */
		@Override
		public void onProviderEnabled(String provider) {

		}

		/**
		 * 某个设备关闭时
		 */
		@Override
		public void onProviderDisabled(String provider) {

		}

		/**
		 * 手机位置发生变动
		 */
		@SuppressWarnings("unused")
		@Override
		public void onLocationChanged(Location location) {
			location.getAccuracy();// 精确度
			// setLocation(location);
			Log.i(TAG, "位置发生改变回调");
			if (location != null) {
				String address = "LATIDUTE-" + location.getLatitude() + "==LONGTIDUTE-" + location.getLongitude();
				Log.i(TAG, address);
				JSUtil.execCallback(pWebviews, callbackid, address, JSUtil.OK, true);
			}

		}
	};
	
}

光判断是否存在权限依旧是不够的,经过测试发现当有权限,但用户主动关闭,会导致依旧无法获取经纬度信息的问题,所以添加了判断LocationManager.GPS_PROVIDER和LocationManager.NETWORK_PROVIDER,当用户手动关闭位置服务,两者均会返回false,反之两者都是true(本人手机的测试结果,不代表全部,所以用的"||")

混合开发,插件js部分

document.addEventListener("plusready",function(){
	// 声明的JS“扩展插件别名”
    var _BARCODE = 'checkAndGetLocation',
        B = window.plus.bridge;
	var checkAndGetLocation = {
        getLongitudeAndLatitude:function(Argus,successCallback,errorCallback){
        	var success = typeof successCallback !== 'function' ? null : function(args) 
            		{
            			successCallback(args);
            		},
            		fail = typeof errorCallback !== 'function' ? null : function(code) 
            		{
            			errorCallback(code);
            		};
            		callbackID = B.callbackId(success, fail);
            		return B.exec(_BARCODE, "getLongitudeAndLatitude", [callbackID, Argus]);
            }
	};
	window.plus.checkAndGetLocation = checkAndGetLocation;
},true)

猜你喜欢

转载自blog.csdn.net/qq_38322527/article/details/80732056