2

Android 设备可以通过两种方式进入“睡眠”模式。一种是让屏幕超时并自动关闭。在这种情况下,不清楚 CPU 是否仍在运行应用程序(当然,除非它们具有部分唤醒锁定)。另一种情况是当您按下电源按钮并且屏幕熄灭时。我不清楚这是否与让屏幕超时相同。

但我真正想知道的是真正发生了什么。例如,如果我按下电源按钮但有电话打进来,设备将唤醒并亮起并启动电话应用程序。这只是带有部分唤醒锁定功能的手机应用程序,还是制造商使用自定义硬件功能来识别手机响铃并使其退出睡眠模式?

我之所以感兴趣是因为如果它是硬件控制的,那么出现的问题是是否有其他硬件相关的功能以同样的方式控制。例如,GPS 接收器是否有可能保持活动状态但仅在接收到有效位置时才唤醒设备?

为了节省电池消耗,如果我们可以在某些硬件功能被激活时唤醒设备,那就太好了。我对 WakeLock 功能的印象是它只是一个软件功能,对电源按钮的支持很少。

4

1 回答 1

0

根据我的经验,电话和 GPS 等会广播Intents,您可以使用BroadcastReceiver. 该设备将保持足够长的时间来广播它们。

(从技术上讲,Android 固件处理设备的功率级别,并为某些功能提供唤醒锁。这给人的印象是硬件信号允许您的代码运行,但实际上硬件信号允许 Android 运行,这允许您的代码运行.)

因此,您将注册这些意图并在您的BroadcastReceiver子类中收到通知。设备将在您的接收器内短暂唤醒,足够长的时间让您控制并创建自己的WakeLock.

所以:

  1. 该设备确实具有您所追求的功能 - 尽管具体来说它是由 Android 固件控制的,而不是完全由硬件控制。这意味着不同的固件版本可以做不同的事情。在不同设备上查看 GPS 跟踪应用程序上的调试日志输出时,这一点非常明显——查看固件 GPS 的使用情况。

  2. 你可以 hookIntent并且会有时间实现你自己的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);
            }
        }
    }
};

我如何设置BroadcastReceiver获取 GPS 事件的示例

这是我用来确保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 回答