I'm using a BroadcastReceiver
that receives a broadcast from an AlarmManager
. In the receiver I am starting two activities. One activity is started from a URI like this and is a third-party app:
// Open spotify
Intent spotify = new Intent(Intent.ACTION_VIEW, Uri.parse(song));
spotify.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(spotify);
} catch (ActivityNotFoundException e) {
status = Status.SPOTIFY_NOT_INSTALLED;
}
After that I start another activity that belongs to the app with a 5 second delay using the AlarmManager
again:
public static void setExact(
Context context, PendingIntent pendingIntent, long time
) {
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
am.setExact(AlarmManager.RTC_WAKEUP, time, pendingIntent);
else
am.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);
}
public static void setExactDelay(
Context context, PendingIntent pendingIntent, long delay
) {
setExact(context, pendingIntent, System.currentTimeMillis() + delay);
}
PendingIntent pendingIntent = AlarmPlayActivity.makePendingIntent(context, alarm, status, startTime);
AlarmSet.setExactDelay(context, pendingIntent, 5000);
The second activity starts in 5 seconds as expected. However the first activity only starts when the device is unlocked. If the device is locked it does not start on Android Nougat (7.0). This is the case even when the lock is not secured by password, pattern etc. This used to work on earlier Android versions, even with a secure lock.
Is there a method by which I can start the first activity without needing the screen to be on?
Edit: I've tried using the following IntentService
. It works when the device is awake and unlocked but there is no luck when the device is locked:
public class AlarmService extends IntentService {
static final int NOTIFICATION_ID = 1;
public AlarmService() {
super("AlarmService");
}
public static Intent makeIntent(Context context, Alarm alarm, AlarmReceiver.Status status, long startTime) {
Intent intent = IntentFactory.alarmPlayIntent(alarm, status, startTime);
intent.setClass(context, AlarmService.class);
return intent;
}
private static void sleep(long time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
// Nothing
}
}
@Override
protected void onHandleIntent(Intent intent) {
// Acquire Wakelock immediately
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock(
PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE,
"AlarmServiceWakeLock"
);
wakeLock.acquire();
KeyguardManager.KeyguardLock lock = ((KeyguardManager) getSystemService(Activity.KEYGUARD_SERVICE)).newKeyguardLock(KEYGUARD_SERVICE);
lock.disableKeyguard();
// Get intent data
final Alarm alarm = IntentFactory.getAlarm(intent);
AlarmReceiver.Status status = IntentFactory.getStatus(intent);
final long startTime = IntentFactory.getStartTime(intent, 0);
// Get a random song for this alarm
AlarmDatabase db = AlarmDatabase.getInstance(this);
Song song = db.getRandomSong(alarm);
String songName = song == null ? "backup sound" : song.getName();
// Start a foreground notification
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle(getText(R.string.alarm_starting_notification_title))
.setContentText(getString(
R.string.alarm_starting_notification_message, alarm.getName(), songName
))
.setSmallIcon(R.drawable.ic_launcher)
.setPriority(NotificationCompat.PRIORITY_MAX)
.build();
startForeground(NOTIFICATION_ID, notification);
// Potentially open Spotify if we can
if (song != null) {
// Open spotify
Intent spotify = new Intent(Intent.ACTION_VIEW, Uri.parse(song.getUri()));
spotify.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
try {
startActivity(spotify);
} catch (ActivityNotFoundException e) {
status = AlarmReceiver.Status.SPOTIFY_NOT_INSTALLED;
}
} else
status = AlarmReceiver.Status.NO_SONGS;
// Start play activity in 10 seconds, giving Spotify some chance to load up.
sleep(10);
startActivity(AlarmPlayActivity.makeIntent(this, alarm, status, startTime));
// Keep alive for 5 more seconds
sleep(5);
// Stop notification
stopForeground(true);
// Release wakelock
wakeLock.release();
}
}
I experienced the same issue and i think
Intent.ACTION_VIEW
don't work until you unlock the screen because of safety reasons.Same issue discussed here also. You can also check this link