4

Я использую BroadcastReceiver, который получает широковещательную передачу от AlarmManager. В приемнике я начинаю два занятия. Одним из видов деятельности начинается с URI, как это и является третьей стороной приложение:startActivity для URI в Lockscreen на Android Nougat

// 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; 
} 

После этого я начинаю другую деятельность, которая принадлежит к приложению с 5-секундной задержкой, используя AlarmManager снова:

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); 

Второе действие начинается через 5 секунд, как ожидалось. Однако первое действие запускается только тогда, когда устройство разблокировано. Если устройство заблокировано, оно не запускается на Android Nougat (7.0). Это происходит даже тогда, когда блокировка не защищена паролем, шаблоном и т. Д. Это использовалось для более ранних версий Android, даже с надежной блокировкой.

Есть ли способ, с помощью которого я могу начать первое действие без необходимости включения экрана?

Редактировать: Я пробовал использовать следующее IntentService. Он работает, когда устройство пробуждается и разблокирован, но не повезло, когда устройство заблокировано:

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(); 


    } 

} 
+0

Я полагаю, я мог бы создать специальный 'Activity' с целью держать устройство разблокируется всю ночь, пока сигнал не приходит, но это далеко не идеальный. –

+0

С момента запуска вашей собственной деятельности, почему бы не начать свою деятельность, которая просто срабатывает? – natario

+1

Выглядит как [здесь] (http://stackoverflow.com/a/32511496/4069913). Попробуйте 'setAlarmclock'? –

ответ

2

я испытал тот же вопрос, и я думаю, что Intent.ACTION_VIEW не работают, пока вы не разблокировать экран из-за соображений безопасности.

Этот же вопрос обсуждался here также. Вы также можете проверить это link

+1

Я думаю, что вы правы. С недавних версий Android это невозможно сделать, и я сомневаюсь, что разработчики Android изменят это поведение. Мне нужно найти совершенно другое решение. К сожалению, ник-фрискель не ответил. –

1

Вы должны использовать уточненные методы: либо am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nexttime, pendingintent);

или am.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nexttime, pendingintent);

Не забудьте установить ваш я активный режим: , чтобы начать:

PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE); 
      wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | 
        PowerManager.ACQUIRE_CAUSES_WAKEUP | 
        PowerManager.ON_AFTER_RELEASE, A_.APPNAME + Integer.toString(index)); 
     if (wakeLock != null && wakeLock.isHeld()){ 
      wakeLock.acquire(); 
     } 

выпустить:

wakeLock.release();

вы можете установить деятельность в качестве переднего плана (над экраном блокировки) описано здесь: https://stackoverflow.com/a/23611199/1979882

import android.view.Window; 
import android.view.WindowManager.LayoutParams; 


Window window = this.getWindow(); 
window.addFlags(LayoutParams.FLAG_DISMISS_KEYGUARD); 
window.addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED); 
window.addFlags(LayoutParams.FLAG_TURN_SCREEN_ON); 

Вы можете начать свою деятельность, как показано здесь:

https://stackoverflow.com/a/6468575/1979882

@Override 
    public void onReceive(Context context, Intent intent) { 
     //start activity 
     Intent i = new Intent(); 
     i.setClassName("com.test", "com.test.MainActivity"); 
     i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     context.startActivity(i); 
    } 
1

Instea d для запуска вашей операции Spotify непосредственно с ресивера, вместо этого приемник должен начать с Service из собственного приложения.

Внутри службы, приобретает свой wakelock, а затем начать Foreground уведомления (построить notification с NotificationCompat.Builder затем использовать startForeground(mId, notification);, это уведомление будет держать службу в живых в тех случаях, когда Нуга иначе остановить его.

Затем запустите свой Spotify Intent со службы, после чего, конечно, убейте службу, уведомление переднего плана и wakelock. Это работало для меня прежде, чтобы избежать надоедливых проблем Нуги, как вы сталкиваетесь. Надеюсь это поможет!

+0

Спасибо. Я попробую этот метод сегодня и награду щедростью, если он сработает. –

+0

К сожалению, это не работает для меня. Я поставлю «IntentService», который я использую в вопросе. Это фактически приводит к тому, что любое существующее уведомление Spotify будет удалено с экрана блокировки, а затем не открывается Spotify. Он работает, когда устройство бодрствует и разблокируется. –

+0

Я только что предоставил редактирование. –