2

Android デバイスが「スリープ」モードに入る方法は 2 つあります。1 つは、画面をタイムアウトさせるだけで、自動的にオフになります。この場合、CPU がまだアプリを実行しているかどうかは明確ではありません (もちろん、部分的な wake lock がある場合を除きます)。もう 1 つのケースは、電源ボタンを押して画面が消える場合です。それが画面をタイムアウトさせるのと同じことなのかどうかは私にはわかりません。

しかし、私が本当に知りたいのは、実際に何が起こっているかです。たとえば、電源ボタンを押したときに電話がかかってくると、デバイスが起動して点灯し、電話アプリが起動します。これは、部分的なウェイク ロックで実行されている電話アプリだけですか? それともメーカーは、電話の呼び出し音を認識してスリープ モードを解除するためのカスタム ハードウェア機能を使用していますか?

私が興味を持った理由は、それがハードウェアで制御されている場合、同じように制御されている他のハードウェア関連の機能があるかどうかという疑問が生じるからです。たとえば、GPS レシーバーが有効な位置情報を受信した場合にのみデバイスをウェイクアップさせることは可能ですか?

バッテリー消費を節約するために、特定のハードウェア機能が有効になったときにデバイスを起動できると便利です。WakeLock 機能に対する私の印象は、電源ボタンのサポートが最小限のソフトウェア機能にすぎないということです。

4

1 に答える 1

0

私の経験から、電話や GPS などは、 でIntents聞くことができる放送をしますBroadcastReceiver。デバイスは、それらをブロードキャストするのに十分な時間、起動しています。

(技術的には、Android ファームウェアはデバイスの電力レベルを処理し、特定の機能にウェイクロックを提供します。これにより、ハードウェア信号によってコードの実行が許可されるように見えますが、実際にはハードウェア信号によって Android の実行が許可され、コードの実行が許可されます。 .)

BroadcastReceiverしたがって、これらのインテントに登録すると、サブクラス内で通知されます。デバイスは、受信機内で短時間起動します。これは、制御して独自の を作成するのに十分な時間ですWakeLock

そう:

  1. デバイスには、あなたが求めている機能があります-具体的には、完全にハードウェアではなく、Android ファームウェアによって制御されます。これは、ファームウェアのリリースが異なれば、動作が異なる可能性があることを意味します。これは、さまざまなデバイスの GPS 追跡アプリでデバッグ ログ出力を監視している場合 (ファームウェア GPS がどのように使用されているかを監視している場合) に非常に明白です。

  2. をフックすることができIntent、独自の を実装する時間がありますWakeLock

@CommonswareのWakefulIntentServiceをチェックして、それを利用します。

そうでなければ、彼はそれについての非常に良い情報を彼の本に書いています.


BroadcastReceiverからの更新をリッスンするために使用する例LocationProvider

これは製品コードを改変したサンプル コードです。一部を削除しましたが、特別なコードがなくてもこのレシーバーが動作することを示すために残しています。

/**
 * Receives broadcasts from the {@link LocationProvider}s. The providers
 * hold a {@link PowerManager.WakeLock} while this code executes. The
 * {@link MyService} code needs to also hold a WakeLock for code that
 * is executed outside of this BroadcastReceiver.
 */
private BroadcastReceiver locationEventReceiver = new BroadcastReceiver()
{

    @Override
    public void onReceive(Context context, Intent intent)
    {
        // get location info
        Bundle extras = intent.getExtras();
        if (extras != null)
        {
            Log.d("mobiRic", "LOCATION RECEIVER CALLBACK");

            // check if this is a new location
            Location location = (Location) extras
                .get(android.location.LocationManager.KEY_LOCATION_CHANGED);
            Log.d("mobiRic", "  - intent = [" + intent + "]");
            Log.d("mobiRic", "  - location = [" + location + "]");
            if (location != null)
            {
                updateCurrentLocation(location, false);
            }
        }
    }
};

BroadcastReceiverGPS イベントを取得するための設定方法の例

Service場所イベントを確実に取得するために使用する 2 つの (編集済み) メソッドを次に示します。

/**
 * Starts listening for {@link LocationManager#GPS_PROVIDER} location
 * updates.
 */
void doStartLocationListeningGps()
{
    Intent intent = new Intent("MY_INTENT_GPS");
    PendingIntent pendingIntentGps = PendingIntent.getBroadcast(getApplicationContext(),
        action.hashCode(), intent, PendingIntent.FLAG_UPDATE_CURRENT);

    getLocationManager().requestLocationUpdates(LocationManager.GPS_PROVIDER,
        LOCATION_UPDATE_TIME_GPS, 0, pendingIntentGps);
}


/**
 * Registers the {@link #locationEventReceiver} to receive location events.
 */
void registerLocationReceiver()
{
    IntentFilter filter = new IntentFilter();

    /* CUSTOM INTENTS */
    filter.addAction("MY_INTENT_GPS");
    registerReceiver(locationEventReceiver, filter);
}
于 2013-03-13T06:46:13.553 に答える