PowerManager的wakelock不是从服务中唤醒设备最多最多、是从、设备、PowerManager

2023-09-12 10:36:41 作者:我会腻你何必i

我有一个应用程序,具有运行每分钟后台服务。我希望服务唤醒设备,如果它是睡着了。我使用的是电源管理器,但该设备不醒来。任何想法,为什么?先谢谢了。

  @覆盖
保护无效onHandleIntent(意向意图){
    电源管理器PM =(电源管理器)getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock WL = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK,
            我的标签);
    wl.acquire();
    //做工作设备是醒着
    wl.release();
}
 

这就是我从活动启动该服务。

  //获取当前时间日历对象
日历CAL = Calendar.getInstance();
//添加5分钟到日历对象
cal.add(Calendar.MINUTE,1);
意向意图=新的意图(getApplicationContext(),AlarmReceiver.class);
intent.putExtra(alarm_message,选派优秀的交易);
//在现实中,你想拥有的一个静态变量
//请求code,而不是192837
PendingIntent发送= PendingIntent.getBroadcast(
        getApplicationContext(),192837,意图,
        PendingIntent.FLAG_UPDATE_CURRENT);
//获取AlarmManager服务
AlarmManager AM =(AlarmManager)getSystemService(ALARM_SERVICE);
// am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(),发送方);
// 86400000 =24小时
// 43200000 =12小时
// 3600000 = 1小时
// 1800000 = 30分钟
// 300000 = 5分钟
am.setRepeating(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(),60000,发送者);
 
原创 Android6.0中PowerManagerService分析 风雨田 ChinaUnix博客

AlarmReceiver类

 进口android.content.BroadcastReceiver;
进口android.content.Context;
进口android.content.Intent;
进口android.widget.Toast;
进口android.os.Bundle;

公共类AlarmReceiver扩展的BroadcastReceiver {

    @覆盖
    公共无效的onReceive(上下文的背景下,意图意图){
        尝试 {

            捆绑包= intent.getExtras();
            字符串消息= bundle.getString(alarm_message);
            // Toast.makeText(背景下,消息,Toast.LENGTH_SHORT).show();
            意图myIntent =新的意图(背景下,
                    SendOutstandingTransactions.class);
            myIntent.setAction(com.carefreegroup.startatboot.MyService);
            context.startService(myIntent);
        }赶上(例外五){
            Toast.makeText(
                    的背景下,
                    有什么地方是一个错误,但我们还是收到了报警,
                    Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        }
    }
}
 

下面的类调用,我要开始活动时,该设备是睡着了。

SendOutstandingTransactions IntentService。

 保护无效onHandleIntent(意向意图){
    电源管理器PM =(电源管理器)getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock WL = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK,
            我的标签);
    wl.acquire();
    如果(hasMessageDisplayed == FALSE){
        意图I =新的意图(这一点,DisplayMessageActivity.class);
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(ⅰ);
    }
    wl.release();
}
 

  @覆盖
公共无效的onDestroy(){
    super.onDestroy();
    电源管理器PM =(电源管理器)this.getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock WL = pm.newWakeLock(
            PowerManager.PARTIAL_WAKE_LOCK,com.something.alarm);
    //获取锁
    如果(wl.isHeld())wl.release();
}
 

解决方案

要么使用Commonsware的 WakefulIntentService 或者做到这一点:

 类YourService扩展IntentService {

    私有静态最后弦乐LOCK_NAME = YourService.class.getName()
            +.Lock;
    私有静态挥发WakeLock lockStatic = NULL; //通知静

    同步私有静态PowerManager.WakeLock GETLOCK(上下文的背景下){
        如果(lockStatic == NULL){
            PowerManager的经理=(电源管理器)上下文
                    .getSystemService(Context.POWER_SERVICE);
            lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                    LOCK_NAME);
            lockStatic.setReferenceCounted(真正的);
        }
        返回(lockStatic);
    }

    公共静态无效startYourService(上下文ctxt,意图我){// STATIC
        GETLOCK(ctxt.getApplicationContext())获得()。
        ctxt.startService(ⅰ);
    }

    公共YourService(字符串名称){
        超(名称);
        setIntentRedelivery(真正的);
    }

    @覆盖
    公众诠释onStartCommand(意向意图,诠释标志,诠释startId){
        PowerManager.WakeLock锁= GETLOCK(this.getApplicationContext());
        如果(lock.isHeld()||(标志&安培;!START_FLAG_REDELIVERY)= 0){
            lock.acquire();
        }
        super.onStartCommand(意向,标志,startId);
        返程(START_REDELIVER_INTENT);
    }

    @覆盖
    保护无效onHandleIntent(意向意图){
        尝试 {
            //做你的事
        } 最后 {
            PowerManager.WakeLock锁= GETLOCK(this.getApplicationContext());
            如果(lock.isHeld())lock.release();
        }
    }
}
 

和您的接收器:

 捆绑包= intent.getExtras();
字符串消息= bundle.getString(alarm_message);
// Toast.makeText(背景下,消息,Toast.LENGTH_SHORT).show();
意图myIntent =新的意图(背景下,SendOutstandingTransactions.class);
myIntent.setAction(com.carefreegroup.startatboot.MyService);
YourService.startYourService(背景下,myIntent)
 

这实际上是从@CommonsWare WakefulIntentService(不知道的START_FLAG_REDELIVERY,我应该问这些天)

核心

I've an app that has a background service running every minute. I want the service to wake the device up if it's asleep. I am using a PowerManager but the device doesn't wake up. Any ideas why? Thanks in advance.

@Override
protected void onHandleIntent(Intent intent) {
    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK,
            "My Tag");
    wl.acquire();
    // do work as device is awake
    wl.release();
}

[edit1]

This is how i start the service from an Activity.

// get a Calendar object with current time
Calendar cal = Calendar.getInstance();
// add 5 minutes to the calendar object
cal.add(Calendar.MINUTE, 1);
Intent intent = new Intent(getApplicationContext(), AlarmReceiver.class);
intent.putExtra("alarm_message", "sending outstanding transactions");
// In reality, you would want to have a static variable for the
// request code instead of 192837
PendingIntent sender = PendingIntent.getBroadcast(
        getApplicationContext(), 192837, intent,
        PendingIntent.FLAG_UPDATE_CURRENT);
// Get the AlarmManager service
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
// am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
// 86400000 = 24 hours
// 43200000 = 12 hours
// 3600000 = 1hr
// 1800000 = 30 mins
// 300000 = 5 mins
am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),60000,sender);

AlarmReceiver class

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
import android.os.Bundle;

public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        try {

            Bundle bundle = intent.getExtras();
            String message = bundle.getString("alarm_message");
            // Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
            Intent myIntent = new Intent(context,
                    SendOutstandingTransactions.class);
            myIntent.setAction("com.carefreegroup.startatboot.MyService");
            context.startService(myIntent);
        } catch (Exception e) {
            Toast.makeText(
                    context,
                    "There was an error somewhere, but we still received an alarm",
                    Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        }
    }
}

The following class calls the Activity which I want to start when the device is asleep.

SendOutstandingTransactions IntentService.

protected void onHandleIntent(Intent intent) {
    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK,
            "My Tag");
    wl.acquire();
    if (hasMessageDisplayed == false) {
        Intent i = new Intent(this, DisplayMessageActivity.class);
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(i);
    }
    wl.release();
}

[edit2]

@Override
public void onDestroy() {
    super.onDestroy();
    PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wl = pm.newWakeLock(
            PowerManager.PARTIAL_WAKE_LOCK, "com.something.alarm");
    // Acquire the lock
    if (wl.isHeld()) wl.release();
}

解决方案

Either use Commonsware's WakefulIntentService or do this :

class YourService extends IntentService {

    private static final String LOCK_NAME = YourService.class.getName()
            + ".Lock";
    private static volatile WakeLock lockStatic = null; // notice static

    synchronized private static PowerManager.WakeLock getLock(Context context) {
        if (lockStatic == null) {
            PowerManager mgr = (PowerManager) context
                    .getSystemService(Context.POWER_SERVICE);
            lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                    LOCK_NAME);
            lockStatic.setReferenceCounted(true);
        }
        return (lockStatic);
    }

    public static void startYourService(Context ctxt, Intent i) { // STATIC 
        getLock(ctxt.getApplicationContext()).acquire();
        ctxt.startService(i);
    }

    public YourService(String name) {
        super(name);
        setIntentRedelivery(true);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        PowerManager.WakeLock lock = getLock(this.getApplicationContext());
        if (!lock.isHeld() || (flags & START_FLAG_REDELIVERY) != 0) {
            lock.acquire();
        }
        super.onStartCommand(intent, flags, startId);
        return (START_REDELIVER_INTENT);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        try {
            // do your thing
        } finally {
            PowerManager.WakeLock lock = getLock(this.getApplicationContext());
            if (lock.isHeld()) lock.release();
        }
    }
}

and in your receiver :

Bundle bundle = intent.getExtras();
String message = bundle.getString("alarm_message");
// Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
Intent myIntent = new Intent(context, SendOutstandingTransactions.class);
myIntent.setAction("com.carefreegroup.startatboot.MyService");
YourService.startYourService(context, myIntent)

which is actually the core from @CommonsWare WakefulIntentService (not sure about the START_FLAG_REDELIVERY, I should ask one of these days)