在服务中调用PhoneStateListener时的NullPointerExecption

时间:2015-09-14 15:16:30

标签: android mobile service fragment phone-state-listener

我有一个PhoneStateLister,我收到了大量数据,然后发送到服务器。

如果我用一个片段给听众打电话,那一切都很好,但是当我在服务中调用它时,我得到一个NullPointerException。这是我的代码:

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


}

和我的服务:

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;
}

我在片段的onResume()中启动服务:

getActivity().startService(new Intent(getActivity(), SendDataService.class));

片段开始时...这是我得到的例外:

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)

2 个答案:

答案 0 :(得分:12)

这是一个消息队列问题,你必须在调用telephonyManager.listen之前初始化looper并在之后循环。

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

答案 1 :(得分:1)

我有同样的问题。崩溃发生在MyPhoneListener类的构造方法中,该方法扩展了PhoneStateLister。但它没有任何作用。所以我通过阅读PhoneStateLister

的源代码来搜索超构造方法

PhoneStateListener.java:

public PhoneStateListener() {
  this(SubscriptionManager.DEFAULT_SUB_ID, Looper.myLooper());
}
public PhoneStateListener(long subId, Looper looper) {
  if (DBG) log("ctor: subId=" + subId + " looper=" + looper);
  mSubId = subId;
  mHandler = new Handler(looper) {
       ...........
  };
}

Handler.java:

public Handler(Looper looper) {
    this(looper, null, false);
}
public Handler(Looper looper, Callback callback, boolean async) {
    mLooper = looper;
    mQueue = looper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
}

崩溃发生在&#34; mQueue = looper.mQueue;&#34;。因为Thread t没有looper,所以looper为null。