Can I use AppWidgetHost
inside a Fragment
? I can't get most widgets added to my AppWidgetHost to update. Here is my scenario..
LauncherActivity.java
main.xml
CodeRedWidgetHostFragment.java
onCreateView
create instances of AppWidgetHost & AppWidgetManager
create and setup my host view with a widget ID that I've stored in preferences
onStart()
appWidgetHost.startListening()
onStop()
appWidgetHost.stopListening()
When I get my instances of AppWidgetHost and AppWidgetManager I'm using getActivity() to get the Fragments hosting activity. I'm wondering if this is why my widgets aren't updating?
Some widgets actually do update, like the Analog Clock for example, however, the Youtube widget doesn't auto cycle through video thumbnails.
I should mention that I select the widget I want in my AppWidgetHost in another activity that stores the selected widget's id in SharedPreferences.
Here is the code for my Fragment class.
package com.brockoli.android.codered.widgethost;
import android.app.Fragment;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.brockoli.android.codered.R;
public class CodeRedWidgetHostFragment extends Fragment {
private static final String TAG = CodeRedWidgetHostFragment.class.getSimpleName();
public static final String CODERED_WIDGET_ID = "CODERED_WIDGET_ID";
private SharedPreferences mSharedPrefsWidgets;
AppWidgetManager mAppWidgetManager;
AppWidgetHost mAppWidgetHost;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View parentView = inflater.inflate(R.layout.widget_host, null);
mSharedPrefsWidgets = getActivity().getSharedPreferences("codered_widgets", 0);
mAppWidgetManager = AppWidgetManager.getInstance(getActivity());
mAppWidgetHost = new AppWidgetHost(getActivity(), R.id.APPWIDGET_HOST_ID);
createWidget(parentView);
return parentView;
}
@Override
public void onStart() {
super.onStart();
mAppWidgetHost.startListening();
}
@Override
public void onStop() {
super.onStop();
mAppWidgetHost.stopListening();
}
@Override
public void onResume() {
super.onResume();
createWidget(getView());
}
/**
* Creates the widget and adds to our view layout.
*/
public void createWidget(View v) {
if (v != null) {
// Remove any existing widgets from the widget host
((ViewGroup) v).removeAllViews();
int appWidgetId = mSharedPrefsWidgets.getInt(CODERED_WIDGET_ID, -1);
if (appWidgetId > -1) {
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
AppWidgetHostView hostView = mAppWidgetHost.createView(getActivity(), appWidgetId, appWidgetInfo);
hostView.setAppWidget(appWidgetId, appWidgetInfo);
((ViewGroup) v).addView(hostView);
Log.i(TAG, "The widget size is: " + appWidgetInfo.minWidth + "*" + appWidgetInfo.minHeight);
}
}
}
}
Building on Clemens answer, the AppWidgetHost should be alive during the entire lifecycle of your application. This means that regardless of Activity you should have an instance of AppWidgetHost and AppWidgetManager somewhere easily accessible to your app.
public class YourApp extends Application {
private static final int HARDCODED_ID = 0;
private static AppWidgetHost appWidgetHost;
private static AppWidgetManager appWidgetManager;
@Override
public void onCreate() {
super.onCreate();
appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
appWidgetHost = new AppWidgetHost(getApplicationContext(), HARDCODED_ID);
appWidgetHost.startListening();
}
@Override
public void onTerminate() {
super.onTerminate();
appWidgetHost.stopListening();
appWidgetHost = null;
}
public static AppWidgetHost getAppWidgetHost() { return appWidgetHost; }
public static AppWidgetManager getAppWidgetManager() { return appWidgetManager; }
}
My current implementation has been updating correctly. Tested with many apps that need 'real-time' updates like my music player widget.
Please keep in mind, that application context was used to ensure that the context for AppWidgetHost and AppWidgetManager would always be available.
Also, newer widgets that use the AppCompat libraries within their widgets currently have a bug in com.android.support:appcompat-v7:23.1.1 dependencies. To avoid this use application context when calling the following.
AppWidgetHostView hostView = YourApp.getAppWidgetHost()
.createView(context.getApplicationContexxt(), appWidgetId, info);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With