【问题标题】:Android device GPS on/off programmatically以编程方式打开/关闭 Android 设备 GPS
【发布时间】:2014-03-20 09:46:33
【问题描述】:

我正在使用以下代码打开/关闭 GPS。

//Enable GPS
Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", true);
context.sendBroadcast(intent);
//Disable GPS
Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", false);
context.sendBroadcast(intent);

我需要以编程方式在 android 设备上打开/关闭 GPS。 我正在使用上面的代码。但它不适用于所有设备。

【问题讨论】:

标签: android android-intent gps


【解决方案1】:

根据我的个人经验,我正在回答这个问题,

  • 您在问题中显示的 hack 代码已从 Android 版本 4.4 停止工作。您将从 Kitkat 版本 java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE

  • 开始触发此异常
  • Firstanswer 的代码将不再起作用,它只会在通知栏中显示动画 GPS 图标。

  • 出于安全目的,Google 开发人员已经阻止了之前运行良好的两种方法。

  • 因此结论是您不能以编程方式启动或关闭 GPS。

【讨论】:

  • 感谢您的宝贵回答。那么还有其他方法可以开启/关闭 GPS 吗?
  • @ShrikantSalunkhe,欢迎您。现在唯一可能的方法是手动而不是编程。
  • startActivity(context, new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
  • startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));您也可以使用 can 并在设置页面导航到用户。
  • @Faisal Ashraf - 但它不会自动打开/关闭 GPS
【解决方案2】:

试试这个代码:

/** Method to turn on GPS **/
    public void turnGPSOn(){
        try
        {

        String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);


        if(!provider.contains("gps")){ //if gps is disabled
            final Intent poke = new Intent();
            poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
            poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
            poke.setData(Uri.parse("3"));
            sendBroadcast(poke);
        }
        }
        catch (Exception e) {

        }
    }
// Method to turn off the GPS
    public void turnGPSOff(){
        String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);

        if(provider.contains("gps")){ //if gps is enabled
            final Intent poke = new Intent();
            poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
            poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
            poke.setData(Uri.parse("3"));
            sendBroadcast(poke);
        }
    }

    // turning off the GPS if its in on state. to avoid the battery drain.
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        turnGPSOff();`enter code here`
    }

    /**

Also add this on your manifest:

<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>

更新:

现在我们可以使用默认的启用位置对话框(如 Google 地图)在我们的应用中打开/关闭 GPS。

文档可以在这里找到:

Android Location Dialog

示例代码:

if (googleApiClient == null) {
        googleApiClient = new GoogleApiClient.Builder(getActivity())
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this).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); //this is the key ingredient
            //**************************

            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();
                    final LocationSettingsStates state = result.getLocationSettingsStates();
                    switch (status.getStatusCode()) {
                        case LocationSettingsStatusCodes.SUCCESS:
                            // All location settings are satisfied. The client can initialize location
                            // requests here.
                            break;
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            // Location settings are not satisfied. But could be fixed by showing the user
                            // a dialog.
                            try {
                                // Show the dialog by calling startResolutionForResult(),
                                // and check the result in onActivityResult().
                                status.startResolutionForResult(
                                        getActivity(), 1000);
                            } catch (IntentSender.SendIntentException e) {
                                // Ignore the error.
                            }
                            break;
                        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                            // Location settings are not satisfied. However, we have no way to fix the
                            // settings so we won't show the dialog.
                            break;
                    }
                }
            });           
  }

【讨论】:

  • oh.4.4我还没有测试过
  • 在 4.4 中它会触发安全异常。
  • 在4.4.2版本触发安全异常Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE,所以在4.4及以上版本不再起作用
  • SettingsApi 现已弃用。建议的新(类似)代码在这里:developers.google.com/android/reference/com/google/android/gms/…
【解决方案3】:

此代码适用于 Rooted 手机

public class MainActivity extends AppCompatActivity {

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



        String[] cmds = {"cd /system/bin" ,"settings put secure location_providers_allowed +gps"};
        try {
            Process p = Runtime.getRuntime().exec("su");
            DataOutputStream os = new DataOutputStream(p.getOutputStream());
            for (String tmpCmd : cmds) {
                os.writeBytes(tmpCmd + "\n");
            }
            os.writeBytes("exit\n");
            os.flush();
        }
        catch (IOException e){
            e.printStackTrace();
        }

    }
}

【讨论】:

    【解决方案4】:

    使用它来打开 GPS 并反转条件以关闭 GPS

    Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
     intent.putExtra("enabled", true);
     this.ctx.sendBroadcast(intent);
    
    String provider = Settings.Secure.getString(ctx.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
    if(!provider.contains("gps")){ //if gps is disabled
        final Intent poke = new Intent();
        poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider"); 
        poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
        poke.setData(Uri.parse("3")); 
        this.ctx.sendBroadcast(poke);
    
    
    }
    

    【讨论】:

    【解决方案5】:

    我会建议你为 Android kitkat 4.4.x 使用以下代码

       public class GPSService extends Service implements LocationListener 
    
    
       {
    // saving the context for later use
    private final Context mContext;
    // if GPS is enabled
    boolean isGPSEnabled = false;
    // if Netw`enter code here`ork is enabled
    boolean isNetworkEnabled = false;
    // if Location co-ordinates are available using GPS or Network
    public boolean isLocationAvailable = false;
    
    // Location and co-ordinates coordinates
    Location mLocation;
    double mLatitude;
    double mLongitude;
    
    // Minimum time fluctuation for next update (in milliseconds)
    private static final long TIME = 30000;
    // Minimum distance fluctuation for next update (in meters)
    private static final long DISTANCE = 20;
    
    // Declaring a Location Manager
    protected LocationManager mLocationManager;
    
    public GPSService(Context context) {
        this.mContext = context;
        mLocationManager = (LocationManager) mContext
                .getSystemService(LOCATION_SERVICE);
    
    }
    
    /**
     * Returs the Location
     * 
     * @return Location or null if no location is found
     */
    public Location getLocation() {
        try {
    
            // Getting GPS status
            isGPSEnabled = mLocationManager
                    .isProviderEnabled(LocationManager.GPS_PROVIDER);
    
            // If GPS enabled, get latitude/longitude using GPS Services
            if (isGPSEnabled) {
                mLocationManager.requestLocationUpdates(
                        LocationManager.GPS_PROVIDER, TIME, DISTANCE, this);
                if (mLocationManager != null) {
                    mLocation = mLocationManager
                            .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                    if (mLocation != null) {
                        mLatitude = mLocation.getLatitude();
                        mLongitude = mLocation.getLongitude();
                        isLocationAvailable = true; // setting a flag that
                                                    // location is available
                        return mLocation;
                    }
                }
            }
    
            // If we are reaching this part, it means GPS was not able to fetch
            // any location
            // Getting network status
            isNetworkEnabled = mLocationManager
                    .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    
            if (isNetworkEnabled) {
                mLocationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER, TIME, DISTANCE, this);
                if (mLocationManager != null) {
                    mLocation = mLocationManager
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    if (mLocation != null) {
                        mLatitude = mLocation.getLatitude();
                        mLongitude = mLocation.getLongitude();
                        isLocationAvailable = true; // setting a flag that
                                                    // location is available
                        return mLocation;
                    }
                }
            }
            // If reaching here means, we were not able to get location neither
            // from GPS not Network,
            if (!isGPSEnabled) {
                // so asking user to open GPS
                askUserToOpenGPS();
            }
    
        } catch (Exception e) {
            e.printStackTrace();
        }
        // if reaching here means, location was not available, so setting the
        // flag as false
        isLocationAvailable = false;
        return null;
    }
    
    /**
     * Gives you complete address of the location
     * 
     * @return complete address in String
     */
    public String getLocationAddress() {
    
        if (isLocationAvailable) {
    
            Geocoder geocoder = new Geocoder(mContext, Locale.getDefault());
            // Get the current location from the input parameter list
            // Create a list to contain the result address
            List<Address> addresses = null;
            try {
                /*
                 * Return 1 address.
                 */
                addresses = geocoder.getFromLocation(mLatitude, mLongitude, 1);
            } catch (IOException e1) {
                e1.printStackTrace();
                return ("IO Exception trying to get address:" + e1);
            } catch (IllegalArgumentException e2) {
                // Error message to post in the log
                String errorString = "Illegal arguments "
                        + Double.toString(mLatitude) + " , "
                        + Double.toString(mLongitude)
                        + " passed to address service";
                e2.printStackTrace();
                return errorString;
            }
            // If the reverse geocode returned an address
            if (addresses != null && addresses.size() > 0) {
                // Get the first address
                Address address = addresses.get(0);
                /*
                 * Format the first line of address (if available), city, and
                 * country name.
                 */
                String addressText = String.format(
                        "%s, %s, %s",
                        // If there's a street address, add it
                        address.getMaxAddressLineIndex() > 0 ? address
                                .getAddressLine(0) : "",
                        // Locality is usually a city
                        address.getLocality(),
                        // The country of the address
                        address.getCountryName());
                // Return the text
                return addressText;
            } else {
                return "No address found by the service: Note to the developers, If no address is found by google itself, there is nothing you can do about it.";
            }
        } else {
            return "Location Not available";
        }
    
    }
    
    
    
    /**
     * get latitude
     * 
     * @return latitude in double
     */
    public double getLatitude() {
        if (mLocation != null) {
            mLatitude = mLocation.getLatitude();
        }
        return mLatitude;
    }
    
    /**
     * get longitude
     * 
     * @return longitude in double
     */
    public double getLongitude() {
        if (mLocation != null) {
            mLongitude = mLocation.getLongitude();
        }
        return mLongitude;
    }
    
    /**
     * close GPS to save battery
     */
    public void closeGPS() {
        if (mLocationManager != null) {
            mLocationManager.removeUpdates(GPSService.this);
        }
    }
    
    /**
     * show settings to open GPS
     */
    public void askUserToOpenGPS() {
        AlertDialog.Builder mAlertDialog = new AlertDialog.Builder(mContext);
    
        // Setting Dialog Title
        mAlertDialog.setTitle("Location not available, Open GPS?")
        .setMessage("Activate GPS to use use location services?")
        .setPositiveButton("Open Settings", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                mContext.startActivity(intent);
                }
            })
            .setNegativeButton("Cancel",new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                    }
                }).show();
    }
    
    /** 
     * Updating the location when location changes
     */
    @Override
    public void onLocationChanged(Location location) {
        mLatitude = location.getLatitude();
        mLongitude = location.getLongitude();
    }
    
    @Override
    public void onProviderDisabled(String provider) {
    }
    
    @Override
    public void onProviderEnabled(String provider) {
    }
    
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }
    
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }}
    

    //////////////////////

                                                                                                                         public class MainActivity extends ActionBarActivity {
         @Override
                 public class MainActivity extends ActionBarActivity {protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment()).commit();
        }
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    
    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {
    
        public PlaceholderFragment() {
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container,
                    false);
    
            final TextView tvLocation = (TextView)rootView.findViewById(R.id.tvLocation);
            final TextView tvAddress = (TextView)rootView.findViewById(R.id.tvAddress);
    
            Button btnGetLocation = (Button)rootView.findViewById(R.id.btnGetLocation);
    
            btnGetLocation.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
    
                    String address = "";
                    GPSService mGPSService = new GPSService(getActivity());
                    mGPSService.getLocation();
    
                    if (mGPSService.isLocationAvailable == false) {
    
                        // Here you can ask the user to try again, using return; for that
                        Toast.makeText(getActivity(), "Your location is not available, please try again.", Toast.LENGTH_SHORT).show();
                        return;
    
                        // Or you can continue without getting the location, remove the return; above and uncomment the line given below
                        // address = "Location not available";
                    } else {
    
                        // Getting location co-ordinates
                        double latitude = mGPSService.getLatitude();
                        double longitude = mGPSService.getLongitude();
                        Toast.makeText(getActivity(), "Latitude:" + latitude + " | Longitude: " + longitude, Toast.LENGTH_LONG).show();
    
                        address = mGPSService.getLocationAddress();
    
                        tvLocation.setText("Latitude: " + latitude + " \nLongitude: " + longitude);
                        tvAddress.setText("Address: " + address);
                    }
    
                    Toast.makeText(getActivity(), "Your address is: " + address, Toast.LENGTH_SHORT).show();
    
                    // make sure you close the gps after using it. Save user's battery power
                    mGPSService.closeGPS();
    
    
                }
            });
    
    
    
    
    
    
    
            return rootView;
        }
    }}
    

    【讨论】:

      猜你喜欢
      • 2015-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多