Android Question How to receive shortcuts sent by other apps

NeoTechni

Well-Known Member
Licensed User
Longtime User
There's guides here on how to make shortcuts from your app, how would you make a launcher that can receive them?
 

NeoTechni

Well-Known Member
Licensed User
Longtime User
The launcher is done. I just need to know how to listen for the intents and what intents to listen for. I tried the ones in the guide but couldn't get it to reliably fire
 
Upvote 0

NeoTechni

Well-Known Member
Licensed User
Longtime User
B4X:
Sub Service_Start (StartingIntent As Intent)
   Select Case StartingIntent.Action
     Case "com.android.launcher.action.INSTALL_SHORTCUT"
       HandleNewShortcut(StartingIntent)
   end select
end sub

'VarTypes: java.lang.String java.lang.Boolean
Sub GetParceableExtra(StartingIntent As Intent, Extra As String, Default As String) As Object
   'LogColor( startingintent.HasExtra(extra) & " / " & Extra & " / " & Default, Colors.Green)
   If Not(StartingIntent.HasExtra(Extra)) Then Return Default
   Dim r As Reflector, tempstr As String , IsTempstrNull As Boolean
   r.Target = StartingIntent
   tempstr = r.RunMethod2("getParcelableExtra", Extra, "java.lang.String")
   IsTempstrNull= tempstr=Null Or (tempstr ="null")
   If tempstr = Null Or IsTempstrNull Then Return Default
   'Log(Extra & " tempstr=null" & (tempstr=Null) & " " & IsTempstrNull)
   Try
     If tempstr.Length  = 0 Then Return Default
     'Log(Extra & " GetParceableExtra: " & tempstr & " " & Default)
   Catch
     Return Default
   End Try
 
   Return tempstr
End Sub

Sub ParseExtras(StartingIntent As Intent) As Map
   Dim ExtrasString As String = StartingIntent.ExtrasToString
   ParseShortcutExtra(StartingIntent)

   LogColor(ExtrasString, Colors.Red)
   Dim tempMap As Map ,tempstr() As String , temp As Int , Key As String, Value As String
   tempMap.Initialize
   ExtrasString = API.Mid(ExtrasString, 8, ExtrasString.Length-10) & ", "
   tempstr= Regex.Split(", ", ExtrasString)
   For temp = 0 To tempstr.Length-1
     Key=API.getside(tempstr(temp), "=", True, False).Trim
     Value= StartingIntent.GetExtra(Key)' API.Right(tempstr(temp), tempstr(temp).Length- Key.Length -1).Trim
     tempMap.Put( Key, Value)
     LogColor("ParseExtras: " & Key & " = " & Value, Colors.Green)
   Next
   Return tempMap
End Sub

Sub ParseShortcutExtra(StartingIntent As Intent)
   Dim NewIntent As Intent = StartingIntent.GetExtra("android.intent.extra.shortcut.INTENT")
   Dim Name As String = StartingIntent.GetExtra("android.intent.extra.shortcut.NAME")
   Dim Icon As String = StartingIntent.GetExtra("android.intent.extra.shortcut.ICON")

   Log("NewIntent: " & NewIntent)
   Log("Name: " & Name)
   Log("Icon: " & Icon)
   Log("----------------")
   'android.intent.extra.shortcut.INTENT=Intent { act=android.intent.action.VIEW dat=http://warnersretrocorner.com/wp-content/uploads/imported/A3-80s-Replica-Reproduction-Video-Game-PRINT-Box-Art-Poster-Nes-Conan-barbarian-190876195313.jpg pkg = null
   'android.intent.extra.shortcut.ICON = null
   'android.intent.extra.shortcut.NAME = A3-80s-Replica-Reproduction-Video-Game-PRINT-Box-Art-Poster-Nes-Conan-barbarian-190876195313.jpg (290×400)
End Sub

'Sub GetBundle(Bundle)
'Dim jintent As JavaObject = StartingIntent
'Dim widgetOptions As JavaObject = jintent.RunMethod("getBundleExtra", Array As Object("appWidgetOptions"))
'Log(widgetOptions.RunMethod("getInt", Array As Object("appWidgetMaxHeight")))
'End Sub

Sub HandleNewShortcut(StartingIntent As Intent)
   'Bundle[{android.intent.extra.shortcut.INTENT=Intent { act=android.intent.action.MAIN cmp=com.nkahoang.screenstandby/.ManualBrightnessChangerActivity (has extras) },
   'duplicate=True, android.Intent.extra.Shortcut.NAME=23% Brightness, android.Intent.extra.Shortcut.ICON_RESOURCE=com.nkahoang.screenstandby:drawable/brightnessico}]
 
   'Bundle[{duplicate=false, android.intent.extra.shortcut.NAME=Screen off shortcut, android.intent.extra.shortcut.ICON_RESOURCE=com.nkahoang.screenstandby:drawable/ic_launcher}]
   'Extras: Bundle[{android.intent.extra.shortcut.INTENT=Intent { act=android.intent.action.VIEW dat=http://warnersretrocorner.com/wp-content/uploads/imported/A3-80s-Replica-Reproduction-Video-Game-PRINT-Box-Art-Poster-Nes-Conan-barbarian-190876195313.jpg pkg=com.android.chrome (has extras) }, android.intent.extra.shortcut.ICON=android.graphics.Bitmap@2b7afcf3, android.intent.extra.shortcut.NAME=A3-80s-Replica-Reproduction-Video-Game-PRINT-Box-Art-Poster-Nes-Conan-barbarian-190876195313.jpg (290×400)}]
   Dim E_Extras As String = StartingIntent.ExtrasToString, E_Map As Map = ParseExtras(StartingIntent), temp As Int, tempstr As String
   Dim E_Intent As String, E_Duplicate As String, E_Name As String, E_Icon As String
   Dim BMPd As BitmapDrawable, BMP As Bitmap' , Obj As Object  'AndroidResources1 As AndroidResources,
 
   For temp = 0 To E_Map.Size-1
     'LogColor(temp & ": '" & E_Map.GetKeyAt(temp) & "' = '" & E_Map.GetValueAt(temp) & "'", Colors.Blue)
     'Log(E_Map.Get( E_Map.GetKeyAt(temp) ) )
     tempstr=API.lCase(E_Map.GetKeyAt(temp))
     Select Case tempstr
       Case "android.intent.extra.shortcut.intent": E_Intent=E_Map.GetValueAt(temp)
       Case "duplicate": E_Duplicate =E_Map.GetValueAt(temp)
       Case "android.intent.extra.shortcut.name":E_Name=E_Map.GetValueAt(temp)
       Case "android.intent.extra.shortcut.icon_resource":E_Icon=E_Map.GetValueAt(temp)
     End Select
   Next

   E_Intent = GetParceableExtra(StartingIntent, "android.intent.extra.shortcut.INTENT", E_Map.Getdefault("android.intent.extra.shortcut.INTENT",E_Intent ))
   'E_Duplicate = GetParceableExtra(StartingIntent, "duplicate", E_Map.Getdefault("duplicate",E_Duplicate))
   E_Name = GetParceableExtra(StartingIntent, "android.intent.extra.shortcut.NAME", E_Map.Getdefault("android.intent.extra.shortcut.NAME",E_Name))
   E_Icon=GetParceableExtra(StartingIntent, "android.intent.extra.shortcut.ICON_RESOURCE", E_Map.Getdefault("android.intent.extra.shortcut.ICON_RESOURCE",E_Icon))
   If E_Icon.Length = 0 Then
     E_Icon=GetParceableExtra(StartingIntent, "android.intent.extra.shortcut.ICON", E_Map.Getdefault("android.intent.extra.shortcut.ICON",E_Icon))
     If E_Icon.Length > 0 Then
       BMP = GetBMP(StartingIntent, "android.intent.extra.shortcut.ICON")
     End If
   Else
     BMP = GetBMP(StartingIntent, "android.intent.extra.shortcut.ICON_RESOURCE")
   End If
 
   Dim FinishingIntent As Intent = GetIntent(StartingIntent, "android.intent.extra.shortcut.INTENT")
   E_Map = ParseExtras(FinishingIntent)
 
   'LogColor("New icon: " & E_Extras, Colors.Red)
   'LogColor("E_Duplicate: " & E_Duplicate, Colors.blue)'blank
   'LogColor("E_Icon: " & E_Icon, Colors.blue)'E_Icon:
 
 
 
   'Bundle[{android.intent.extra.shortcut.INTENT=Intent { act=android.provider.action.QUICK_CONTACT dat=content://com.android.contacts/contacts/lookup/1628i93960c00cd394a2/147 flg=0x14018000 pkg=com.google.android.contacts cmp=com.google.android.contacts/com.android.contacts.quickcontact.QuickContactActivity (has extras) }, android.intent.extra.shortcut.ICON=android.graphics.Bitmap@bf8535f, android.intent.extra.shortcut.NAME=NAME OF CONTACT}]
   LogColor("E_Intent: " & E_Intent, Colors.blue)'Is an intent
       'act=android.provider.action.QUICK_CONTACT
       'dat=content://com.android.contacts/contacts/lookup/1628i93960c00cd394a2/147
       'flg=0x14018000
       'pkg=com.google.android.contacts
       'cmp=com.google.android.contacts/com.android.contacts.quickcontact.QuickContactActivity (has extras)
   LogColor("E_Name: " & E_Name, Colors.blue)'E_Name: NAME OF CONTACT
   LogColor("D_Icon: " & BMP, Colors.blue)'D_Icon: (Bitmap) Not initialized

   LogColor("act: " & FinishingIntent.Action, Colors.red)'android.provider.action.QUICK_CONTACT
   LogColor("flg: " & FinishingIntent.Flags, Colors.red)'335642624
   LogColor("dat: " & GetParameter(FinishingIntent, "dat"), Colors.red)
   LogColor("cmp: " & GetParameter(FinishingIntent, "cmp"), Colors.red)
   LogColor("pkg: " & GetParameter(FinishingIntent, "pkg"), Colors.red)
 
   LogColor(E_Map, Colors.Magenta)
End Sub

Sub GetBMP(StartingIntent As Intent, Key As String) As Bitmap
   Dim r As Reflector
   r.Target = StartingIntent
   Dim bmp As Bitmap = r.RunMethod2("getParcelableExtra", Key, "java.lang.String")
   Return bmp
End Sub
Sub GetIntent(StartingIntent As Intent, Key As String) As Intent
   Dim r As Reflector
   r.Target = StartingIntent
   Dim bmp As Intent = r.RunMethod2("getParcelableExtra", Key, "java.lang.String")
   Return bmp
End Sub
Sub GetParameter(StartingIntent As Intent, Key As String) As String
   Dim r As Reflector
   r.Target = StartingIntent
   Return r.GetField(Key)
End Sub

I'm having trouble getting the last 3 data keys (dat, cmp, pkg)
They show up when I log(FinishingIntent), but I can't get those fields. Even trying GetParameter results in an error:
java.lang.NoSuchFieldException: No field dat in class Landroid/content/Intent; (declaration of 'android.content.Intent' appears in /system/framework/framework.jar)

(Sorry it took so long, I haven't worked on this since then...)
 
Upvote 0

NeoTechni

Well-Known Member
Licensed User
Longtime User
For now I'm cheating:

Replace:

B4X:
LogColor("dat: " & GetParameter(FinishingIntent, "dat"), Colors.red)
LogColor("cmp: " & GetParameter(FinishingIntent, "cmp"), Colors.red)
LogColor("pkg: " & GetParameter(FinishingIntent, "pkg"), Colors.red)
and
B4X:
Sub GetParameter(StartingIntent AsIntent, Key AsString) AsString
  Dim r As Reflector
  r.Target = StartingIntent
  Return r.GetField(Key)
End Sub

with:
B4X:
  LogColor("dat: " & GetParameter(FinishingIntent, E_Intent, "dat"), Colors.red)
   LogColor("cmp: " & GetParameter(FinishingIntent, E_Intent, "cmp"), Colors.red)
   LogColor("pkg: " & GetParameter(FinishingIntent, E_Intent, "pkg"), Colors.red)
B4X:
Sub GetParameter(StartingIntent As Intent, StringIntent As String, Key As String) As String
   StringIntent = StringIntent.Replace("}", " ")
   Return GetBetween(StringIntent, Key & "=", " ")
   'Dim r As Reflector
   'r.Target = StartingIntent
   'Return r.GetField(Key)
End Sub
Sub GetBetween(Text As String, Start As String, Finish As String) As String
   Dim Temp As Int,temp2 As Int
   Temp=Text.IndexOf(Start)
   If Temp>-1 Then
     temp2=Text.IndexOf2(Finish, Temp+ Start.Length  +1)
     Return Mid(Text, Temp+Start.Length,temp2-Temp-Start.Length)
   End If
End Sub

I know it's the wrong way to get it, but it's the only way that works at the moment
 
Upvote 0
Top