Android设备是如何唤醒的

时间:2013-03-13 06:35:25

标签: android wakelock

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

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

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

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

1 个答案:

答案 0 :(得分:0)

根据我的经验,通过电话和GPS等广播Intents您可以使用BroadcastReceiver收听。该设备将清醒足够长时间播放它们。

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

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

所以:

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

  2. 您可以挂钩Intent并有时间实施自己的WakeLock

  3. 我会查看@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);
    }