B4A Library AppShortcuts - a Helper to define Dynamic shortcuts (Android 7.1(

This Library help you to define dynamic shortcuts for your app.
A Device with Android 7.1 (Api 25) is needed to use this library.

ShortcutHelper

Author: DonManfred
Version: 1.0
  • ShortcutHelper
    • Functions:
      • addDynamicShortcuts (shortcutInfoList As List) As Boolean
      • createShortcut (shortLabel As CharSequence, longLabel As CharSequence, IconResource As String, intent As android.content.Intent) As android.content.pm.ShortcutInfo
      • disableShortcuts (shortcuts2disable As List, disabledMessage As CharSequence)
      • disableShortcuts2 (shortcuts2disable As List)
      • enableShortcuts (shortcuts2enable As List)
      • Initialize (EventName As String)
      • isRateLimitingActive As Boolean
      • removeAllDynamicShortcuts
      • removeDynamicShortcuts (shortcutIds As List)
      • reportShortcutUsed (shortcutId As String)
      • setDynamicShortcuts (dynamicShortcuts As List) As Boolean
      • updateShortcuts (shortcuts2update As List) As Boolean
    • Properties:
      • DynamicShortcuts As List [read only]
      • IconMaxHeight As Int [read only]
      • IconMaxWidth As Int [read only]
      • ManifestShortcuts As List [read only]
      • MaxShortcutCountPerActivity As Int [read only]
      • PinnedShortcuts As List [read only]


B4X:
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim helper As ShortcutHelper
    Dim cs As CSBuilder
    Dim pm As PackageManager
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")
    helper.Initialize("")
    Log(helper.ManifestShortcuts)
 
    Dim dynshortcuts As List
    dynshortcuts.Initialize
 
    Dim in As Intent
    in = pm.GetApplicationIntent(Application.PackageName)
    in.AddCategory("dynamic")
    in.PutExtra("menu1","HelloWorld")
    dynshortcuts.Add(helper.createShortcut(cs.Initialize.Color(Colors.Red).Append("Hello World!").PopAll,cs.Initialize.Color(Colors.Blue).Append("This is the long label").PopAll,"ic_action_achievement",in))

    Dim in As Intent
    in = pm.GetApplicationIntent(Application.PackageName)
    in.AddCategory("dynamic")
    in.PutExtra("menu2","dynamic2")
    dynshortcuts.Add(helper.createShortcut(cs.Initialize.Color(Colors.Red).Append("2nd dynamic").PopAll,cs.Initialize.Color(Colors.Blue).Append("This is the long label").PopAll,"ic_action_amazon",in))

    Dim in As Intent
    in = pm.GetApplicationIntent(Application.PackageName)
    in.AddCategory("dynamic")
    in.PutExtra("menu3","dynamic3")
    dynshortcuts.Add(helper.createShortcut(cs.Initialize.Color(Colors.Red).Append("3rd dynamic").PopAll,cs.Initialize.Color(Colors.Blue).Append("This is the long label").PopAll,"ic_action_armchair",in))

    helper.setDynamicShortcuts(dynshortcuts)

The Shortcuts can be added fix in the manifest.
See this example @Erel provided.

B4X:
AddActivityText(main, <meta-data android:name="android.app.shortcuts"
  android:resource="@xml/shortcuts" />
)

CreateResource(xml, shortcuts.xml,
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
  <shortcut
  android:shortcutId="compose"
  android:enabled="true"
  android:icon="@drawable/icon"
  android:shortcutShortLabel="@string/compose_shortcut_short_label1"
  android:shortcutLongLabel="@string/compose_shortcut_long_label1"
  android:shortcutDisabledMessage="@string/compose_disabled_message1">
  <intent
  android:action="b4a.shortcut.item1"
  android:targetPackage="b4a.example.shortcut"
  android:targetClass="b4a.example.shortcut.main" />
  <categories android:name="android.shortcut.conversation" />
  </shortcut>
  <!-- Specify more shortcuts here. -->
</shortcuts>
)
CreateResource(values, strings.xml,
<resources>
  <string name="compose_shortcut_short_label1">short label</string>
  <string name="compose_shortcut_long_label1">long label</string>
  <string name="compose_disabled_message1">disabled</string>
</resources>
)

Please note that it is NOT mandatory to define the Shortcuts in the Manifest. They can be fully dynamically created.

BUT: Shortcuts defined in the Manifest will be available for your app directly if you install the app.

The dynamically added are only shown after you FIRST START the app (note that the Dynamics are created in Activity_create).

So i suggest to use them both.
Fixed Shortcuts in Manifest + Dynamics added with this library.

WhatsApp Image 2017-12-23 at 14.36.50.jpeg
 

Attachments

  • res.Icons.zip
    12.7 KB · Views: 406
  • ShortcutHelperEx.zip
    7.5 KB · Views: 412
  • ShortcutHelperV1.0.zip
    5.2 KB · Views: 413
Last edited:

Multiverse app

Active Member
Licensed User
Longtime User
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
main_activity_create (java line: 341)
java.lang.NoSuchMethodError: No virtual method getManifestShortcuts()Ljava/util/List; in class Landroid/content/pm/ShortcutManager; or its super classes (declaration of 'android.content.pm.ShortcutManager' appears in /system/framework/framework.jar)
at de.donmanfred.ShortcutHelperwrapper.getManifestShortcuts(ShortcutHelperwrapper.java:100)
at b4a.example.shortcut.main._activity_create(main.java:341)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:186)
at b4a.example.shortcut.main.afterFirstLayout(main.java:102)
at b4a.example.shortcut.main.access$000(main.java:17)
at b4a.example.shortcut.main$WaitForLayout.run(main.java:80)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

The above is on Galaxy S8, running on 7.0 Is it not possible to make the lib compatible with older versions? Fewer devices will have 7.1
 
Last edited:

DonManfred

Expert
Licensed User
Longtime User
S8, running on 7.0 Is it not possible to make the lib compatible with older versions?
No.
It is a feature which came with Android 7.1
It is not available in any older Version.

You should add a check for the SDK level and only use the Methods of this lib if you are running on Api 25+
 

JohnC

Expert
Licensed User
Longtime User
Hi Don,

The IconResource is the file name of an *already existing* image file.

I have a bitmap image stored in a database that I would like to assign to the new shortcut.

Would it be possible to add a "CreateShortcut2" Method that will accept bitmap data for the icon image parameter?
 

JohnC

Expert
Licensed User
Longtime User
Another question I have is that with other apps that have this dynamic shortcut ability, when the shortcut menu pops up, I am able to drag one of the shortcuts off of the popup menu and create a totally separate icon (additional to the app's icon) on the homescreen.

Then after I create this separate home screen icon, if I then tap and hold on the app's main icon, the shortcut that I moved off of the pop-up menu is no longer displayed in the pop-up menu (this is the desired behavior).

But if I try to move a shortcut off of a pop-up menu using this library, the shortcut still remains in the pop-up menu. Is there a flag that can be set to indicate that if a user drags a shortcut off of the main app's pop-up menu, to also remove that shortcut from the popup menu?

Yes, I could programmically remove that shortcut, but how would I know which shortcut the user dragged off of the pop-up menu so I will know just to remove that one?
 
Last edited:

JohnC

Expert
Licensed User
Longtime User
I guess what would solve both of my above posts would be if you could add support for creating "Pinned" shortcuts with the ability to provide bitmap data for the icon image for the new shortcut.
 
Top