2

BroadcastRecieverPHONE_STATE をリッスンする単純なアプリを作成しています。

        <receiver android:name=".PhoneStateBroadcastReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>
        </receiver>

では、状態がBroadcastRecieveronRecieve()ときにサービスを開始し、状態がOFFHOOKのときにサービスを停止しますIDLE

public class PhoneStateBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        Bundle bundle = intent.getExtras();

        String state = bundle.getString(TelephonyManager.EXTRA_STATE);
        if(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
            context.startService(new Intent(context, ProximityService.class));
        }
        else if(state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
            context.stopService(new Intent(context, ProximityService.class));
        }
    }

}

このサービスでは、近接センサー リスナーを登録しWakeLock、通話中に画面がオフになるように作成しています。呼び出しが終了したら、サービスを停止し、そのonDestroy()中でリスナーの登録を解除してWakeLock. しかし、アプリから大量のバッテリーが消耗しているため (30%)、何かがリリースされていないようです。

WakeLockリスナーの登録解除とリリース時にログを入れたところ、リリースWakeLockされてリスナーが正常に登録解除されたことがわかります(リスナーが登録解除されたというログも表示されますSensorManager)。

ここで何が欠けていますか?それは本当に迷惑です。

サービスのコード:

public int onStartCommand(Intent intent, int flags, int startId){

    Log.d("CALL", "Service started");

    // Get an instance of the sensor service, and use that to get an instance of
    // a particular sensor.
    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);

    mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);

    mAudioManager = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);

    mPowerMngr = (PowerManager) getSystemService(Context.POWER_SERVICE);
    try{
        mWakeLock = mPowerMngr.newWakeLock(PROXIMITY_SCREEN_OFF_WAKE_LOCK, "Proximity");

        if (!mWakeLock.isHeld()) {
            Log.d("CALL", "Wake lock acquired");
            mWakeLock.acquire();
        }
    }
    catch (Exception e){
        mWakeLock = null;
    }


    return START_STICKY;
}

public void onDestroy(){
    super.onDestroy();
    mSensorManager.unregisterListener(this);

    if (mWakeLock != null) {
        if (mWakeLock.isHeld()) {
            Log.d("CALL", "Wake lock released");
            mWakeLock.release();
        }
    }


            Log.d("CALL", "Service stopped");
    }

私が見るログ:

09-30 03:35:09.120: D/SensorManager(21565): unregisterListener:: disable all sensors for this listener,  listener = com.eladaharon.android.proximity.ProximityService@41a31a18
09-30 03:35:09.125: D/CALL(21565): Wake lock released
09-30 03:35:09.125: D/CALL(21565): Service stopped

どうもありがとう!エラド

4

1 に答える 1

1

サービスが複数のインテントを受け取っている場合、コードは実行されるWakeLockたびに新しいインテントを作成します。onStartCommandあなたは最後のものだけを解放しWakeLock、他のものを漏らし、バッテリーの消耗を説明します. Logcat は通常、この状況で役立つメッセージを提供します。

サービスはしばらく実行されているため、 をmWakeLock呼び出す前に が初期化されているかどうかを確認できますnewWakeLock()

于 2012-09-30T02:11:30.273 に答える