getlastknownlocation()返回null,App正在关闭

时间:2016-06-09 17:46:23

标签: android gps location

我试图在几秒钟内获取当前位置,我使用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()。 我能做些什么来解决问题并获取我当前的位置?谢谢!

1 个答案:

答案 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) {}
    }
}