2014-12-11 5 views
3

매일 자정에 Android 위젯을 업데이트하는 방법 ?? 아래 솔루션은이 주제와 관련하여 스택 오버플로에서 다른 질문을 조사하여 형성됩니다. 위젯은 위젯이 자정에 매일 갱신됩니다 있도록 타이머와 알람을 설정해야합니다의 AppWidgetProvider자정에 Android 위젯 업데이트

public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
     final int N = appWidgetIds.length; 
     schedule(context); 
    super.onUpdate(context, appWidgetManager, appWidgetIds); 

} 

2) 예약 방법을 확장 활동에서 생성 될 때 호출되는

1) 일정 (컨텍스트). 그러나 이것은 작동하지 않습니다.

protected void schedule(Context context) { 
    final Intent i = new Intent(context, CalendarWidget.class); 
    service = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT); 

    Calendar calendar = Calendar.getInstance(); 
    calendar.setTimeInMillis(System.currentTimeMillis()); 
    calendar.set(Calendar.SECOND, 0); 
    calendar.set(Calendar.MINUTE, 0); 
    calendar.set(Calendar.HOUR, 0); 
    calendar.set(Calendar.AM_PM, Calendar.AM); 
    calendar.add(Calendar.DAY_OF_MONTH, 1); 

    AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); 

//This doesn't work 
     // alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), service); 
//This doesn't work either. 
     alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, service); 
    } 

해결책이 작동하지 않습니다. 매일 자정에만 테스트 할 수 있기 때문에 테스트하기가 어렵습니다. 그러므로 현상금. 나는 그것이 작동하게 만든 최초의 사람에게 그것을 수여 할 것이다.

+0

왜 AlarmManager를 두 번 설정 했습니까? 그 중 하나를 삭제하고 거기에 setRepeating 메소드를 보냅니다. – Opiatefuchs

+0

둘 다 작동하지 않습니다. 나는 모두 시도했다 – coolcool1994

+0

좋아, 정확히 작동하지 않는 무엇입니까? Shedule()은 결코 호출되지 않습니까? 또는 호출했는데 AlarmManager가 작동하지 않습니까? – Opiatefuchs

답변

4

나는 한동안 날짜와 시간 도구를 만들었습니다. 의 AppWidgetProvider 클래스에서

:

private boolean first_run = true; 
public AlarmManager am; 
public PendingIntent pi; 

@Override 
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
    first_run = context.getSharedPreferences("mywidet", MODE_PRIVATE).getBoolean("first_run", true); 
    if(first_run) { 
     am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
     Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class); 
     pi = PendingIntent.getBroadcast(context, 0, intent, 0); 
     long current = System.currentTimeMillis(); 

     LocalTime localTime = LocalTime.now(); 
     long triggerOffset = (24*60*60 - localTime.getHour()*60*60 - localTime.getMinute()*60 - localTime.getSecond())*1000; 
     am.setRepeating(AlarmManager.RTC_WAKEUP, current + triggerOffset, 86400000, pi); 
     SharedPreferences.Editor editor = context.getSharedPreferences("mywidet", MODE_PRIVATE).edit(); 
     editor.putBoolean("first_run", false); 
     editor.apply(); 
    } 
    for (int appWidgetId : appWidgetIds) { 
     appWidgetManager.updateAppWidget(appWidgetId, remoteView); 
    } 
} 

AlarmManagerBroadcasrReceiver 클래스 : API 19에서 1

은 이후 모든 setReapeating() 경보가 부정확하다

@Override 
public void onReceive(Context context, Intent intent) { 
    PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 
    PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "YOUR TAG"); 
    //Acquire the lock 
    wl.acquire(); 

    Log.d("widget", "in alarm manager. static method will come next"); 

    ComponentName thisWidget = new ComponentName(context, NewAppWidget.class); 
    AppWidgetManager manager = AppWidgetManager.getInstance(context); 
    manager.updateAppWidget(thisWidget, remoteViews); 
    //Release the lock 
    wl.release(); 
} 

편집 아래의 구현입니다. 그래서, 하나는 다음을 수행 할 수 있습니다 :

if(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { 
     alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, nexMin.getTimeInMillis()-current.getTimeInMillis(), 60000, pendingIntent); 
} else { 
     alarmManager.setExact(AlarmManager.RTC_WAKEUP, nexMin.getTimeInMillis() - current.getTimeInMillis(), pendingIntent); 
} 

당신은 전체 구현 here을 찾을 수 있습니다.

+0

나는 앞으로 6 시간 이내에 모든 솔루션을 시도하고 작동하는 솔루션에 현상금을 수여 할 것입니다. 모든 것이 작동하면 최상의 솔루션으로 얻을 수 있습니다. 하지만 솔직히 나는 아무것도 작동하도록 노력하겠습니다. – coolcool1994

+0

한가지를 잊었습니다. 부울 first_run .. 바보 같은 실수를 추적하기 위해 sharedpreferences를 사용하십시오. 죄송합니다. – rafid059

+0

이것은 단지 발췌 일뿐입니다. 그의 질문은 매일 오전 12시에 위젯을 정확하게 업데이트하는 것이 었습니다. 그것은 그것이하는 것입니다. onDisabled, onDeleted, onRestored를 재정 의하여 필요한 코드를 추가하여 알람 제어를 관리 할 수 ​​있습니다. – rafid059

1

Rafiduzzman Sonnet's answer 작품 (종류)하지만 단순화 될 수 있습니다. AppWidgetProvider은 이미 BroadcastReceiver이므로 실제로 의도를 AppWidgetProvider으로 되돌려 보내고 onReceive를 재정 의하여 처리 할 수 ​​있습니다. 클래스가 AppWidgetProvider 확장에

는 : AppWidgetManager.ACTION_APPWIDGET_UPDATE 모든 위젯을 업데이트하지 않기 때문에

private static final String ACTION_SCHEDULED_UPDATE = "your.package.name.SCHEDULED_UPDATE"; 

@Override 
public void onReceive(Context context, Intent intent) { 
    if (intent.getAction().equals(ACTION_SCHEDULED_UPDATE)) { 
     AppWidgetManager manager = AppWidgetManager.getInstance(context); 
     int[] ids = manager.getAppWidgetIds(new ComponentName(context, AppWidget.class)); 
     onUpdate(context, manager, ids); 
    } 

    super.onReceive(context, intent); 
} 

@Override 
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
    // Do your updates... 

    _scheduleNextUpdate(context); 
} 

private static void _scheduleNextUpdate(Context context) { 
    AlarmManager alarmManager = 
      (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
    // Substitute AppWidget for whatever you named your AppWidgetProvider subclass 
    Intent intent = new Intent(context, AppWidget.class); 
    intent.setAction(ACTION_SCHEDULED_UPDATE); 
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0); 

    // Get a calendar instance for midnight tomorrow. 
    Calendar midnight = Calendar.getInstance(); 
    midnight.set(Calendar.HOUR_OF_DAY, 0); 
    midnight.set(Calendar.MINUTE, 0); 
    // Schedule one second after midnight, to be sure we are in the right day next time this 
    // method is called. Otherwise, we risk calling onUpdate multiple times within a few 
    // milliseconds 
    midnight.set(Calendar.SECOND, 1); 
    midnight.set(Calendar.MILLISECOND, 0); 
    midnight.add(Calendar.DAY_OF_YEAR, 1); 

    // For API 19 and later, set may fire the intent a little later to save battery, 
    // setExact ensures the intent goes off exactly at midnight. 
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { 
     alarmManager.set(AlarmManager.RTC_WAKEUP, midnight.getTimeInMillis(), pendingIntent); 
    } else { 
     alarmManager.setExact(AlarmManager.RTC_WAKEUP, midnight.getTimeInMillis(), pendingIntent); 
    } 
} 

우리는 당신이 AppWidgetManager.EXTRA_APPWIDGET_IDS에서 추가로 식별자의 전체 배열을 전달하더라도, 사용자 정의 의도 조치를해야합니다. 그것은 단지 생성 된 첫 번째 위젯을 업데이트합니다.

Here is a project I'm working on 이와 비슷한 스케줄 된 위젯 업데이트를 구현합니다.