Search code examples
androidandroid-appwidget

How can i run methods in AppWidget?


i learned today how to develop AppWidget and my question is, how can i run methods in the app widget? example: I have a button in the xml and i want the button calculate something. -the part of create the widget works fine and now i want to add some methods to the button. how does its works in "App Widgets"?

here is my code:

public class WorkClockWidget extends AppWidgetProvider {

    MySharedPreferences shared;
    RemoteViews views;
    private Context context;
    private String text;

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {

        for (int i = 0; i < appWidgetIds.length; i++) {

             views = new RemoteViews(context.getPackageName(), R.layout.clock_widget);

             /// i have button in the "R.layout.clock_widget" .
             //what i need to do if i want the button run the  "someText()" method?


            appWidgetManager.updateAppWidget(appWidgetIds[i], views);

        }
    }


    //The method i want to run when i press on the button.
    public String someText(){
        System.out.println("Works!!!");
        return "Test if this method works";
    }



}

One more question: If i want my widget add data to my database, i have to use contentProvider?


Solution

  • You can't call a method directly, but you can fire an Intent. One way would do this would be to have an Intent send a broadcast, using PendingIntent.getBroadcast. (I'm not sure you need the category in there, but that's how I do that in my own code, so I'm including it in this example.)

    Intent intent = new Intent("com.myapp.button_press").addCategory("com.myapp");
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
    views.setOnClickPendingIntent(R.id.widget_button, pendingIntent);
    

    Next you need a BroadcastReceiver to receive that broadcast. One sneaky way to do that is to use your AppWidgetProvider class as the receiver, since that what an app widget really is. You would have to modify the manifest entry for your app widget to include the Intent that you've created in onUpdate:

    <receiver android:name=".widget.MintAppWidgetProvider">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
            <action android:name="com.myapp.button_press"/>
            <category android:name="com.myapp"/>
        </intent-filter>
    
        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/my_provider_info"/>
    </receiver>
    

    Also, when you override onReceive, be sure to call super.onReceive if the Intent is not your special Intent, so that the base AppWidgetProvider class can process the normal intent and call onUpdate.

    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        if ("com.myapp.button_press".equals(action)) {
            // First handle your special intent action
            someText();
        } else {
            // otherwise let Android call onUpdate
            super.onReceive(context, intent);
        }
    }