问题
I have a test screen where there is a button - where it is pressed it calls the service. I'm trying to implement a way to get the current gps location of the current user and it is crashing when it tries to call. Can anyone tell what the problem is?
package com.example.whereyouapp;
import java.util.Arrays;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.telephony.SmsManager;
import android.widget.Toast;
public class Controller extends Service{
private static final int POLL_INTERVAL = 1000 *3;
static int number_of_times=0;
Location location;
// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
makeUseOfNewLocation(location);
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
public void makeUseOfNewLocation(Location location){
this.location=location;
}
public static double coordinatesDistance(double lat1, double lon1, double lat2, double lon2){//returns distance in kilometers between two coordiantes
double deltaLat = Math.toRadians(lat2-lat1);
double deltaLong = Math.toRadians(lon2 - lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) + Math.sin(deltaLong / 2) * Math.sin(deltaLong / 2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.asin(Math.sqrt(a));
return 6371 * c;
}
public int onStartCommand(Intent intent,int flags, int startId){
Toast.makeText(this, "yololo- the service class works", Toast.LENGTH_SHORT).show();
//sendSMS("5613500110","If you received this text message then the Service class for WhereYouApp works");
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1, 0, locationListener);
if(location!=null){
double distance=coordinatesDistance(location.getLatitude(),location.getLatitude(),location.getLatitude()+2,location.getLatitude()+2);
Toast.makeText(this, ""+distance, Toast.LENGTH_SHORT).show();
}
if(number_of_times==5){
setServiceAlarm(getBaseContext(),false);
number_of_times=-1;
}
number_of_times++;
return START_STICKY;
}
public void onDestroy(){
super.onDestroy();
Toast.makeText(this, "yolo- the service has stopped working", Toast.LENGTH_LONG).show();
}
public void sendSMS(String phoneNumber, String message) {
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, null, null);
ContentValues values = new ContentValues();
values.put("address", phoneNumber);
values.put("body", message);
getContentResolver().insert(Uri.parse("content://sms/sent"), values);
}
public static void setServiceAlarm(Context context, boolean isOn){
Intent i = new Intent(context, Controller.class);
PendingIntent pi = PendingIntent.getService(context, 0, i, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
if (isOn) {
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), POLL_INTERVAL, pi);
} else {
alarmManager.cancel(pi);
pi.cancel();
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
This class will be used to test controller functions, it will consist of a screen with buttons that do various functions
package com.example.whereyouapp;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.telephony.SmsManager;
import android.view.Menu;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.content.ContentValues;
import android.content.Intent;
import android.graphics.PorterDuff;
import android.view.View;
import android.widget.Button;
public class ControllerTestingScreen extends Activity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_controller_test_screen);
//Set button colors to red, green, blue, and red, respectively
Button button = (Button) findViewById(R.id.testbutton);
button.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
OnClickListener buttonListener = new View.OnClickListener(){
public void onClick(View arg0) {
Controller.setServiceAlarm(getBaseContext(), true);
}
};
button.setOnClickListener(buttonListener);
}
}
Logcat:
02-26 22:04:38.317: D/AndroidRuntime(1427): Shutting down VM
02-26 22:04:38.317: W/dalvikvm(1427): threadid=1: thread exiting with uncaught exception (group=0xb1a91ba8)
02-26 22:04:38.457: D/dalvikvm(1427): GC_FOR_ALLOC freed 115K, 6% free 3270K/3460K, paused 87ms, total 103ms
02-26 22:04:38.497: E/AndroidRuntime(1427): FATAL EXCEPTION: main
02-26 22:04:38.497: E/AndroidRuntime(1427): Process: com.example.whereyouapp, PID: 1427
02-26 22:04:38.497: E/AndroidRuntime(1427): java.lang.RuntimeException: Unable to instantiate service com.example.whereyouapp.Controller: java.lang.NullPointerException
02-26 22:04:38.497: E/AndroidRuntime(1427): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2556)
02-26 22:04:38.497: E/AndroidRuntime(1427): at android.app.ActivityThread.access$1800(ActivityThread.java:135)
02-26 22:04:38.497: E/AndroidRuntime(1427): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
02-26 22:04:38.497: E/AndroidRuntime(1427): at android.os.Handler.dispatchMessage(Handler.java:102)
02-26 22:04:38.497: E/AndroidRuntime(1427): at android.os.Looper.loop(Looper.java:136)
02-26 22:04:38.497: E/AndroidRuntime(1427): at android.app.ActivityThread.main(ActivityThread.java:5017)
02-26 22:04:38.497: E/AndroidRuntime(1427): at java.lang.reflect.Method.invokeNative(Native Method)
02-26 22:04:38.497: E/AndroidRuntime(1427): at java.lang.reflect.Method.invoke(Method.java:515)
02-26 22:04:38.497: E/AndroidRuntime(1427): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-26 22:04:38.497: E/AndroidRuntime(1427): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-26 22:04:38.497: E/AndroidRuntime(1427): at dalvik.system.NativeStart.main(Native Method)
02-26 22:04:38.497: E/AndroidRuntime(1427): Caused by: java.lang.NullPointerException
02-26 22:04:38.497: E/AndroidRuntime(1427): at android.content.ContextWrapper.getSystemService(ContextWrapper.java:540)
02-26 22:04:38.497: E/AndroidRuntime(1427): at com.example.whereyouapp.Controller.<init>(Controller.java:30)
02-26 22:04:38.497: E/AndroidRuntime(1427): at java.lang.Class.newInstanceImpl(Native Method)
02-26 22:04:38.497: E/AndroidRuntime(1427): at java.lang.Class.newInstance(Class.java:1208)
02-26 22:04:38.497: E/AndroidRuntime(1427): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2553)
02-26 22:04:38.497: E/AndroidRuntime(1427): ... 10 more
02-26 22:04:45.187: I/Process(1427): Sending signal. PID: 1427 SIG: 9
02-26 22:04:47.507: D/AndroidRuntime(1469): Shutting down VM
02-26 22:04:47.507: W/dalvikvm(1469): threadid=1: thread exiting with uncaught exception (group=0xb1a91ba8)
02-26 22:04:47.517: E/AndroidRuntime(1469): FATAL EXCEPTION: main
02-26 22:04:47.517: E/AndroidRuntime(1469): Process: com.example.whereyouapp, PID: 1469
02-26 22:04:47.517: E/AndroidRuntime(1469): java.lang.RuntimeException: Unable to instantiate service com.example.whereyouapp.Controller: java.lang.NullPointerException
02-26 22:04:47.517: E/AndroidRuntime(1469): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2556)
02-26 22:04:47.517: E/AndroidRuntime(1469): at android.app.ActivityThread.access$1800(ActivityThread.java:135)
02-26 22:04:47.517: E/AndroidRuntime(1469): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
02-26 22:04:47.517: E/AndroidRuntime(1469): at android.os.Handler.dispatchMessage(Handler.java:102)
02-26 22:04:47.517: E/AndroidRuntime(1469): at android.os.Looper.loop(Looper.java:136)
02-26 22:04:47.517: E/AndroidRuntime(1469): at android.app.ActivityThread.main(ActivityThread.java:5017)
02-26 22:04:47.517: E/AndroidRuntime(1469): at java.lang.reflect.Method.invokeNative(Native Method)
02-26 22:04:47.517: E/AndroidRuntime(1469): at java.lang.reflect.Method.invoke(Method.java:515)
02-26 22:04:47.517: E/AndroidRuntime(1469): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-26 22:04:47.517: E/AndroidRuntime(1469): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-26 22:04:47.517: E/AndroidRuntime(1469): at dalvik.system.NativeStart.main(Native Method)
02-26 22:04:47.517: E/AndroidRuntime(1469): Caused by: java.lang.NullPointerException
02-26 22:04:47.517: E/AndroidRuntime(1469): at android.content.ContextWrapper.getSystemService(ContextWrapper.java:540)
02-26 22:04:47.517: E/AndroidRuntime(1469): at com.example.whereyouapp.Controller.<init>(Controller.java:30)
02-26 22:04:47.517: E/AndroidRuntime(1469): at java.lang.Class.newInstanceImpl(Native Method)
02-26 22:04:47.517: E/AndroidRuntime(1469): at java.lang.Class.newInstance(Class.java:1208)
02-26 22:04:47.517: E/AndroidRuntime(1469): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2553)
02-26 22:04:47.517: E/AndroidRuntime(1469): ... 10 more
回答1:
I did some changes in your code and finally got a working code.
public class Controller extends Service
{
private static final int POLL_INTERVAL = 1000 *3;
static int number_of_times=0;
Location currentLocation;
static LocationManager locationManager;
// Define a listener that responds to location updates
LocationListener locationListenerGps = new LocationListener()
{
public void onLocationChanged(Location location)
{
currentLocation = location;
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
public static double coordinatesDistance(double lat1, double lon1, double lat2, double lon2)
{
//returns distance in kilometers between two coordiantes
double deltaLat = Math.toRadians(lat2-lat1);
double deltaLong = Math.toRadians(lon2 - lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) + Math.sin(deltaLong / 2) * Math.sin(deltaLong / 2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.asin(Math.sqrt(a));
return 6371 * c;
}
public int onStartCommand(Intent intent,int flags, int startId)
{
Toast.makeText(this, "yololo- the service class works", Toast.LENGTH_SHORT).show();
//sendSMS("5613500110","If you received this text message then the Service class for WhereYouApp works");
if ( locationManager != null )
{
System.out.println ( "not null" );
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerGps);
}
if( currentLocation != null )
{
double distance=coordinatesDistance(currentLocation.getLatitude(),currentLocation.getLatitude(),currentLocation.getLatitude()+2,currentLocation.getLatitude()+2);
Toast.makeText(this, ""+distance, Toast.LENGTH_SHORT).show();
}
else
{
System.out.println ( "location not found" );
}
if(number_of_times==5)
{
setServiceAlarm(getBaseContext(),false);
number_of_times=-1;
}
number_of_times++;
return START_NOT_STICKY;
}
public void onDestroy()
{
super.onDestroy();
Toast.makeText(this, "yolo- the service has stopped working", Toast.LENGTH_LONG).show();
}
public void sendSMS(String phoneNumber, String message)
{
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, null, null);
ContentValues values = new ContentValues();
values.put("address", phoneNumber);
values.put("body", message);
getContentResolver().insert(Uri.parse("content://sms/sent"), values);
}
public static void setServiceAlarm(Context context, boolean isOn)
{
// Acquire a reference to the system Location Manager
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
Intent i = new Intent(context, Controller.class);
PendingIntent pi = PendingIntent.getService(context, 0, i, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
if (isOn)
{
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(), POLL_INTERVAL, pi);
}
else
{
alarmManager.cancel(pi);
pi.cancel();
}
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
}
This code perfectly runs on my Samsung device.
回答2:
You are getting a NPE on this line
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
because your Context is null since the Service hasn't actually been created yet. Move that line inside onStartCommand().
Much like an Activity, there is no Context until it has been started. With an Activity, not before onCreate() has run and, with a Service, it wouldn't be available until onCreate() or onStartCommand().
See this answer on how to read your logcat. It will take you a long way.
来源:https://stackoverflow.com/questions/22058169/nullpointerexception-while-fetching-current-gps