位置服务GPS强制closures

嗨,我开发一个应用程序来find最好的位置和短信到一个数字。 其工作正常与networking位置,但是当我想定位与GPS或标准类它的成为力量closures! 它如此友善地帮助我tnx。

package ir.M410.toolkit; import android.app.Service; import android.content.Intent; import android.location.Criteria; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.os.IBinder; import android.telephony.SmsManager; import android.util.Log; public class LocationFinder extends Service implements LocationListener{ double lat ,lon ; @Override public IBinder onBind(Intent arg0) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { // We want this service to continue running until it is explicitly // stopped, so return sticky. LocationManager mlocationManager = (LocationManager) getSystemService(LOCATION_SERVICE); Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setPowerRequirement(Criteria.POWER_MEDIUM); String locationprovider = mlocationManager.getBestProvider(criteria, true); Location mlocation = mlocationManager.getLastKnownLocation(locationprovider); lat = mlocation.getLatitude (); lon = mlocation.getLongitude (); Log.i("Geo_Location", "Latitude: " + lat + ", Longitude: " + lon); SmsManager sms = SmsManager.getDefault(); sms.sendTextMessage("+11231233213", null,"https://maps.google.com/maps?q="+lat+","+lon, null, null); // SmsManager sms = SmsManager.getDefault(); //sms.sendTextMessage(MainActivity.senderNum, null," "+"lat:"+lat+" "+"lon:"+lon, null, null); //stopSelf(); return START_NOT_STICKY; } @Override public void onLocationChanged(Location location) { // TODO Auto-generated method stub lat= location.getLatitude(); lon =location.getLongitude(); Log.i("Geo_Location", "Latitude: " + lat + ", Longitude: " + lon); // stopSelf(); } @Override public void onProviderDisabled(String provider) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) { // TODO Auto-generated method stub } @Override public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } @Override public void onDestroy() { super.onDestroy(); } } 

这是我的清单:

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ir.M410.toolkit" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.RECEIVE_SMS" > </uses-permission> <uses-permission android:name="android.permission.READ_SMS" > </uses-permission> <uses-permission android:name="android.permission.SEND_SMS" > </uses-permission> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" > </uses-permission> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" > </uses-permission> <uses-permission android:name="android.permission.CALL_PHONE" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <receiver android:name="ir.M410.toolkit.Broadcast_Receiver" > <intent-filter android:priority="2147483647" > <action android:name="android.intent.action.PHONE_STATE" /> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> <action android:name="ir.M410.toolkit.android.action.broadcast" /> </intent-filter> </receiver> <service android:name="ir.M410.toolkit.LocationFinder" /> <activity android:name="ir.M410.toolkit.PasswordCheck" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="ir.M410.toolkit.MainActivity" android:label="@string/title_activity_main" android:screenOrientation="portrait" > </activity> <activity android:name="ir.M410.toolkit.Teturial" android:label="@string/title_activity_teturial" > </activity> <activity android:name="ir.M410.toolkit.CallDivertActivity" android:label="@string/title_activity_call_divert" > </activity> </application> </manifest> 

[编辑]这里是LogCat的定义:

 10-14 19:58:37.823: E/AndroidRuntime(2685): FATAL EXCEPTION: main 10-14 19:58:37.823: E/AndroidRuntime(2685): java.lang.RuntimeException: Unable to start service ir.M410.toolkit.LocationFinder@4482e4a8 with Intent { cmp=ir.M410.toolkit/.LocationFinder }: java.lang.NullPointerException 10-14 19:58:37.823: E/AndroidRuntime(2685): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3260) 10-14 19:58:37.823: E/AndroidRuntime(2685): at android.app.ActivityThread.access$3600(ActivityThread.java:135) 10-14 19:58:37.823: E/AndroidRuntime(2685): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2205) 10-14 19:58:37.823: E/AndroidRuntime(2685): at android.os.Handler.dispatchMessage(Handler.java:99) 10-14 19:58:37.823: E/AndroidRuntime(2685): at android.os.Looper.loop(Looper.java:143) 10-14 19:58:37.823: E/AndroidRuntime(2685): at android.app.ActivityThread.main(ActivityThread.java:4914) 10-14 19:58:37.823: E/AndroidRuntime(2685): at java.lang.reflect.Method.invokeNative(Native Method) 10-14 19:58:37.823: E/AndroidRuntime(2685): at java.lang.reflect.Method.invoke(Method.java:521) 10-14 19:58:37.823: E/AndroidRuntime(2685): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 10-14 19:58:37.823: E/AndroidRuntime(2685): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 10-14 19:58:37.823: E/AndroidRuntime(2685): at dalvik.system.NativeStart.main(Native Method) 10-14 19:58:37.823: E/AndroidRuntime(2685): Caused by: java.lang.NullPointerException 10-14 19:58:37.823: E/AndroidRuntime(2685): at ir.M410.toolkit.LocationFinder.onStartCommand(LocationFinder.java:38) 10-14 19:58:37.823: E/AndroidRuntime(2685): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3246) 10-14 19:58:37.823: E/AndroidRuntime(2685): ... 10 more 

[编辑]代码检查不为空:

 @Override public int onStartCommand(Intent intent, int flags, int startId) { // We want this service to continue running until it is explicitly // stopped, so return sticky. LocationManager mlocationManager = (LocationManager) getSystemService(LOCATION_SERVICE); Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setPowerRequirement(Criteria.POWER_MEDIUM); String locationprovider = mlocationManager.getBestProvider(criteria, true); if(mlocationManager.getLastKnownLocation(locationprovider)!=null){ Location mlocation = mlocationManager.getLastKnownLocation(locationprovider); lat = mlocation.getLatitude (); lon = mlocation.getLongitude (); Log.i("Geo_Location", "Latitude: " + lat + ", Longitude: " + lon); SmsManager sms = SmsManager.getDefault(); sms.sendTextMessage("+11231233213", null,"https://maps.google.com/maps?q="+lat+","+lon, null, null); } 

它的好,没有得到强制closures,但没有收到数据,它总是为空!

我从http://www.androidhive.info/2012/07/android-gps-location-manager-tutorial/实现了我自己的GPSTracker类的版本;

使用此function,您可以打开GPS并在有效位置可用时立即收到回叫。 这可能需要一些时间,取决于设备的位置,但会提供一个更加精确和可靠的位置。

通过我的实现,你可以做这样的事情:

 private GPSTracker gps; private FirstFixListener firstFixListener; private LocationUpdateListener locationUpdateListener; private void sendGPStoSMS() { gps = GPSTracker.getInstance(context); firstFixListener = new MyFirstFixListener(); locationUpdateListener = new MyLocationUpdateListener(); gps.startUsingGPS(firstFixListener, locationUpdateListener); } private class MyFirstFixListener implements FirstFixListener { @Override public void onFirsFixChanged(boolean hasGPSfix) { if (hasGPSfix == true) { Location position = gps.getLocation(); // send SMS with position // stop the gps and unregister callbacks gps.stopUsingGPS(firstFixListener, locationUpdateListener); } } } private class MyLocationUpdateListener implements LocationUpdateListener { @Override public void onLocationChanged(Location location) { // hand you each new location from the GPS // you do not need this as you only want to send a single position } } 

这里是我的GPSTracker的实现:

 public class GPSTracker extends Service implements LocationListener { private static final String TAG = "GPSTracker"; /** * Register to receive callback on first fix status * * @author Morten * */ public interface FirstFixListener { /** * Is called whenever gps register a change in first-fix availability * This is valuable to prevent sending invalid locations to the server. * * @param hasGPSfix */ public void onFirsFixChanged(boolean hasGPSfix); } /** * Register to receive all location updates * * @author Morten * */ public interface LocationUpdateListener { /** * Is called every single time the GPS unit register a new location * The location param will never be null, however, it can be outdated if hasGPSfix is not true. * * @param location */ public void onLocationChanged(Location location); } private Context mContext; // flag for GPS status private List<FirstFixListener> firstFixListeners; private List<LocationUpdateListener> locationUpdateListeners; boolean isGPSFix = false; boolean isGPSEnabled = false; private GPSFixListener gpsListener; // flag for GPS status boolean canGetLocation = false; Location location; // location double latitude; // latitude double longitude; // longitude long mLastLocationMillis; private boolean logLocationChanges; // Declaring a Location Manager protected LocationManager locationManager; /** removed again as we need multiple instances with different callbacks **/ private static GPSTracker instance; public static GPSTracker getInstance(Context context) { if (instance != null) { return instance; } return instance = new GPSTracker(context); } private GPSTracker(Context context) { this.mContext = context; gpsListener = new GPSFixListener(); firstFixListeners = new ArrayList<GPSTracker.FirstFixListener>(); locationUpdateListeners = new ArrayList<GPSTracker.LocationUpdateListener>(); } public boolean hasGPSFirstFix() { return isGPSFix; } private void addFirstFixListener(FirstFixListener firstFixListener) { this.firstFixListeners.add(firstFixListener); } private void addLocationUpdateListener( LocationUpdateListener locationUpdateListener) { this.locationUpdateListeners.add(locationUpdateListener); } private void removeFirstFixListener(FirstFixListener firstFixListener) { this.firstFixListeners.remove(firstFixListener); } private void removeLocationUpdateListener( LocationUpdateListener locationUpdateListener) { this.locationUpdateListeners.remove(locationUpdateListener); } public void setLogLocationChanges(boolean logLocationChanges) { this.logLocationChanges = logLocationChanges; } public Location getLocation() { return location; } private Location startLocationListener() { canGetLocation = false; try { locationManager = (LocationManager) mContext .getSystemService(Service.LOCATION_SERVICE); // getting GPS status isGPSEnabled = locationManager .isProviderEnabled(LocationManager.GPS_PROVIDER); if (isGPSEnabled) { if (location == null) { locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, this); locationManager.addGpsStatusListener(gpsListener); if (locationManager != null) { location = locationManager .getLastKnownLocation(LocationManager.GPS_PROVIDER); if (location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); } } } } else { showSettingsAlert(); } } catch (Exception e) { e.printStackTrace(); } return location; } public void stopUsingGPS(FirstFixListener firstFixListener, LocationUpdateListener locationUpdateListener) { if (firstFixListener != null) removeFirstFixListener(firstFixListener); if (locationUpdateListener != null) removeLocationUpdateListener(locationUpdateListener); stopUsingGPS(); } /** * Stop using GPS listener Calling this function will stop using GPS in your * app * */ public void stopUsingGPS() { Log.d("DEBUG", "GPS stop"); if (locationManager != null) { locationManager.removeUpdates(GPSTracker.this); location = null; if (gpsListener != null) { locationManager.removeGpsStatusListener(gpsListener); } } isGPSFix = false; location = null; } public void startUsingGPS(FirstFixListener firstFixListener, LocationUpdateListener locationUpdateListener) { Log.d("DEBUG", "GPS start"); if (firstFixListener != null) addFirstFixListener(firstFixListener); if (locationUpdateListener != null) addLocationUpdateListener(locationUpdateListener); startLocationListener(); } /** * Function to get latitude * */ public double getLatitude() { if (location != null) { latitude = location.getLatitude(); } else { Log.e("GPSTracker", "getLatitude location is null"); } // return latitude return latitude; } /** * Function to get longitude * */ public double getLongitude() { if (location != null) { longitude = location.getLongitude(); } else { Log.e("GPSTracker", "getLongitude location is null"); } // 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 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) { if ( location == null) return; this.location = location; mLastLocationMillis = SystemClock.elapsedRealtime(); canGetLocation = true; if (isGPSFix) { if (locationUpdateListeners != null) { for (LocationUpdateListener listener : locationUpdateListeners) { listener.onLocationChanged(location); } } } } @Override public void onProviderDisabled(String provider) { canGetLocation = false; } @Override public void onProviderEnabled(String provider) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public IBinder onBind(Intent arg0) { return null; } private boolean wasGPSFix = false; // http://stackoverflow.com/questions/2021176/how-can-i-check-the-current-status-of-the-gps-receiver // answer from soundmaven private class GPSFixListener implements GpsStatus.Listener { public void onGpsStatusChanged(int event) { switch (event) { case GpsStatus.GPS_EVENT_SATELLITE_STATUS: isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000; if (isGPSFix != wasGPSFix) { // only notify on changes wasGPSFix = isGPSFix; for (FirstFixListener listener : firstFixListeners) { listener.onFirsFixChanged(isGPSFix); } } break; case GpsStatus.GPS_EVENT_FIRST_FIX: // Do something. break; } } } }