有很多操作,例如周期性的和服务器Sync(Email,Cloud Service),周期性的更新下载进度,等等是比较耗电的。因此可以根据电量,是否充电,Dock状态,网络连接状态这些条件来调整更新频率,以便节省电量。
和电池相关的几个Broadcast,都是battery manager发出的:
1, ACTION_BATTERY_CHANGED
这是个sticky broadcast,并且不能在manifest中注册receiver接收这个broadcast,因为是sticky的,所以app一启动就可以收到,相当于当前的电池状态。
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter); //因为是sticky broadcast,所以receiver使用null就可以。
这个broadcast中包含很多信息,例如是否在充电,是用USB充电还是AC充电
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
status == BatteryManager.BATTERY_STATUS_FULL;
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
2,除了这个broadcast还可以接收其他一些broadcast,这些broadcast就可以在manifest中注册receiver接收了,相当于关注电池的变化。
<receiver android:name=".PowerConnectionReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/> //充电器连接
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/> //充电器断开
</intent-filter>
</receiver>
<receiver android:name=".BatteryLevelReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_BATTERY_LOW"/> //这两个用于电量的显著变化,一个是电量低,一个是不处于低电量状态了。
<action android:name="android.intent.action.ACTION_BATTERY_OKAY"/>
</intent-filter>
</receiver>
在receiver中不能处理太大的工作量,如果有大工作量要启动IntentService,而不要使用work thread。
和Dock相关的broadcast:
拿到Dock当前状态:
IntentFilter ifilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
Intent dockStatus = context.registerReceiver(null, ifilter);
后继Dock的变化:
也是接收ACTION_DOCK_EVENT
网络连接的状态
拿到当前连接状态
ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
后继状态的变化
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
注册receiver时应该注意,在manifest中注册receiver可能导致app会被频繁唤醒,所以有些receiver需要动态注册,另外还可以通过package manager把manifest中注册的组件disable或者enable:
下面的code就是enable一个receiver:myReceiver
ComponentName receiver = new ComponentName(context, myReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP)
智能调整更新频率以节省电量
本文探讨如何根据电量、充电状态、Dock状态和网络连接情况调整周期性操作的频率,如与服务器同步(电子邮件、云服务)、更新下载进度等,以节省电量。通过接收batterymanager发出的多个Broadcast,如ACTION_BATTERY_CHANGED、ACTION_POWER_CONNECTED、ACTION_POWER_DISCONNECTED、ACTION_DOCK_EVENT以及网络连接状态变化的Broadcast,实现动态调整。同时,文章强调在manifest中注册receiver可能导致app频繁唤醒,建议使用动态注册或包管理器控制receiver的启用和禁用。
1338

被折叠的 条评论
为什么被折叠?



