Reputation: 31
I have created a test Android launcher application and installed it on a rooted device as a system app. The goal is for the app to place all installed widgets on fragments of a viewpager. This has been successfully accomplished; however, the user is shown a message every time a new page is shown.
Even if the user checks the box, the message is still shown every time a widget is to be added.
I have generally followed the steps in Hosting widgets in an android launcher and Adding widgets to a launcher page without bindAppWidgetId() to add widgets to the app.
First I get a list of widgets in the class that extends application and store it in a public static variable
AppWidgetManager manager = AppWidgetManager.getInstance(this);
widgetList = manager.getInstalledProviders();
Next I use a bind intent to get the widget
appWidgetManager = AppWidgetManager.getInstance(this.getActivity());
appWidgetHost = new AppWidgetHost(this.getActivity(), APPWIDGET_HOST_ID);
int id = appWidgetHost.allocateAppWidgetId();
Intent bindIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
bindIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id);
bindIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER,LauncherExperiment.widgetList.get(mParam1).provider);
startActivityForResult(bindIntent, REQUEST_BIND_APPWIDGET);
Then on activity result I create the widget
Bundle extras = data.getExtras();
int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
AppWidgetProviderInfo appWidgetInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
AppWidgetHostView hostView = appWidgetHost.createView(this.getActivity(), appWidgetId, appWidgetInfo);
hostView.setAppWidget(appWidgetId, appWidgetInfo);
// Add it on the layout you want
myLayout.addView(hostView);
Again, I have rooted the device and installed the app as a system app by updating the manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.launcherexperiment"
android:sharedUserId="android.uid.system" >
And by following the steps here: How can I sign my application with the system signature key?
So in summary, I have been able to successfully bind apps and display them; but the issue is that the warning message should be displayed at most one time.
Upvotes: 3
Views: 5143
Reputation: 955
Here we go! With this code the user will only be shown the dialog once. It also shows a complete solution for adding widgets programmatically.
As I will be updating this on my github, look here for the latest version, https://github.com/DagW/FragmentHomescreen/blob/master/app/src/main/java/se/dw/fragmenthomescreen/widget/WidgetFragment.java.
But for archiving purposes here is the way I do it now.
/**
* checkToAddWidget
* <p/>
* At the creation of WidgetFragment,
* add a default widget so that the homescreen is not empty
* shows how to add widgets programmatically
*/
private void checkToAddWidget () {
MainActivity m = (MainActivity) getActivity();
AppWidgetManager manager = m.getAppWidgetManager();
AppWidgetHost host = m.getAppWidgetHost();
List<AppWidgetProviderInfo> widgetList = manager.getInstalledProviders();
AppWidgetProviderInfo searchProvider = null;
AppWidgetProviderInfo search2Provider = null;
AppWidgetProviderInfo clockProvider = null;
for ( AppWidgetProviderInfo info : widgetList ) {
Log.d(TAG, info.provider.getPackageName() + " " + info.provider.getClassName());
if ( info.provider.getClassName().equals("com.google.android.googlequicksearchbox.SearchWidgetProvider") ) {
searchProvider = info;
break;
}
if ( info.provider.getClassName().equals("com.android.alarmclock.AnalogAppWidgetProvider") ) {
clockProvider = info;
}
if ( info.provider.getClassName().equals("com.android.alarmclock.DigitalAppWidgetProvider") ) {
clockProvider = info;
}
if ( info.provider.getClassName().equals("com.android.quicksearchbox.SearchWidgetProvider") ) {
search2Provider = info;
}
}
if ( searchProvider != null || search2Provider != null || clockProvider != null ) {
AppWidgetProviderInfo provider = null;
if ( searchProvider != null ) {
provider = searchProvider;
} else if ( clockProvider != null ) {
provider = clockProvider;
} else {
provider = search2Provider;
}
addProvider(m, host, manager, provider);
}
}
public void addProvider (MainActivity m, AppWidgetHost host, AppWidgetManager manager, AppWidgetProviderInfo provider) {
int id = host.allocateAppWidgetId();
boolean success = false;
success = manager.bindAppWidgetIdIfAllowed(id, provider.provider);
if ( success ) {
AppWidgetHostView hostView = host.createView(getActivity(), id, provider);
AppWidgetProviderInfo appWidgetInfo = manager.getAppWidgetInfo(id);
LauncherAppWidgetInfo info = new LauncherAppWidgetInfo(id);
info.setHostView(hostView);
info.getHostView().setAppWidget(id, appWidgetInfo);
ItemInfo launcherInfo = attachWidget(info);
if ( launcherInfo != null ) {
WidgetPersistance.addDesktopAppWidget(screen, launcherInfo);
}
} else {
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, provider.provider);
m.startActivityForResult(intent, MainActivity.REQUEST_BIND_APPWIDGET);
}
}
You might also need
<uses-permission android:name="android.permission.BIND_APPWIDGET"
tools:ignore="ProtectedPermissions"/>
Upvotes: 3