2016-04-23 3 views
0

В моем виджете у меня есть кнопка обновления, которую я использую, чтобы сообщить (custom) listview, что набор данных изменился. Прямо сейчас у меня есть вызов onRecieve, который вызывается при нажатии кнопки обновления, но передаваемый пул намерений имеет значение null, поэтому я не могу вызывать onUpdate для идентификаторов.Обновление виджета Listview

Я проверил функцию, где я добавляю дополнительные функции. Он говорит, что целочисленный массив, который он добавляет, имеет длину 1 и не равен нулю, я не уверен, почему это не работает:/Надеюсь, кто-то здесь может дать мне рука.

Спасибо.

WidgetProvider.java

public class WidgetProvider extends AppWidgetProvider { 

    @Override 
    public void onDeleted(Context context, int[] appWidgetIds) 
    { 
     super.onDeleted(context, appWidgetIds); 
    } 

    @Override 
    public void onDisabled(Context context) 
    { 
     super.onDisabled(context); 
    } 

    @Override 
    public void onEnabled(Context context) 
    { 
     super.onEnabled(context); 
    } 

    @Override 
    public void onReceive(Context context, Intent intent) 
    { 
     System.out.println("RECIEVED SOMETHING:" + intent.getAction()); 
     AppWidgetManager appWidgetMgr = AppWidgetManager.getInstance(context); 

     Bundle extras = intent.getExtras(); 
     int[] ids = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS); //NPE ON THIS LINE, EXTRAS IS NULL 

     System.out.println("SENDING AN UPDATE"); 
     onUpdate(context, appWidgetMgr, ids); 

     super.onReceive(context, intent); 
    } 

    protected PendingIntent getPendingSelfIntent(Context context, String action, int[] ids) { 
     Intent intent = new Intent(context, getClass()); 
     intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids); 
     System.out.println("PUTTING ARRAY OF LEN: " + ids.length); 
     intent.setAction(action); 
     return PendingIntent.getBroadcast(context, 0, intent, 0); 
    } 

    @Override 
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, 
         int[] appWidgetIds) 
    { 
     for(int i=0;i<appWidgetIds.length;i++) 
     { 
      System.out.println("CHECK"); 
      RemoteViews rv = new RemoteViews(context.getPackageName(), 
        R.layout.app_widget); 

      Intent intent = new Intent(context, WidgetService.class); 
      intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 
        appWidgetIds[i]); 
      intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); 

      rv.setRemoteAdapter(R.id.list, intent); 

      rv.setOnClickPendingIntent(R.id.refresh, getPendingSelfIntent(context, 
        "refresh", appWidgetIds)); 

      appWidgetManager.updateAppWidget(appWidgetIds[i], rv); 
     } 
     super.onUpdate(context, appWidgetManager, appWidgetIds); 
    } 
} 

Edit: Новая функция onRecieve, та же ошибка:

@Override 
    public void onReceive(Context context, Intent intent) 
    { 
     if("refresh".equals(intent.getAction())) { 
      System.out.println("RECIEVED SOMETHING:" + intent.getAction()); 
      AppWidgetManager appWidgetMgr = AppWidgetManager.getInstance(context); 

      Bundle extras = intent.getExtras(); 

      int[] ids = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS); 

      System.out.println("SENDING AN UPDATE"); 
      onUpdate(context, appWidgetMgr, ids); 
     } 

     super.onReceive(context, intent); 
    } 

ответ

1

Если вы посмотрите на source for AppWidgetProvider, onReceive() называется первым для каждой стандартной операции виджета, не просто для вашего пользовательского кода. Вы должны обернуть свой код в if-check, который гарантирует, что это ваша кнопка нажата.

// In onReceive() 
if ("refresh".equals(intent.getAction())) { 
    // Do your code 
} 

Вы также заметите, из PendingIntent documentation:

Because of this behavior, it is important to know when two Intents are considered to be the same for purposes of retrieving a PendingIntent. A common mistake people make is to create multiple PendingIntent objects with Intents that only vary in their "extra" contents, expecting to get a different PendingIntent each time. This does not happen. The parts of the Intent that are used for matching are the same ones defined by Intent.filterEquals. If you use two Intent objects that are equivalent as per Intent.filterEquals, then you will get the same PendingIntent for both of them.

...

If you only need one PendingIntent active at a time for any of the Intents you will use, then you can alternatively use the flags FLAG_CANCEL_CURRENT or FLAG_UPDATE_CURRENT to either cancel or modify whatever current PendingIntent is associated with the Intent you are supplying.

Таким образом, вы должны также обновить свой призыв к PendingIntent.getBroadcast() к

return PendingIntent.getBroadcast(context, 0, intent, 
    PendingIntent.FLAG_UPDATE_CURRENT); 

Конечно, альтернативой было бы просто позвонить AppWidgetManager#getAppWidgetIds() и пропустить установку каких-либо дополнительных функций.

+0

Я обновил свой код, ту же ошибку, хотя – Nathan

+0

Обновлен мой ответ: Я даже не думаю, что вам нужно устанавливать какие-либо дополнительные функции, теперь, когда я смотрю, что вы делаете снова. – ianhanniballake

+0

Интересный сниппет, не знал этого. Либо настройка моего PendingIntent, либо использование getAppWidgetIds решит проблему. Приветствия :) – Nathan

Смежные вопросы