以编程方式打开/关闭 Android 设备 GPS
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22528984/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android device GPS on/off programmatically
提问by Shrikant Salunkhe
I am using following code for GPS on/off.
我正在使用以下代码打开/关闭 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);
Programmatically I need to on/off GPS on android device. I am using above code for that. But It doesn't work on all the devices.
我需要以编程方式在 android 设备上打开/关闭 GPS。我正在使用上面的代码。但它不适用于所有设备。
回答by Lucifer
From my personal experience, I am answering this,
以我个人的经验来回答这个问题,
The hack code you shown in the your question has been stopped working from Android version 4.4. Your will fire this Exception starting from Kitkat version
java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE
The First answer's code will not work any more, it only display animated GPS icon in notification bar.
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.
您在问题中显示的黑客代码已从 Android 4.4 版停止工作。您将从 Kitkat 版本开始触发此异常
java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE
第一个答案的代码将不再起作用,它仅在通知栏中显示动画 GPS 图标。
出于安全目的,谷歌开发人员在这两种之前运行良好的方法上都有块。
因此结论是您不能以编程方式启动 GPS On 或 Off。
回答by kgandroid
Try this code:
试试这个代码:
/** 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"/>
UPDATE:
更新:
Now we can on/off GPS from our app using the default enable location dialog like Google maps.
现在我们可以使用默认的启用位置对话框(如谷歌地图)从我们的应用程序打开/关闭 GPS。
The documentation can be found here:
文档可以在这里找到:
Sample code:
示例代码:
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;
}
}
});
}
回答by DarwinFernandez
This code works on Rooted Phone
此代码适用于有根电话
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();
}
}
}
回答by Sanket Pandya
Use this for turning GPS ON and reverse the condition to put GPS OFF
使用它来打开 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);
}
回答by Imran Khan
i will suggest you use following code for Android kitkat 4.4.x
我建议您使用以下代码用于 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;
}
}}