Android Question Create Multiple Widgets for an App [Solved]

shubas

Member
Licensed User
Hello everyone - I have been searching for an answer to my very simple question, however upon my search I found out it was not such a simple question after all. (Maybe I was searching all wrong never the less, let's go on).

I have created an app which works normally like any ordinary app should. Then I thought it would be good to have widgets in the home screen that performs some of hte functionality of the app (tasks like sending a message or making a call). Well I searched high and low and found examples (yes I went thru the widget tutorial, both parts) and created one widget. It worked fine as expected. Now I wanted to add another, so I created another Service, pretty much like my previous one and compiled the app. I made the necessary changes to the XML as well. However only my 1st widget appears in the widget list in the emulator, and not the second one. What could possibly be wrong?

Based on your response for, I'll share any additional info that may be required.

Thanks in advance for your help.
 

shubas

Member
Licensed User
Ok, found the solution to my query. The androidmanifest.xml file needs to have the below structure

<service android:name=".widgetservice"> </service>

<receiver
android:name=".widgetservice$widgetservice_BR"
android:label="Name of your widget goes here">

<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>

<meta-data android:name="android.appwidget.provider"
android:resource="@xml/NAMEOFYOURWIDGETSERVICEMODULE_info" />
</receiver>

You have to add this for the number of widgets that you create. The point that is most important is change the name of the service module for each widget. You'll find the reference to the XML files in the Objects\res\XML folder. Put the exact same filename in resource statement.
 

shubas

Member
Licensed User
I missed a line in the abvoe post. You need to add the Service action as well for each widget and the name of the should correspond to the name of your servicemodule.
 

Peter Simpson

Expert
Licensed User
What I would do is create multiple panels on top of each each other, each panel has its own views linked to it as a parent. You can then have the one widget but with multiple layouts (Panels), then you just set which layout (panel) is viewable by setting it visible or not on a settings screen. Basically think of it this way, multiple panels in one widget layout, which ever layout (panel) with its views you want to see you just make it visible, all the other layouts you do not make visible. This way you can have lots of widget layouts and they can all be controlled in your main app.
 
Last edited:

shubas

Member
Licensed User
Yes that's a good idea too Peter. Thanks.
One question though. How do you make a panel visible via the servicemodule? My undertanding is that the servicemodule has all the functionality code in it for the widget. And you couldn't determine which panel the user will select beforehand. I know I can probably save the panel name as a setting but how do I activate the panel? Any pointers?
 

Peter Simpson

Expert
Licensed User
Here you go @shubas,
YourWidget.RV.SetVisible("Panel1", False)
YourWidget.RV.SetVisible("Panel2", True)
YourWidget.RV.SetVisible("Panel3", False)
YourWidget.RV.SetVisible("Panel4", False)
YourWidget.RV.SetVisible("Panel5", False)

Using SetVisible is how you set the panel visibility in widgets. Above Panel2 (Widget layout 1) is viewable in your widget, all the rest are not. Please note that All your layouts (Panels) must share the same main parent panel, that main parent panel has the activity as its parent, see below. Panels can be changed during run time.

In designer:
B4X:
Activity
    MainPanel
        Panel1 (Widget layout 1)
        Panel2 (Widget layout 2)
        Panel3 (Widget layout 3)
        Panel4 (Widget layout 4)
        Panel5 (Widget layout 5)
You can have as many widget layouts (Panels) as you would like.

Enjoy...
 
Last edited:

shubas

Member
Licensed User
Here you go @shubas,
YourWidget.RV.SetVisible("Panel1", False)
YourWidget.RV.SetVisible("Panel2", True)
YourWidget.RV.SetVisible("Panel3", False)
YourWidget.RV.SetVisible("Panel4", False)
YourWidget.RV.SetVisible("Panel5", False)

Using SetVisible is how you set the panel visibility in widgets. Above Panel2 (Widget layout 1) is viewable in your widget, all the rest are not. Please note that All your layouts (Panels) must share the same main parent panel, that main parent panel has the activity as its parent, see below. Panels can be changed during run time.

In designer:
B4X:
Activity
    MainPanel
        Panel1 (Widget layout 1)
        Panel2 (Widget layout 2)
        Panel3 (Widget layout 3)
        Panel4 (Widget layout 4)
        Panel5 (Widget layout 5)
You can have as many widget layouts (Panels) as you would like.

Enjoy...
Thanks you @Peter Simpson
 

shubas

Member
Licensed User
@Peter Simpson
Quick question. I have created a servicemodule called widgetservice4 and in that I have declared a remoteview rv4.
When I use the statement widgetservice4.rv4.SetVisible("Panel1",True), I get an error, Undeclared variable 'widgetservice4' is used before it was assigned any value.
Where should the above code (in your post) be used then?
 

Peter Simpson

Expert
Licensed User
You need to follow the basic ruleswhen first creating a widget @shubas :)

B4X:
Sub Process_Globals
     Dim rv As RemoteViews
End Sub

Sub Service_Create
     rv = ConfigureHomeWidget("LayoutFileName", "rv", 30, "Widget Name")
End Sub

Sub Service_Start (StartingIntent AsIntent)
     If rv.HandleWidgetEvents(StartingIntent) Then Return
End Sub
 

shubas

Member
Licensed User
Hi @Peter Simpson - thank for your repsonse. I've all the code that you have shared above in post #9. What I wanted to know was about hiding/showing panels from within the widget using the code in post #6.
B4X:
Sub Process_Globals
    Dim rv4 As RemoteViews
    Dim flashon As Boolean
  
    End Sub
Sub Service_Create
    'Set the widget to update every day
    rv4 = ConfigureHomeWidget("WFLS", "rv4", 60, "SafetyFirst Flash",True)
    'var22 = setpref.GetString("def2") 'msg
 
'Then I have a label in the layout that i want the user to click and show a panel from the layout.
 
rv4.SetText("Label1","On")
WidgetService4.rv4.SetVisible("WFLS",True) <--- I get error here based on the example you provided in Post#6
rv4.SetTextColor("Label1",Colors.Black)
rv4.UpdateWidget
I may be confusing the layout file and Panels you have mentioned to be part of the layouts.
 
Top