androidwidgetandroid-widgetshortcutandroid-shortcut

How can you create Shortcuts from an Android Widget?


I'm trying to add a new widget functionality to my app, which allows you to create pinned shortcuts from a 'shortcut widget.'

Normally shortcuts in Android are created like in the video below. You long-press the application, select a shortcut, and then you can pin the shortcut onto the homescreen. My app currently implements shortcuts like this following Android developer guidelines.

However, I noticed the Settings app allows you to create many more shortcuts for your app, by allowing shortcuts to be created through the Settings widget like in the video below.

I would like to give users of my app the ability to create shortcuts for the many features in my app, however, most launchers can only display four shortcuts from long-pressing.

Does anyone know how the to implement a App Widget that allows you to create many shortcuts, like the Settings app has implemented?


Solution

  • Though it is added from the App widget section, it's not even related to appwidgetprovider. If you're trying to create an app widget, then you're on the wrong path.

    I've grabbed some code from my existing projects, hope this helps :)

    1.add required permission to AndroidManifest.xml

        <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
    

    2.add intent-filter <action android:name="android.intent.action.CREATE_SHORTCUT"/> , so your AndroidManifest.xml should be something like this:

        <activity
            android:name=".ui.SetupWizardActivity"
            android:label="@string/create_shortcut_label">
            <intent-filter>
                <action android:name="android.intent.action.CREATE_SHORTCUT"/>
            </intent-filter>
        </activity> 
    

    with those lines added, when the user drags the activity from the widget section to home, the desired activity will be opened.

    3.Here's the code used to create a shortcut:

    import android.content.Context;
    import android.content.Intent;
    import android.widget.Toast;
    
    import androidx.annotation.DrawableRes;
    import androidx.core.content.pm.ShortcutInfoCompat;
    import androidx.core.content.pm.ShortcutManagerCompat;
    import androidx.core.graphics.drawable.IconCompat;
    
    public class ShortcutCreator {
    
        public static void vCreateShortcutByActivityClass(Context context, String strShortcutID, Class<?> ActivityClass, String strLabelName, @DrawableRes int resourceID){
    
            if (ShortcutManagerCompat.isRequestPinShortcutSupported(context)){
                Intent intent = new Intent(context, ActivityClass).setAction(Intent.ACTION_MAIN);
                ShortcutInfoCompat sic =
                        new ShortcutInfoCompat.Builder(context, strShortcutID).setIntent(intent).setShortLabel(strLabelName).setIcon(IconCompat.createWithResource(context, resourceID)).build();
                ShortcutManagerCompat.requestPinShortcut(context, sic, null);
    
            }else{
    
                Toast.makeText(context, "Device doesn't support creating shortcuts.", Toast.LENGTH_SHORT).show();
    
            }
        }
    
    }
    

    Note: ShortcutID is used to determine if there're duplicated shortcuts.

    4.Now you can do the following modification to your desired activity to call the code for creating shortcut(the activity that displays many options for creating different shortcuts):

            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
        
                final String strIntentAction = getIntent().getAction();
                if (TextUtils.equals(strIntentAction,Intent.ACTION_CREATE_SHORTCUT)) {
                    setContentView(R.layout.activity_shortcut);
                    //display selections here and let user choose shortcut
                    //...deleted
                    vCreateShortcutByActivityClass(this, "ID_0", SetupWizardActivity.class, "App Settings", R.mipmap.ic_launcher);
                    finish();
                    return;
                }
                
                setContentView(R.layout.activity_main);
                //codes of your activity opened from launcher
                //...deleted
            }
    

    or you can also create a new blank activity for creating a "single" shortcut, without calling setContentView(), if you only need to create one shortcut:

            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                vCreateShortcutByActivityClass(this, "ID_0", MainActivity.class, "App Settings", R.mipmap.ic_launcher);
                finish();
            }
    

    Note : For devices under Android Nougat(7.1), the target activity that the shortcut tries to open must contain at least one intent-filter tag(can be any, consider adding <category android:name="android.intent.category.DEFAULT"/> for hidden activities), otherwise the shortcut may display "app is not installed".