Zachary Sweigart
Zachary Sweigart

Reputation: 31

Android Adding Widgets To App Programmatically Warning Message

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.

no description

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

Answers (1)

DagW
DagW

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

Related Questions