如何在Ionic Framework或Cordova中以编程方式启用和禁用GPS

时间:2016-01-13 12:15:36

标签: cordova gps ionic-framework ionic ngcordova

我的问题很简单。我需要一种方法来使用Ionic应用程序内的按钮打开和关闭GPS。我检查了文档并阅读了这个ng-cordova插件http://ngcordova.com/docs/plugins/geolocation/,但它们似乎没有这个功能。我只是遗漏了一些东西,或者这在Ionic Framework中是否可行?谢谢!

5 个答案:

答案 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>

在调用此功能时,您将看到一个类似的对话框,要求启用设备位置。

enter image description here

同样,我建议仅在启用用户位置对您的应用功能非常重要时使用此功能,因为它的工作量非常大。随意批评: - )