Android 4.4中的自动GPS启用和禁用类似于谷歌地图?

时间:2014-11-25 12:49:56

标签: java android google-maps gps

每当我尝试打开并自动关闭GPS时,KITKAT会触发java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE exception...

来自堆栈溢出的以下答案,Android device GPS on/off programatically
 我知道了,

* For The security purpose Google developer has block above both methods which were previously working fine.

* Hence conclusion is that You can not programmatically start GPS On or Off. 

 This is the code part where exception is thrown,



/** Method for stop GPS **/
    public synchronized void onPauseGPSListener() {
        mLogger.log("Remove GPS Location Update");


 //this Line throws the exception--------------------------------


Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
            intent.putExtra("enabled", false);
            sendBroadcast(intent);
            if (locationclient != null && mlocListener != null) {
                locationclient.removeLocationUpdates(mlocListener);
                locationclient.disconnect();
                locationclient=null;
                mlocListener = null;
            }
            StoptimerForGPSRemoveListener();
            if (mcalMgr.mServerReset == 0) {
                timerForGPSStartListener();
            }
        }

        /** Method for Start GPS **/
        public synchronized void onStartGPSListener() {
            mLogger.log("Start GPS Location Update");
            if (mlocListener == null) {
                mlocListener = new MyLocationListener();
            }
            Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
            intent.putExtra("enabled", true);
            sendBroadcast(intent);
            StoptimerForGPSStartListener();
            if (mcalMgr.mServerReset == 0) {
                initGPSModule(mnFrequency, mfChangeDistance);
            } else {
                mlocListener = null;
                Intent mintent = new Intent("android.location.GPS_ENABLED_CHANGE");
                mintent.putExtra("enabled", false);
                sendBroadcast(mintent);
            }
    }

这是Logcat堆栈跟踪,

11-20 11:19:26.317: E/AndroidRuntime(7773): Process: com.teclever.tracking, PID: 7773
11-20 11:19:26.317: E/AndroidRuntime(7773): java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE from pid=7773, uid=10160
11-20 11:19:26.317: E/AndroidRuntime(7773):     at android.os.Parcel.readException(Parcel.java:1465)
11-20 11:19:26.317: E/AndroidRuntime(7773):     at android.os.Parcel.readException(Parcel.java:1419)
11-20 11:19:26.317: E/AndroidRuntime(7773):     at android.app.ActivityManagerProxy.broadcastIntent(ActivityManagerNative.java:2451)
11-20 11:19:26.317: E/AndroidRuntime(7773):     at android.app.ContextImpl.sendBroadcast(ContextImpl.java:1264)
11-20 11:19:26.317: E/AndroidRuntime(7773):     at android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:365)
11-20 11:19:26.317: E/AndroidRuntime(7773):     at com.teclever.tracking.LocationGetter.onPauseGPSListener(LocationGetter.java:601)
11-20 11:19:26.317: E/AndroidRuntime(7773):     at com.teclever.tracking.LocationGetter$1.run(LocationGetter.java:706)
11-20 11:19:26.317: E/AndroidRuntime(7773):     at android.os.Handler.handleCallback(Handler.java:808)
11-20 11:19:26.317: E/AndroidRuntime(7773):     at android.os.Handler.dispatchMessage(Handler.java:103)
11-20 11:19:26.317: E/AndroidRuntime(7773):     at android.os.Looper.loop(Looper.java:193)
11-20 11:19:26.317: E/AndroidRuntime(7773):     at android.app.ActivityThread.main(ActivityThread.java:5312)
11-20 11:19:26.317: E/AndroidRuntime(7773):     at java.lang.reflect.Method.invokeNative(Native Method)
11-20 11:19:26.317: E/AndroidRuntime(7773):     at java.lang.reflect.Method.invoke(Method.java:515)
11-20 11:19:26.317: E/AndroidRuntime(7773):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
11-20 11:19:26.317: E/AndroidRuntime(7773):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
11-20 11:19:26.317: E/AndroidRuntime(7773):     at dalvik.system.NativeStart.main(Native Method)
11-20 11:19:27.026: E/(706): Could not open '/data/data/hotplug/cmd'
11-20 11:19:27.027: E/(706): error : 2, No such file or directory
11-20 11:19:27.104: E/(1015): appName=com.jrdcom.launcher, acAppName=/system/bin/surfaceflinger
11-20 11:19:27.104: E/(1015): 0
11-20 11:19:27.179: E/(706): Could not open '/data/data/hotplug/cmd'
11-20 11:19:27.180: E/(706): error : 2, No such file or directory
11-20 11:19:27.967: E/TelephonyProvider(833): iTelephony is null!!!

但我的问题是,当我打开Google maps时,它会变成GPS on and off without any prompt from user ,,,它只是在我们首次登录我们的应用程序时要求,从那时起它会自动打开并且关闭GPS,我怎么能实现谷歌地图中实现的相同程序,更好地为我提供代码示例谢谢

1 个答案:

答案 0 :(得分:0)

它的工作方式与谷歌地图类似吗?

在build.gradle文件中添加依赖

编译'com.google.android.gms:play-services:8.3.0'

this or that

编译'com.google.android.gms:play-services-location:10.0.1'     enter image description here

package com.keshav.volleypostexample;

import android.content.Context;
import android.content.IntentSender;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResult;
import com.google.android.gms.location.LocationSettingsStatusCodes;

import java.util.List;

public class LocationOnOff_Similar_To_Google_Maps extends AppCompatActivity {

    protected static final String TAG = "LocationOnOff";


    private GoogleApiClient googleApiClient;
    final static int REQUEST_LOCATION = 199;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.setFinishOnTouchOutside(true);

        // Todo Location Already on  ... start
        final LocationManager manager = (LocationManager) LocationOnOff_Similar_To_Google_Maps.this.getSystemService(Context.LOCATION_SERVICE);
        if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)) {
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps already enabled",Toast.LENGTH_SHORT).show();
            finish();
        }
        // Todo Location Already on  ... end

        if(!hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)){
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps not Supported",Toast.LENGTH_SHORT).show();
        }

        if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)) {
            Log.e("keshav","Gps already enabled");
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps not enabled",Toast.LENGTH_SHORT).show();
            enableLoc();
        }else{
            Log.e("keshav","Gps already enabled");
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps already enabled",Toast.LENGTH_SHORT).show();
        }
    }


    private boolean hasGPSDevice(Context context) {
        final LocationManager mgr = (LocationManager) context
                .getSystemService(Context.LOCATION_SERVICE);
        if (mgr == null)
            return false;
        final List<String> providers = mgr.getAllProviders();
        if (providers == null)
            return false;
        return providers.contains(LocationManager.GPS_PROVIDER);
    }

    private void enableLoc() {

        if (googleApiClient == null) {
            googleApiClient = new GoogleApiClient.Builder(LocationOnOff_Similar_To_Google_Maps.this)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                        @Override
                        public void onConnected(Bundle bundle) {

                        }

                        @Override
                        public void onConnectionSuspended(int i) {
                            googleApiClient.connect();
                        }
                    })
                    .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                        @Override
                        public void onConnectionFailed(ConnectionResult connectionResult) {

                            Log.d("Location error","Location error " + connectionResult.getErrorCode());
                        }
                    }).build();
            googleApiClient.connect();

            LocationRequest locationRequest = LocationRequest.create();
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            locationRequest.setInterval(30 * 1000);
            locationRequest.setFastestInterval(5 * 1000);
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                    .addLocationRequest(locationRequest);

            builder.setAlwaysShow(true);

            PendingResult<LocationSettingsResult> result =
                    LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
            result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
                @Override
                public void onResult(LocationSettingsResult result) {
                    final Status status = result.getStatus();
                    switch (status.getStatusCode()) {
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            try {
                                // Show the dialog by calling startResolutionForResult(),
                                // and check the result in onActivityResult().
                                status.startResolutionForResult(LocationOnOff_Similar_To_Google_Maps.this, REQUEST_LOCATION);

                                finish();
                            } catch (IntentSender.SendIntentException e) {
                                // Ignore the error.
                            }
                            break;
                    }
                }
            });
        }
    }

}