如何使用AlarmReceiver每10分钟ping一次GPS位置



我真的很抱歉,但这个问题很长。

我有一个正常工作的GPSTracker类,它包含为设备ping GPS定位的方法。在我的MainActivity中,我有一个按钮,它使用GPS跟踪器在toast中显示位置。我正试图将这个按钮转换为每X分钟重复一次的自动操作,让我们从10开始。(现在警报接收器设置为10秒)即使应用程序在后台。所以我设置了一个AlarmReceiver来尝试这样做,但我不能完全让它工作。

这是我的GPSTracker类:

import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
public class GPSTracker extends Service implements LocationListener {
private final Context context;
boolean isGPSEnabled = false;
boolean canGetLocation = false;
boolean isNetworkEnabled = false;
Location location;
double latitude;
double longitude;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10;
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1;
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.context = context.getApplicationContext();
getLocation();
}
public Location getLocation(){
try {
locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if(!isGPSEnabled && !isNetworkEnabled) {
}else {
this.canGetLocation = true;
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

if(locationManager != null){
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if(location !=null){
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
if(isGPSEnabled){
if(location == null){
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if(locationManager !=null){
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null){
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
public void stopUsingGPS() {
if(locationManager != null){
locationManager.removeUpdates(GPSTracker.this);
}
}
public double getLatitude() {
if(location!= null){
latitude = location.getLatitude();
}
return latitude;
}
public double getLongitude() {
if(location !=null){
longitude = location.getLongitude();
}
return longitude;
}
public boolean canGetLocation(){
return this.canGetLocation;
}
public void showSettingsAlert() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
alertDialog.setTitle("GPS is settings");
alertDialog.setMessage("GPS isn't enabled.  Do you want to go to settings menu?");
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(intent);
}
});
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int i) {
dialog.cancel();
}
});
alertDialog.show();
}
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}

这是我的主要活动:

package com.example.gwyn.locationnabtest;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MainActivity extends ActionBarActivity {
Button btnShowLocation;
Button btnStartService;
Button btnStopService;
GPSTracker gps;
//GoogleMap mMap;
private PendingIntent pendingIntent;
private AlarmManager manager;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnShowLocation = (Button) findViewById(R.id.show_location);
btnShowLocation.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
FragmentActivity activity = (FragmentActivity)view.getContext();
FragmentManager manager = activity.getSupportFragmentManager();
//MapFragment myMap = (MapFragment) (MainActivity.getFragmentManager()).findFragmentById((R.id.mapFragment));
// Test, remove me.
// mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapFragment)).getMap();
gps = new GPSTracker(MainActivity.this);
if(gps.canGetLocation()) {
// Location Achieved.
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
// Draw Marker for Current Location on Fragment
// Currently Crashing App
//  mMap.addMarker(new MarkerOptions().position(new LatLng(latitude, longitude)).title("Marker"));
// Toast a popup of the location data.
Toast.makeText(getApplicationContext(), "Your Location is -nLat:" + latitude + "nLong:" + longitude, Toast.LENGTH_LONG).show();
} else {
gps.showSettingsAlert();
}
}
});
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);


btnStartService = (Button) findViewById(R.id.start_service);
btnStartService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
int interval = 10000;
// 10 Second Interval.  Good for testing, but turn this off.
manager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
Toast.makeText(getApplicationContext(), "Service Started", Toast.LENGTH_SHORT).show();
//startService(new Intent(getBaseContext(), MyServices.class));
}
});
btnStopService = (Button) findViewById(R.id.stop_service);
btnStopService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Cancel pending intents
manager.cancel(pendingIntent);
Toast.makeText(getApplicationContext(), "Pending Intents Cancelled", Toast.LENGTH_SHORT).show();
}
});
}
}

特别强调的是,这是MainActivity中用于显示GPS:的部分

public void onClick(View view) {
FragmentActivity activity = (FragmentActivity)view.getContext();
FragmentManager manager = activity.getSupportFragmentManager();
//MapFragment myMap = (MapFragment) (MainActivity.getFragmentManager()).findFragmentById((R.id.mapFragment));
// Test, remove me.
// mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapFragment)).getMap();
gps = new GPSTracker(MainActivity.this);
if(gps.canGetLocation()) {
// Location Achieved.
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
// Draw Marker for Current Location on Fragment
// Currently Crashing App
//  mMap.addMarker(new MarkerOptions().position(new LatLng(latitude, longitude)).title("Marker"));
// Toast a popup of the location data.
Toast.makeText(getApplicationContext(), "Your Location is -nLat:" + latitude + "nLong:" + longitude, Toast.LENGTH_LONG).show();
} else {
gps.showSettingsAlert();
}
}

我的AlarmReceiver如下所示,并且在创建GPSTracker:时会产生错误

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class AlarmReceiver extends BroadcastReceiver {
GPSTracker gps;
@Override
public void onReceive(Context arg0, Intent arg1) {
// Here's where we'd grab location and store it into DB.
//gps = new GPSTracker(AlarmReceiver.this);
// if(gps.canGetLocation()) {
//     double latitude = gps.getLatitude();
//     double longitude = gps.getLongitude();
// Draw Marker for Current Location on Fragment
// Toast a popup of the location data.
//     Toast.makeText(arg0, "Your Location is -nLat:" + latitude + "nLong:" + longitude, Toast.LENGTH_LONG).show();
// } else {
//    gps.showSettingsAlert();
// }

// Toast that the alarm ran.
Toast.makeText(arg0, "Location Pinged.", Toast.LENGTH_SHORT).show();
}

更具体地说,问题的一部分是我在这里调用新的gps跟踪器对象的方式:

//gps = new GPSTracker(AlarmReceiver.this);

我不确定如何在使用警报接收器而不是按钮的情况下获得原始结果,这是我问题的主要来源。有人确切知道我可以在这里修改什么来让警报接收器正确使用GPSTracker类吗?

不要使用GPSTracker。它坏了十几个方面。忘记它的存在吧。如果您想要更好的版本,可以使用http://gabesechansoftware.com/location-tracking/这个链接还解释了为什么GPSTracker在设计上被破坏,以及为什么它永远不应该被使用。如果在最佳情况下使用,它基本上会起作用,并在所有其他情况下给你可怕的数据。

其次,如果你使用的是GPS而不是网络,你需要给它时间来同步位置。这可能需要几秒钟到几分钟(如果用户在地下室或其他地方,则需要几个小时),因此获取位置的直接形式是行不通的——你必须等待它真正同步位置。

我建议您不要寻找库来解决这个问题,而是实际尝试了解基本API是如何工作的。在你这样做之前,你会遇到任何你使用的东西的麻烦,因为这里有很多角落的案例,这不是一件小事。

最新更新