我已经为这个问题苦苦挣扎了好几天......我有一个应用程序设置了一些警报。触发警报时,必须显示显示消息的 Activity,播放声音和振动。当设备通过 USB 电缆连接到我的 PC 时,一切正常。相反,当手机没有插上电源并进入睡眠模式时,即使在正确的时间触发了警报并且屏幕正确打开,消息 Activity 似乎也只是开始了一毫秒的声音和振动,然后它被立即杀死。我错过了什么?为了避免已知的睡眠/打盹模式问题,我使用 AlarmClock 设置了闹钟,并使用一些已弃用的 PowerManager 方法从睡眠模式返回屏幕。也许我在清单文件中缺少一些权限,还是我添加到打开活动的意图中的标志错了?这是我的代码:
清单权限:
<!-- Needs internet to connect to Google Services -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- Permission to check internet connection state -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- Keeps processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<!-- Permission to vibrate when receive a notification -->
<uses-permission android:name="android.permission.VIBRATE"/>
<!-- Lets app receive data messages. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<!-- Permission to set alarms again when device is rebooted -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<!-- Permission to disable the keylock -->
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
....
<receiver android:name=".alarm.PrescrizioneAlarmBroadcastReceiver"/>
警报设置管理器:
public class AlarmSettingManager
{
private Context context;
private DBManager dbManager = null;
final int DAYS_BETWEEN_PILLS = 1;
// Constructor
public AlarmSettingManager(Context c)
{
context = c;
dbManager = new DBManager(context);
}
private class PrescriptionAlarmSetter extends AsyncTask<String, Void, Boolean>
{
@Override
protected Boolean doInBackground(String... strings)
{
Intent alarmIntent = new Intent(context, PrescrizioneAlarmBroadcastReceiver.class);
String text = "This is the message";
// put the RequestCode ID as intent's extra, in order to identify which alarm is triggered
alarmIntent.putExtra("request_code", currentID);
alarmIntent.putExtra("title", "Assumere compressa");
alarmIntent.putExtra("text", text);
alarmIntent.putExtra("id_prescrizione", prescrizione.getId_prescrizione());
alarmIntent.putExtra("id_farmaco", prescrizione.getId_farmaco());
alarmIntent.putExtra("numero_pasticche", prescrizione.getNumero_pasticche());
PendingIntent pendingIntent = PendingIntent.getBroadcast
(
context.getApplicationContext(),
currentID,
alarmIntent,
PendingIntent.FLAG_CANCEL_CURRENT
);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, prescrizione.getIntHour());
calendar.set(Calendar.MINUTE, prescrizione.getIntMinutes());
calendar.set(Calendar.SECOND, 0);
// if for today the time is passed already
if(calendar.getTimeInMillis() < System.currentTimeMillis())
{
// set the alarm for the next day (add one day)
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(calendar.getTimeInMillis(), pendingIntent);
alarmManager.setAlarmClock(alarmClockInfo, pendingIntent);
return true;
}
@Override
protected void onPostExecute(Boolean b)
{
super.onPostExecute(b);
}
}
public boolean setPrescriptionAlarms()
{
AlarmSettingManager.PrescriptionAlarmSetter prescriptionAlarmSetter = new AlarmSettingManager.PrescriptionAlarmSetter();
prescriptionAlarmSetter.execute();
return true;
}
}
PrescrizioneAlarmBroadcastReceiver:
public class PrescrizioneAlarmBroadcastReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent receivedIntent)
{
int request_code = receivedIntent.getIntExtra("request_code", -1);
String title = receivedIntent.getStringExtra("title");
String text = receivedIntent.getStringExtra("text");
int id_farmaco = receivedIntent.getIntExtra("id_farmaco", -1);
int id_prescrizione = receivedIntent.getIntExtra("id_prescrizione", -1);
int numero_pasticche = receivedIntent.getIntExtra("numero_pasticche", -1);
// Take the first 4 digits of the request code as a String
String requestCodePrefix = Integer.toString(request_code).substring(0, 4);
if(request_code != -1)
{
if(requestCodePrefix.equals(Constants.PRESCRIZIONE_ALARM_PREFIX) || requestCodePrefix.equals(Constants.SNOOZED_PRESCRIZIONE_ALARM_PREFIX))
{
// Wake device from sleep mode
PowerManager pm = (PowerManager) context.getApplicationContext().getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "TAG");
wakeLock.acquire();
//to release the screen lock
KeyguardManager keyguardManager = (KeyguardManager) context.getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("TAG");
keyguardLock.disableKeyguard();
Intent intent = new Intent(context, PrescrizioneAlarmReceiverActivity.class);
intent.putExtra("request_code", request_code);
if(title != null && text != null)
{
intent.putExtra("title", title);
intent.putExtra("text", text);
}
intent.putExtra("id_farmaco", id_farmaco);
intent.putExtra("id_prescrizione", id_prescrizione);
intent.putExtra("numero_pasticche", numero_pasticche);
// ARE THESE FLAGS OK???
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intent);
}
}
}
}
PrescrizioneAlarmReceiverActivity(被关闭的活动):
public class PrescrizioneAlarmReceiverActivity extends AppCompatActivity
{
SoundManager soundManager;
VibrationManager vibrationManager;
DBManager dbManager;
TextView alarmTitle, alarmText;
Button snoozeButton, stopButton;
String title, text;
int id_farmaco, id_prescrizione, numero_pasticche;
boolean okClicked;
int request_code = -1;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
dbManager = new DBManager(getApplicationContext());
vibrationManager = VibrationManager.getInstance(getApplicationContext());
soundManager = SoundManager.getInstance(getApplicationContext());
// Vibrate
vibrationManager.startVibration();
// Play sound
soundManager.playSound();
setOkClicked(false);
// Set Activity fullscreen
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
Window window = getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
// let the window be shown when the screen is locked and the keyguard will be dismissed
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
// Turn the device's screen on and keep it turned on and bright
// as long as this window is visible to the user
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
setContentView(R.layout.activity_prescrizione_alarm_receiver);
// Reference all Views of the Activity
alarmTitle = (TextView) findViewById(R.id.alarm_title_prescription);
alarmText = (TextView) findViewById(R.id.alarm_text_prescription);
snoozeButton = (Button) findViewById(R.id.snooze_alarm_prescription_button);
stopButton = (Button) findViewById(R.id.stop_alarm_prescription_button);
Bundle extras = getIntent().getExtras();
title = extras.getString("title");
text = extras.getString("text");
id_farmaco = extras.getInt("id_farmaco");
id_prescrizione = extras.getInt("id_prescrizione");
numero_pasticche = extras.getInt("numero_pasticche");
request_code = extras.getInt("request_code");
alarmTitle.setText(title);
alarmText.setText(text);
// Set all listeners
snoozeButton.setOnClickListener(new SnoozeAlarmButtonClickListener());
stopButton.setOnClickListener(new PrescrizioneStopAlarmButtonClickListener());
}
@Override
protected void onPause()
{
AlarmSettingManager alarmSettingManager = new AlarmSettingManager(getApplicationContext());
// Se ho cliccato su stop
if(okClicked)
{
// Set the alarm to trigger again in 1 day
alarmSettingManager.setPrescriptionAlarms();
}
super.onPause();
}
@Override
protected void onStop()
{
super.onStop();
// Get redirected to another Activity
Intent intent = new Intent(this, SplashActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
谢谢。