NullPointerExecption when calling a PhoneStateListener in a service

user2492806 picture user2492806 · Sep 14, 2015 · Viewed 11.4k times · Source

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)

Answer

Kvant picture Kvant · Dec 31, 2015

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();