我的问题很简单。我需要一种方法来使用Ionic应用程序内的按钮打开和关闭GPS。我检查了文档并阅读了这个ng-cordova插件http://ngcordova.com/docs/plugins/geolocation/,但它们似乎没有这个功能。我只是遗漏了一些东西,或者这在Ionic Framework中是否可行?谢谢!
答案 0 :(得分:4)
我想根据我的要求自动打开GPS。
所以我使用 cordova-plugin-request-location-accuracy
当GPS关闭时,它要求用户打开GPS ..这对我很有帮助..
>
的 Ionic1 强>
https://github.com/dpa99c/cordova-plugin-request-location-accuracy
的 Ionic2 强>
https://ionicframework.com/docs/native/location-accuracy/
最诚挚的问候......
答案 1 :(得分:1)
据我所知,无法从您的应用中直接禁用GPS。
如果您尝试允许用户停用GPS,我通过向localStorage
添加设置来实现此目的,用户可以在我的应用中的设置页面上进行更改。每次我在我的位置工厂检查GPS时,如果设置被禁用,我会检查设置并运行错误回调。
可能有某种调用可以自动打开设备上的位置设置页面,因为我看到其他应用程序这样做了,但我不确定Cordova / Ionic是否支持它。
答案 2 :(得分:0)
经过研究,我意识到使用Ionic无法在应用内打开/关闭位置(至少现在不行),所以最好的选择是打开设备位置设置,因为你可以改变不仅GPS的状态,你也可以改变功率和精度。
你可以使用cordova-diagnostic-plugin,一个插件(带有很好的文档)来操作设备设置,如wifi,蓝牙,GPS。
我希望它有所帮助!
答案 3 :(得分:0)
在Ionic 3上测试此插件Location Accuracy时,无需通过设置页面即可启用该位置,该页面表示可以通过编程方式启用GPS。这是导航到模态页面后使用的代码示例,方法是使用Diagnostic plugin检查位置是否已启用。
位置的auth.ts
import { Component } from '@angular/core';
import { IonicPage,
ViewController } from 'ionic-angular';
import { LocationAccuracy } from '@ionic-native/location-accuracy';
@IonicPage({
name: 'location-auth'
})
@Component({
selector: 'page-location-auth',
templateUrl: 'location-auth.html',
})
export class LocationAuthPage {
constructor(private locationAccuracy: LocationAccuracy,
public viewCtrl: ViewController) {}
requestAccuracy() {
this.locationAccuracy.canRequest().then((canRequest: boolean) => {
if(canRequest) {
this.locationAccuracy.request(this.locationAccuracy.REQUEST_PRIORITY_HIGH_ACCURACY).then(() => {
console.log('Request successful.')
this.closeModal();
},
error => {
console.log('Error requesting location permissions', error)
this.closeModal();
}
);
}
});
}
closeModal() {
this.viewCtrl.dismiss();
}
}
位置的auth.html
<ion-header>
<ion-navbar color="primary">
<ion-title>GPS Authorization</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<p>Your Location is not enabled yet, please turn on your gps location.</p>
<button large
ion-button
block
(click)="requestAccuracy()">Turn on your GPS</button>
</ion-content>
到目前为止,我已在Android手机上进行测试。让我知道iOS是否按原样运行。
答案 4 :(得分:0)
据我所知,无法控制设备位置,因为没有任何Ionic或Cordova插件可用于此目的。可以使用Geolocation plugin获取设备位置。但是,如果设备GPS关闭,这不起作用。我已经使用JSInterface桥来管理设备位置。此解决方案仅适用于离子安卓平台,老实说,我建议只有打开设备GPS才能使用此功能。
说明: Google LocationServices为我们提供了启用设备位置的功能。我在离子和原生平台之间建立了一座桥梁。我的离子页面使用此桥接器请求设备位置。例如: NativeBridge.functionNameInActivity
本机功能请求设备位置&lt; -----&gt; JSInterface Bridge&lt; ----&gt;离子功能
<强> 1。以下是扩展CordovaActivity的MainActivity的代码:
public class MainActivity extends CordovaActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<LocationSettingsResult> {
public static Context mContext;
private Intent mIntent;
private final int REQUEST_CODE_LOCATION = 101;
private final int REQUEST_CODE_LOCATION_SETTINGS = 102;
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest locationRequest;
public static double LATITUDE, LONGITUDE;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getApplicationContext();
loadUrl(launchUrl);
mIntent = new Intent(this, LocationService.class);
final WebView webView = (WebView) appView.getEngine().getView();
webView.addJavascriptInterface(this.getJavaScriptHandler(), "NativeBridge");
}
@Override
public void onDestroy() {
super.onDestroy();
stopService(mIntent);
}
public void configureLocationClient() {
final int intervalInSecs = 30;
final int fastestIntervalInSecs = 5;
final int milliSecondMultiplier = 1000;
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
mGoogleApiClient.connect();
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(intervalInSecs * milliSecondMultiplier);
locationRequest.setFastestInterval(fastestIntervalInSecs * milliSecondMultiplier);
}
public void checkLocationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_LOCATION);
} else {
configureLocationClient();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_LOCATION_SETTINGS) {
if (resultCode == RESULT_OK) {
startService(mIntent);
} else {
//Display a message requesting location access for further operations
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Map<String, Integer> perms;
switch (requestCode) {
case REQUEST_CODE_LOCATION:
perms = new HashMap<String, Integer>();
perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
for (int i = 0; i < permissions.length; i++) {
perms.put(permissions[i], grantResults[i]);
}
if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
//Start location fetching service
configureLocationClient();
} else {
// Location Permission Denied
DisplayUtils.displayToast(mContext, AppConstants.MSG_PERMISSIONS_LOCATION);
return;
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
@Override
public void onConnected(@Nullable Bundle bundle) {
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(
mGoogleApiClient,
builder.build()
);
result.setResultCallback(this);
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Override
public void onResult(@NonNull LocationSettingsResult locationSettingsResult) {
final Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
/*Start location fetching service*/
startService(mIntent);
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
/*Location settings are not satisfied. Show the user a dialog by calling startResolutionForResult(), and check the result in onActivityResult().*/
try {
status.startResolutionForResult(MainActivity.this, REQUEST_CODE_LOCATION_SETTINGS);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
/*Location settings unavailable*/
break;
default:
break;
}
}
public JavaScriptHandler getJavaScriptHandler() {
return new JavaScriptHandler(this.getApplicationContext());
}
/***
* Javascript handler
***/
public class JavaScriptHandler {
CordovaActivity parentActivity;
private Context mContext;
public JavaScriptHandler(final CordovaActivity activity) {
this.parentActivity = activity;
}
public JavaScriptHandler(final Context context) {
this.mContext = context;
}
@JavascriptInterface
public boolean ifLocationPermissionGranted() {
return ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
}
@JavascriptInterface
public boolean ifLocationAccessible() {
LocationManager mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
return mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
@JavascriptInterface
public void startLocationService() {
checkLocationPermission();
}
@JavascriptInterface
public String getLatitude() {
return String.valueOf(LATITUDE);
}
@JavascriptInterface
public String getLongitude() {
return String.valueOf(LONGITUDE);
}
}
}
<强> 2。位置服务类:
public class LocationService extends Service {
private static String TAG = "TAG-LocationService";
private LocationManager mLocationManager;
private static final int LOCATION_INTERVAL = 2000;
private static final float LOCATION_DISTANCE = 0f;
private class LocationListener implements android.location.LocationListener {
Location mLastLocation;
public LocationListener(String provider) {
mLastLocation = new Location(provider);
}
@Override
public void onLocationChanged(Location location) {
mLastLocation.set(location);
if (location != null) {
MainActivity.LATITUDE = mLastLocation.getLatitude();
MainActivity.LONGITUDE = mLastLocation.getLongitude();
}
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
LocationListener[] mLocationListeners = new LocationListener[]{
new LocationListener(LocationManager.GPS_PROVIDER), new LocationListener(LocationManager.NETWORK_PROVIDER),
};
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
@Override
public void onCreate() {
initializeLocationManager();
try {
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[1]);
} catch (SecurityException ex) {
ex.printStackTrace();
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
} catch (SecurityException ex) {
ex.printStackTrace();
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLocationManager.removeUpdates(mLocationListeners[i]);
}
}
}
}
private void initializeLocationManager() {
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
}
第3。 JS控制器文件的代码:
MyDemoApp.controller('LocationController', function ($scope, $cordovaToast, $ionicPopup) {
$scope.goForIt = function () {
if (NativeBridge.ifLocationPermissionGranted()) {
if (NativeBridge.ifLocationAccessible()) {
$scope.getDevicePosition();
} else {
$scope.showLocationAlert();
}
} else {
$scope.showLocationAlert();
}
}
$scope.getDevicePosition = function () {
var positionLatitude = parseFloat(NativeBridge.getLatitude());
var positionLongitude = parseFloat(NativeBridge.getLongitude());
}
$scope.showLocationAlert = function () {
var confirmPopup = $ionicPopup.confirm({
title: 'Location Service required for further operation',
template: 'Grant permission to access Location?'
});
confirmPopup.then(function (res) {
if (res) {
NativeBridge.startLocationService();
} else {
$cordovaToast.showShortCenter("Location access required");
}
});
};
});
<强> 4。在build.gradle的依赖项中添加以下行:
compile 'com.google.android.gms:play-services-location:10.0.1'
<强> 5。添加对您的清单的权限
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location.gps" />
<强> 6。在清单中声明服务:
<service android:name=".LocationService"></service>
在调用此功能时,您将看到一个类似的对话框,要求启用设备位置。
同样,我建议仅在启用用户位置对您的应用功能非常重要时使用此功能,因为它的工作量非常大。随意批评: - )