你好,情况:
我正在开发作为运动跟踪器/导航应用的Android应用程序--因此它需要与GPS和永久唤醒设备永久连接。每秒钟录制一次。
目前的解决方案工作了多年,这要归功于wakelocks
,它让设备保持清醒。
安卓6.0+的打瞌睡模式使情况变得复杂,但事实并非如此。
对华为的设备可能是不同类型的优化。
下面是日志的一部分:
10-10 10:33:18.462 1014-384 D/PFW.HwPFWAppWakeLockPolicy: getUidWakeLock uid: 10097 wakelock >= 10 mins 10-10 10:33:18.543 1014-384 D/PFW.HwPFWAppWakeLockPolicy: force stop abnormal wakelock app uid: 10097 10-10 10:33:18.558 1014-384 I/ActivityManager: Force stopping menion.android.locus appid=10097 user=0: from pid 1014
所以在大约之后。30+分钟,系统简单地决定应用程序使用过多的wakelocks
,并完全终止它与所有服务,历史,简单的kill
。
有没有这种行为的经验和任何建议,如何更好地完成这项简单的任务(屏幕关闭时永久记录GPS位置)?
正如我在一开始所写的,除了新华为之外,在所有其他设备上,这样的系统都能正常工作很多年。
编辑:华为电池管理器中的“白名单”应用程序(标记为“受保护的应用程序”)对此问题没有影响。
发布于 2017-11-01 11:08:18
有两个华为系统应用程序可能会为了节省电池而杀死用户应用程序:
com.huawei.systemmanager
)杀死所有在屏幕关闭后仍在运行的应用程序,除非它们在“受保护的应用程序”列表中。com.huawei.powergenie
)会杀死任何长时间保持唤醒锁的应用程序。听起来你的应用程序被PowerGenie杀了。您可以利用PowerGenie的wake锁标记硬编码白名单来避免这种情况。例如,如果您的唤醒锁的标记是"LocationManagerService“,则PowerGenie将忽略它,因为系统服务持有具有相同标记的唤醒锁,并且PowerGenie已将其白化。
发布于 2017-02-11 17:35:05
您是否尝试过设置一个闹钟,定期释放WakeLock,然后在几秒钟后重新获取它?如果问题是华为的Android不喜欢滥用Wakelocks,那么如果你时不时地发布它,他们可能还好吗?例如:我想您将在前台运行一个后台进程。如果是这样,请在onStartCommand中插入:
setupWakeupAlarm(context);
其中,该方法定义为:
private static void setupWakeupAlarm(Context context) {
AlarmManager mWakeUpAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent mWakeUpAlarmIntent;
Intent serviceIntent;
serviceIntent = new Intent(context, SSAlarmReceiver.class);
mWakeUpAlarmIntent = PendingIntent.getBroadcast(context, 0, serviceIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// every 5 minutes
mWakeUpAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + WAKEUP_ALARM_FREQUENCY, mWakeUpAlarmIntent);
Log.d("TAG", "wakup alarm set up or reset!");
}
在接收者是本地类的地方:
static public class SSAlarmReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
setupWakeupAlarm(context);
mBackgroundService.stopForeground(true);
if (mWakeLock.isHeld())
mWakeLock.release();
new Timer().schedule(
new TimerTask() {
@Override
public void run() {
mWakeLock.acquire();
mBackgroundService.startForeground(mNotificationId, mNotification.getNotification());
}
},
3000
);
}
}
请注意,在我的例子中,我的后台服务也运行在前台,我决定停止前台。不确定这是必要的。
风险当然是,在3秒内,Wakelock是不活动的,您的进程可能被杀死。
https://stackoverflow.com/questions/39954822
复制相似问题