uniApp 解决uniapp三方地图获取位置接口的请求次数限制问题,分别提供 Android 和 iOS 的实现方法(原生插件获取)
以下是使用 UniApp 编写获取位置信息的原生插件步骤,这里分别提供 Android 和 iOS 的实现方法。
一、Android 端实现
-
创建原生插件模块
- 在 UniApp 项目目录下创建一个目录,比如
nativeplugins/android/locationPlugin
。 - 使用 Android Studio 创建一个 Android Library 模块,将其命名为
locationPlugin
(与目录名一致)。
- 在 UniApp 项目目录下创建一个目录,比如
-
实现获取位置信息的功能
- 在插件的 Java 代码中,可以使用 Android 的
LocationManager
来获取位置信息。以下是一个示例类:
- 在插件的 Java 代码中,可以使用 Android 的
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import com.alibaba.fastjson.JSONObject;
import com.taobao.weex.annotation.JSMethod;
import com.taobao.weex.bridge.JSCallback;
import com.taobao.weex.common.WXModule;
public class LocationPlugin extends WXModule implements LocationListener {
private LocationManager locationManager;
private JSCallback callback;
@JSMethod
public void getLocation(JSCallback jsCallback) {
callback = jsCallback;
locationManager = (LocationManager) mWXSDKInstance.getContext().getSystemService(Context.LOCATION_SERVICE);
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED) {
// 申请权限
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
return;
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
@Override
public void onLocationChanged(Location location) {
if (location!= null) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("latitude", location.getLatitude());
jsonObject.put("longitude", location.getLongitude());
if (callback!= null) {
callback.invoke(jsonObject);
}
locationManager.removeUpdates(this);
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
- 注册插件
- 在插件模块的
AndroidManifest.xml
文件中注册插件:
- 在插件模块的
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<meta-data
android:name="WX_MODULE_LIST"
android:value="com.example.locationPlugin.LocationPlugin" />
</application>
</manifest>
二、iOS 端实现
-
创建原生插件模块
- 在 UniApp 项目目录下创建一个目录,比如
nativeplugins/ios/locationPlugin
。 - 使用 Xcode 创建一个 Cocoa Touch Framework,将其命名为
locationPlugin
(与目录名一致)。
- 在 UniApp 项目目录下创建一个目录,比如
-
实现获取位置信息的功能
- 在插件的 Objective-C 或 Swift 代码中,可以使用 iOS 的
CLLocationManager
来获取位置信息。以下是一个 Objective-C 的示例类:
- 在插件的 Objective-C 或 Swift 代码中,可以使用 iOS 的
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <WeexSDK/WXModule.h>
#import <CoreLocation/CoreLocation.h>
@interface LocationPlugin : WXModule <CLLocationManagerDelegate>
@property (nonatomic, strong) CLLocationManager *locationManager;
@end
@implementation LocationPlugin
- (void)getLocation:(WXModuleKeepAliveCallback)callback {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
[self.locationManager requestWhenInUseAuthorization];
} else if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedAlways) {
[self.locationManager startUpdatingLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
CLLocation *location = [locations lastObject];
NSDictionary *dict = @{
@"latitude": @(location.coordinate.latitude),
@"longitude": @(location.coordinate.longitude)
};
[self fireEvent:@"locationUpdated" params:dict];
[manager stopUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSDictionary *dict = @{
@"error": error.localizedDescription
};
[self fireEvent:@"locationError" params:dict];
}
@end
- 注册插件
- 在插件模块的
Info.plist
文件中注册插件:
- 在插件模块的
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>WXAppModuleClassName</key>
<string>LocationPlugin</string>
</dict>
</plist>
三、在 UniApp 中使用插件
- 在
manifest.json
文件中配置插件:
{
"app-plus": {
"nativePlugins": {
"locationPlugin": {
"android": {
"class": "com.example.locationPlugin.LocationPlugin"
},
"ios": {
"class": "locationPlugin.LocationPlugin"
}
}
}
}
}
- 在 UniApp 的 Vue 页面中调用插件:
import uni from '@dcloudio/uni-app';
export default {
data() {
return {
location: {}
};
},
methods: {
getLocation() {
uni.requireNativePlugin('locationPlugin').getLocation(res => {
this.location = res;
});
}
}
};
注意:在实际使用中,需要处理权限申请、错误处理等情况,以确保插件的稳定性和可靠性。