问题
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