I've got a PhoneStateLister
where I get a bunch of data and I send to a server.
If I call the listener in a fragment, it's all good, but when I'm calling it in a service, I get a NullPointerException
.Here is my code:
PhoneStateListener:
public class CarrierStateListener extends PhoneStateListener {
private Context context;
private TelephonyManager telephonyManager;
private String carrierName;
private int mSignalStrength = 0;
private int mCellTowerID = 0;
private int mCellTowerAreCode = 0;
private int mcc = 0;
private int mnc = 0;
public CarrierStateListener(Context context) {
this.context = context;
}
/**
* Get the Signal strength from the provider, each time there is an update
*/
@Override
public void onSignalStrengthsChanged(final SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
GsmCellLocation loc = (GsmCellLocation) telephonyManager.getCellLocation();
String networkOperator = telephonyManager.getNetworkOperator();
/** Retrieving the carrier name **/
carrierName = telephonyManager.getNetworkOperatorName();
UserInformation.getSingleton(context).setNetwork(carrierName);
/** Retrieving the RSSI value **/
mSignalStrength = signalStrength.getGsmSignalStrength();
mSignalStrength = (2 * mSignalStrength) - 113; // -> dBm
UserInformation.getSingleton(context).setRssi(String.valueOf(mSignalStrength));
/** Retrieve the cell tower id (CID) and the LAC (location area code) **/
mCellTowerID = loc.getCid();
mCellTowerAreCode = loc.getLac();
UserInformation.getSingleton(context).setCellId(String.valueOf(loc.getCid()));
/**tower mobile network code (mnc) and mobile country code (mcc) **/
if (networkOperator != null) {
mcc = Integer.parseInt(networkOperator.substring(0, 3));
mnc = Integer.parseInt(networkOperator.substring(3));
UserInformation.getSingleton(context).setMnc(String.valueOf(mnc));
UserInformation.getSingleton(context).setMcc(String.valueOf(mcc));
} else {
Toast.makeText(context, "Couldn't retrieve mnc and mcc because network operator is "
+ networkOperator, Toast.LENGTH_SHORT).show();
}
}
and My Service:
public class SendDataService extends Service {
private static final String TAG = "SendDataService";
private Thread t;
private TelephonyManager telephonyManager;
private CarrierStateListener pslistener;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SendDataService");
wl.acquire();
t = new Thread() {
@Override
public void run() {
while (true) {
try {
Log.e(TAG, "sending data...");
//post request to send data
Thread.sleep(6000);
} catch (InterruptedException ie) {
}
}
}
};
t.start();
Log.e(TAG, "the SendDataService started");
return START_STICKY;
}
and I start the Service in onResume() of a fragment:
getActivity().startService(new Intent(getActivity(), SendDataService.class));
when the fragment starts...this is the EXCEPTION I get:
09-14 16:11:05.034 21697-21697/? E/CallDataService﹕ the SendDataService started
09-14 16:11:05.036 21697-21729/? E/CallDataService﹕ sending data...
09-14 16:11:05.037 21697-21729/? E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-2445
Process: xxxxxxxx, PID: 21697
java.lang.NullPointerException: Attempt to read from field
'android.os.MessageQueue android.os.Looper.mQueue' on a null object reference
at android.os.Handler.<init>(Handler.java:229)
at android.os.Handler.<init>(Handler.java:137)
at android.telephony.PhoneStateListener$1.<init>(PhoneStateListener.java:270)
at android.telephony.PhoneStateListener.<init>(PhoneStateListener.java:270)
at android.telephony.PhoneStateListener.<init>(PhoneStateListener.java:240)
at xxxxxxxxxxxxx.CarierStateListener.<init>(CarierStateListener.java:27)
at xxxxxxxxx.SendDataService.listenForEvents(SendDataService.java:96)
at xxxxxx.util.SendDataService.access$000(SendDataService.java:25)
at xxxxxxxxxx.util.SendDataService$1.run(SendDataService.java:53)
This is a message queue problem you have to initialize the looper before calling telephonyManager.listen and loop afterwards.
new Thread(new Runnable() {
@Override
public void run() {
quitLooper = false;
Looper.prepare();
tManager.listen(new PhoneStateListener() {
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
lastSignalStrength = signalStrength;
if(quitLooper)
Looper.myLooper().quit();
}
}, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
Looper.loop();
}
}).start();