【问题标题】:Android AlarmManager not waking phone up (with or without WakeLock)Android AlarmManager 不唤醒手机(带或不带 WakeLock)
【发布时间】:2016-11-08 10:04:02
【问题描述】:

我一直在尝试制作一个简单的闹钟应用程序,但我从来没有成功让手机唤醒(无论有没有 WakeLock)。这是我的 MainActivity 代码:

public class MainActivity extends AppCompatActivity {
    public final int sleepRequest = 111;
    public final int wakeRequest = 222;

    PendingIntent pendingIntent;
    AlarmManager manager;

    // currently no difference between sleeping and waking alarms, nor do the alarms use the selected time

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button sleepButton = (Button) findViewById(R.id.sleepButton);
        sleepButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                createAlarm(sleepRequest);
            }
        });

        Button wakeButton = (Button) findViewById(R.id.wakeButton);
        wakeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                createAlarm(wakeRequest);
            }
        });
    }

    public void createAlarm(final int requestCode) {
        showTimePicker(new Completion() {
            @Override
            public void onCompletion(int hour, int minute) {
                setAlarm(hour, minute, requestCode);
            }
        });
    }

    public void showTimePicker(final Completion completion) {
        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);

        TimePickerDialog timePickerDialog = new TimePickerDialog(this,
                new TimePickerDialog.OnTimeSetListener() {
                    @Override
                    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                        completion.onCompletion(hourOfDay, minute);
                    }
                }, hour, minute, false);
        timePickerDialog.show();
    }

    public void setAlarm(int hour, int minute, int requestCode) {
        Date date  = new Date();
        Calendar now = Calendar.getInstance();
        now.setTime(date);

        Calendar alarm = Calendar.getInstance();
        alarm.setTime(date);
        alarm.set(Calendar.HOUR_OF_DAY, hour);
        alarm.set(Calendar.MINUTE, minute);
        alarm.set(Calendar.SECOND,0);

        if(alarm.before(now)){
            alarm.add(Calendar.DATE,1);
        }

        manager = (AlarmManager) getSystemService(ALARM_SERVICE);
        Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(MainActivity.this, requestCode, intent, 0);
        manager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarm.getTimeInMillis(), pendingIntent);
    }
}

对于警报接收器:

public class AlarmReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent service = new Intent(context, AlarmService.class);
        Log.i("SimpleWakefulReceiver", "Starting service @ " + SystemClock.elapsedRealtime());
        startWakefulService(context, service);
    }
}

对于报警服务:

public class AlarmService extends IntentService {
    public AlarmService() {
        super("AlarmService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i("APP", "in onHandleIntent");
        Toast.makeText(getApplicationContext(), "Hello world", Toast.LENGTH_SHORT).show();
    }
}

这是 AndroidManifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.me.app">

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <receiver
            android:process=":remote"
            android:name=".AlarmReceiver">
        </receiver>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".AlarmService" />

    </application>

</manifest>

当到达闹钟应该响起的时间时,我收到此错误:

11-07 20:52:01.106 20764-21883/com.me.app I/APP: in onHandleIntent
11-07 20:52:03.136 20764-20775/com.me.app W/MessageQueue: Handler (android.os.Handler) {f9c4a9b} sending message to a Handler on a dead thread
                                                                  java.lang.IllegalStateException: Handler (android.os.Handler) {f9c4a9b} sending message to a Handler on a dead thread
                                                                      at android.os.MessageQueue.enqueueMessage(MessageQueue.java:543)
                                                                      at android.os.Handler.enqueueMessage(Handler.java:631)
                                                                      at android.os.Handler.sendMessageAtTime(Handler.java:600)
                                                                      at android.os.Handler.sendMessageDelayed(Handler.java:570)
                                                                      at android.os.Handler.post(Handler.java:326)
                                                                      at android.widget.Toast$TN.hide(Toast.java:738)
                                                                      at android.app.ITransientNotification$Stub.onTransact(ITransientNotification.java:11-07 20:52:01.106 20764-21883/com.me.app I/APP: in onHandleIntent
11-07 20:52:03.136 20764-20775/com.me.app W/MessageQueue: Handler (android.os.Handler) {f9c4a9b} sending message to a Handler on a dead thread
                                                                  java.lang.IllegalStateException: Handler (android.os.Handler) {f9c4a9b} sending message to a Handler on a dead thread
                                                                      at android.os.MessageQueue.enqueueMessage(MessageQueue.java:543)
                                                                      at android.os.Handler.enqueueMessage(Handler.java:631)
                                                                      at android.os.Handler.sendMessageAtTime(Handler.java:600)
                                                                      at android.os.Handler.sendMessageDelayed(Handler.java:570)
                                                                      at android.os.Handler.post(Handler.java:326)
                                                                      at android.widget.Toast$TN.hide(Toast.java:738)
                                                                      at android.app.ITransientNotification$Stub.onTransact(ITransientNotification.java:55)
                                                                      at android.os.Binder.execTransact(Binder.java:453)55)
                                                                      at android.os.Binder.execTransact(Binder.java:453)

【问题讨论】:

  • setExact 更改为setAndAllowWhileIdle 并没有什么不同,而且我认为手机甚至没有足够长的空闲时间来激活打盹模式。 (按下按钮后,闹钟会设置几秒钟。)
  • 哦,没看过这个....你需要权限:com.android.alarm.permission.SET_ALARM
  • 很遗憾,这并没有什么不同。
  • 如果 toast 正在显示,那么 alarmManager 应该可以工作。您是否对未在此处发布的日历进行了任何处理?

标签: java android alarmmanager


【解决方案1】:

您对 WakefulBroadcastReceiver 的作用感到困惑。它不会打开屏幕。它唤醒处理器。如果你想打开屏幕,你需要使用一个普通的广播接收器,并采取一个完整的唤醒锁——WakefulBroadcastReceiver 采取的唤醒锁是一个部分的。

【讨论】:

  • 我尝试添加一个唤醒锁,但即使我使用标志ACQUIRE_CAUSES_WAKEUP(我确信它是有效的),它仍然抱怨我需要指定一个有效的唤醒锁级别。
  • 然后指定一个有效的级别。这不是一个级别,这是一个标志。你需要用一个级别来或它。您需要唤醒屏幕的级别是 SCREEN_DIM_WAKELOCK、SCREEN_BRIGHT_WAKELOCK 或 FULL_WAKELOCK,具体取决于您希望屏幕和键盘的亮度。
  • 不过,这些值已被弃用。
  • 它们仍然是您所需要的。它们已被弃用,因为它们更喜欢您使用基于活动的标志,但因为您没有启动不可能的活动
  • 好的,我使用 ACQUIRE_CAUSES_WAKEUP | SCREEN_DIM_WAKE_LOCK 让它工作,然后从服务启动 Activity 并禁用键盘保护。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多