#android #firebase #google-cloud-firestore #android-widget
#Android #firebase #google-облако-firestore #android-виджет
Вопрос:
Я создаю виджет для своего приложения, чтобы получить некоторые данные из Firestore. Единственная проблема заключается в том, что, хотя я могу успешно получить данные изначально в onCreate, если я оставлю onDataSetChanged пустым.
Я полагаю, что onDataSetChanged вызывается ОС через определенное время для обновления. Поэтому я не хочу оставлять эту функцию пустой.
Но проблема в том, что я не могу заставить виджет обновляться в onDataSetChanged без бесконечной рекурсии, потому что я использую notifyAppWidgetViewDataChanged обновить мой виджет, чтобы показать новые документы, извлеченные из Firestore.
Итак, мой вопрос в том, как я могу обновить виджет без notifyAppWidgetViewDataChanged внутри моей функции обратного вызова для моего запроса firebase?
Спасибо
public class TaskWidgetService extends RemoteViewsService {
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return new TaskWidgetItemFactory(getApplicationContext(), intent);
}
class TaskWidgetItemFactory implements RemoteViewsFactory {
public static final String TAG = "TaskWidgetItemFactory";
private Context context;
private int appWidgetID;
private ArrayList<String> tasksArrayList; //tasks I want to show
public TaskWidgetItemFactory(Context context, Intent intent) {
this.context = context;
this.appWidgetID = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
void initializeData() {
Log.d(TAG, "initializeData: I'm being called.....");
try {
//Initialize ALL Firebase components
FirebaseFirestore db = FirebaseFirestore.getInstance();
FirebaseAuth mFirebaseAuth = FirebaseAuth.getInstance();
String userId = mFirebaseAuth.getCurrentUser().getUid();
final int a = this.appWidgetID;
Query tasksQuery = db
.collection("users/" userId "/tasks")
.orderBy(Task.FIRESTORE_FIELD_DUE_TIMESTAMP, Query.Direction.ASCENDING)
.orderBy(Task.FIRESTORE_FIELD_PROGRESS, Query.Direction.ASCENDING)
.whereEqualTo(Task.FIRESTORE_FIELD_PARENT_TASK_DOC_ID, null) // only want Parent Tasks
;
tasksQuery.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull com.google.android.gms.tasks.Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Log.d(TAG, document.getId() " => " document.get("name"));
Task t = document.toObject(Task.class);
tasksArrayList.add(t.toString()); //add item to show
}
//refresh Widget to show the data.
AppWidgetManager appWidgetManager = **AppWidgetManager.getInstance(context);
appWidgetManager.notifyAppWidgetViewDataChanged(a, R.id.task_widget_stack_view);**
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
} catch (Exception e) {
Log.d(TAG, "initializeData: " e.toString());
}
}
@Override
public void onCreate() {
tasksArrayList = new ArrayList<>();
initializeData();//get data
}
@Override
public void onDataSetChanged() {
tasksArrayList = new ArrayList<>();
initializeData(); //get data causes infinte recursion b/c of "notifyAppWidgetViewDataChanged"
}
@Override
public int getCount() {
Log.d(TAG, "getCount: " tasksArrayList.size());
return tasksArrayList.size();
}
}}
Ответ №1:
если (yourList!= null) {
yourList.clear();
Выполните затем операцию
}
наконец, вы можете вызвать
adapter.notifyDataSetChanged();
Ответ №2:
Я смог это исправить, просто получив данные в onDataSetChnaged() с помощью await .
@Override
public void onDataSetChanged() {
tasksArrayList = new ArrayList<>();
FirebaseFirestore db = FirebaseFirestore.getInstance();
FirebaseAuth mFirebaseAuth = FirebaseAuth.getInstance();
String userId = mFirebaseAuth.getCurrentUser().getUid();
Query tasksQuery = db
.collection("users/" userId "/tasks")
.orderBy(Task.FIRESTORE_FIELD_DUE_TIMESTAMP, Query.Direction.ASCENDING)
.orderBy(Task.FIRESTORE_FIELD_PROGRESS, Query.Direction.ASCENDING)
.whereEqualTo(Task.FIRESTORE_FIELD_PARENT_TASK_DOC_ID, null) // only want Parent Tasks
;
try {
//wait for data to be collected.
final QuerySnapshot querySnapshot = Tasks.await(tasksQuery.get());
for (QueryDocumentSnapshot document : querySnapshot) {
Log.d(TAG, document.getId() " => " document.get("name"));
Task t = document.toObject(Task.class);
tasksArrayList.add(t);
}
} catch (ExecutionException e) {
Toast.makeText(getApplicationContext(), "Failed to get Tasks.", Toast.LENGTH_LONG).show();
} catch (InterruptedException e) {
Toast.makeText(getApplicationContext(), "Failed to get Tasks.", Toast.LENGTH_LONG).show();
}
}