我试图在几秒钟内获取当前位置,我使用AlarmManager和LocationListener以及位置管理器。 在设置闹钟之前我需要获取当前位置来计算一般距离。 当我在AVD上运行我的应用程序并设置Lat&使用DDMS手动长,App可以正常工作。 问题是,当应用程序在真实设备上运行时,应用程序会立即关闭(当我手动设置位置时,它也会失败)。 请问有什么问题?我只需要在点击按钮时获取当前位置,并且每隔几秒......
GPSTracker.Java:
public class GPSTracker extends Service implements LocationListener {
private final Context mContext;
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
// Declaring a Location Manager
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.mContext = context;
getLocation();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
// First get location from Network Provider
if (isNetworkEnabled) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return location;
}
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location =
locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
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;
}
/**
* Stop using GPS listener
* Calling this function will stop using GPS in your app
* */
public void stopUsingGPS() {
if (locationManager != null) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
locationManager.removeUpdates(GPSTracker.this);
Log.d("GPS is stopped", "GPS is stopped");
}
}
/**
* Function to get latitude
* */
public double getLatitude() {
if (location != null) {
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude() {
if (location != null) {
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* Function to check GPS/wifi enabled
* @return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog
* On pressing Settings button will lauch Settings Options
* */
public void showSettingsAlert() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("GPS is settings");
// Setting Dialog Message
alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
// On pressing Settings button
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
@Override
public void onLocationChanged(Location location) {
}
@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;
}
Alarm.Java:
@Override
public void onReceive(Context context, Intent intent) {
/** PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();**/
// Put here YOUR code.
//Intent i= new Intent(this,AlarmActivity.class);
//startActivity(i);
try {
gps = new GPSTracker(context);
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
Location CurrLoc = gps.getLocation();
Location DistLoc = new Location("wow");
DistLoc.setLatitude(32.159141);
DistLoc.setLongitude(34.922564);
float CurrDistance = CurrLoc.distanceTo(DistLoc);
SharedPreferences prefs = context.getSharedPreferences("AlarmDistanceAndUserStatus", Context.MODE_PRIVATE);
float AlarmDistance=prefs.getFloat("AlarmDistance",0);
Log.d("distance invoke alarmRe",String.valueOf(AlarmDistance));
Log.d("current distance is:",String.valueOf(CurrDistance));
// Log.d("Run once -2",String.valueOf(AlarmActivity.RUN_ONCE));
// Log.d("distance invoke alarm-2",String.valueOf(AlarmActivity.AlarmDistance));
if(CurrDistance>=0 && CurrDistance<=50){
SharedPreferences.Editor editor=prefs.edit();
editor.putBoolean("UserStatus",false);
editor.commit();
this.CancelAlarm(context);
Bundle bundle = intent.getExtras();
String message = bundle.getString("alarm_message");
Intent newIntent = new Intent(context, AlarmActivity.class);
newIntent.putExtra("alarm_message", message);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
}
else if(AlarmDistance>=CurrDistance){
Bundle bundle = intent.getExtras();
String message = bundle.getString("alarm_message");
Intent newIntent = new Intent(context, AlarmActivity.class);
newIntent.putExtra("alarm_message", message);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
}
Toast.makeText(context, "Your Location is - \nLat: " + latitude + "\nLong: " + longitude + " distanceto:" + CurrDistance + " from AlaramSet!!!", Toast.LENGTH_LONG).show();
Log.d("onReceive", "onReceive");
} catch (Exception e) {
Toast.makeText(context, "There was an error somewhere, but we still received an alarm", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
// Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example
//wl.release();
}
public void SetAlarm(Context context,int SecondsInterval) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, SecondsInterval);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, Alarm.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), (1000 * SecondsInterval), pi); // Millisec * Second * Minute
Toast.makeText(context, "Alarm Set!!!", Toast.LENGTH_LONG).show();
}
public void CancelAlarm(Context context) {
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
Toast.makeText(context, "Alarm Canceled!!!", Toast.LENGTH_LONG).show();
}
AlarmActivity.Java:
公共类AlarmActivity扩展AppCompatActivity { public static boolean RUN_ONCE = true;
GPSTracker gps;
Alarm alarm;
SharedPreferences sharedpref;
boolean UserStatus=true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm);
alarm = new Alarm();
Log.d("Run once -2", String.valueOf(RUN_ONCE));
runOnce();
sharedpref=getSharedPreferences("AlarmDistanceAndUserStatus", Context.MODE_PRIVATE);
SharedPreferences.Editor editor=sharedpref.edit();
UserStatus=sharedpref.getBoolean("UserStatus",true);
Log.d("UserStatus now is:", String.valueOf(UserStatus));
if(UserStatus){
Button OkStopButton=(Button)findViewById(R.id.OkStopButton);
OkStopButton.setVisibility(View.VISIBLE);
TextView WakeUpTimeTextView=(TextView)findViewById(R.id.WakeUpTimeTextView);
WakeUpTimeTextView.setVisibility(View.VISIBLE);
Button DidItButton=(Button)findViewById(R.id.DidItButton);
Button MissItButton=(Button)findViewById(R.id.MissItButton);
DidItButton.setVisibility(View.INVISIBLE);
MissItButton.setVisibility(View.INVISIBLE);
TextView DestArrivedTextView=(TextView)findViewById(R.id.DestArrivedTextView);
DestArrivedTextView.setVisibility(View.INVISIBLE);
}
else{
Button OkStopButton=(Button)findViewById(R.id.OkStopButton);
OkStopButton.setVisibility(View.INVISIBLE);
TextView WakeUpTimeTextView=(TextView)findViewById(R.id.WakeUpTimeTextView);
WakeUpTimeTextView.setVisibility(View.INVISIBLE);
Button DidItButton=(Button)findViewById(R.id.DidItButton);
Button MissItButton=(Button)findViewById(R.id.MissItButton);
DidItButton.setVisibility(View.VISIBLE);
MissItButton.setVisibility(View.VISIBLE);
TextView DestArrivedTextView=(TextView)findViewById(R.id.DestArrivedTextView);
DestArrivedTextView.setVisibility(View.VISIBLE);
}
}
private void runOnce() {
if (RUN_ONCE) {
RUN_ONCE = false;
gps = new GPSTracker(AlarmActivity.this);
if (gps.canGetLocation) {
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
Location loc = gps.getLocation();
Location dist = new Location("wow");
dist.setLatitude(32.159058);
dist.setLongitude(34.922536);
float FirstDistance = loc.distanceTo(dist);
Log.d("first distance",String.valueOf(FirstDistance));
//System.currentTimeMillis()
//interval time of distance check
int SecondsInterval;
if (FirstDistance >= 0 && FirstDistance <= 1000) SecondsInterval = 3;
else if (FirstDistance > 1000 && FirstDistance <= 2000) SecondsInterval = 4;
else if (FirstDistance > 2000 && FirstDistance <= 3500) SecondsInterval = 5;
else SecondsInterval = 8;
///
//check the distance to alarm user before dist. station
int MissingCount = 2;//for example-import from db
float AlarmDistance= (FirstDistance/ 10) * MissingCount;
sharedpref=getSharedPreferences("AlarmDistanceAndUserStatus",Context.MODE_PRIVATE);
SharedPreferences.Editor editor=sharedpref.edit();
editor.putFloat("AlarmDistance",AlarmDistance);
editor.putBoolean("UserStatus",true);
editor.commit();
alarm.SetAlarm(this,SecondsInterval);
Intent newIntent = new Intent(this, MainActivity.class);
this.startActivity(newIntent);
} else {
gps.showSettingsAlert();
}
}
}
public void StopOnClick(View v) {
// gps.stopUsingGPS();
RUN_ONCE = true;
sharedpref=getSharedPreferences("AlarmDistanceAndUserStatus",Context.MODE_PRIVATE);
SharedPreferences.Editor editor=sharedpref.edit();
editor.putFloat("AlarmDistance",0);
editor.putBoolean("UserStatus",true);
editor.commit();
alarm.CancelAlarm(this);
//back to Home Page
}
public void DidItOnClick(View v){
//Return to Home Page (e.g: MainActivity)
Intent newIntent = new Intent(this, MainActivity.class);
this.startActivity(newIntent);
RUN_ONCE = true;
sharedpref=getSharedPreferences("AlarmDistanceAndUserStatus",Context.MODE_PRIVATE);
SharedPreferences.Editor editor=sharedpref.edit();
editor.putFloat("AlarmDistance",0);
editor.putBoolean("UserStatus", true);
editor.commit();
}
public void MissItOnClick(View v){
//go check altenative ways
RUN_ONCE = true;
sharedpref=getSharedPreferences("AlarmDistanceAndUserStatus",Context.MODE_PRIVATE);
SharedPreferences.Editor editor=sharedpref.edit();
editor.putFloat("AlarmDistance",0);
editor.putBoolean("UserStatus",true);
editor.commit();
}
}
失败:
Unable to start activity ComponentInfo{com.example.liorozit.gpstest/com.example.liorozit.gpstest.AlarmActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'float android.location.Location.distanceTo(android.location.Location)' on a null object reference
有一个外部类,它由Intent移动到AlarmActivity类并调用它的OnCraete()。 我能做些什么来解决问题并获取我当前的位置?谢谢!
答案 0 :(得分:0)
如果您想在活动中获取位置,如果不需要在后台运行,则可以尝试此操作。
package com.jmarkstar.activitylocation;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private LocationManager locationManager;
private MyLocationListener locationListener;
private String latitude;
private String longitude;
@Override
protected void onStart() {
super.onStart();
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new MyLocationListener();
Criteria criteria = new Criteria();
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(false);
criteria.setPowerRequirement(Criteria.ACCURACY_FINE);
String bestEnabledProvider = locationManager.getBestProvider(criteria, true);
locationManager.requestLocationUpdates(bestEnabledProvider, 0, 0, locationListener);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//YOU CODE
}
private class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
makeUseOfNewLocation(location);
locationManager.removeUpdates(locationListener);
}
private void makeUseOfNewLocation(final Location location) {
if (location != null) {
String message = "position: " + location.getLatitude() + ", " + location.getLongitude() + " accuracy: " + location.getAccuracy();
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
latitude = String.valueOf(location.getLatitude());
longitude = String.valueOf(location.getLongitude());
//YOUR CODE
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onProviderDisabled(String provider) {}
}
}