Modal dialog (popup) from Android widget example

11 May 2013
By Gonçalo Marques
In this tutorial you will learn how to open a modal popup (or dialog) from an Android home screen widget.

Introduction

Android widgets only contain a subset of the available UI components and functionality when compared to Android activities. This means that if we have a requirement that needs something a bit more sophisticated than the functionality provided by widgets, we may need to implement some workarounds in order to achieve our goal. In this tutorial we will see how we can launch a modal popup dialog from an Android widget.

Used software:

  1. Android SDK 21.0.0

A simple widget

In this tutorial we will use a widget that consists in a simple button. When the user presses the button the application will show a modal popup containing some random text and a dismiss button. The button widget will look similar to the following image:

Simple widget consisting only in a Show button
Android widget - show button


Note: This tutorial will not focus on how to create an Android widget. It will only focus in showing a modal popup fired by the widget itself.

We declare out widget in AndroidManifest.xml:


<receiver
  android:name=".BytesLoungeWidget"
  android:icon="@drawable/ic_launcher"
  android:label="Bytes Lounge Widget" >
    <intent-filter>
      <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
      <action android:name="com.byteslounge.android.widgetshowdialog" />
    </intent-filter>

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

Note that we are registering our widget to listen for com.byteslounge.android.widgetshowdialog intent. This intent will be fired when we press the Show modal popup dialog button.

Following next is our simple widget implementation:

Widget implementation

package com.byteslounge.android;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;

public class BytesLoungeWidget extends AppWidgetProvider {

  private static final String SHOW_DIALOG_ACTION = 
     "com.byteslounge.android.widgetshowdialog";
  
  @Override
  public void onUpdate(Context context, 
      AppWidgetManager appWidgetManager,
      int[] appWidgetIds) {

    prepareWidget(context);

    super.onUpdate(context, appWidgetManager, appWidgetIds);

  }

  @Override
  public void onReceive(final Context context, Intent intent) {
    // If the intent is the one that signals
    // to launch the modal popup activity
    // we launch the activity
    if(intent.getAction().equals(SHOW_DIALOG_ACTION)) {

      Intent i = new Intent(context, WidgetDialogActivity.class);
      i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      context.startActivity(i);

    }

    super.onReceive(context, intent);

  }
  
  private void prepareWidget(Context context) {
    
    AppWidgetManager appWidgetManager = 
      AppWidgetManager.getInstance(context);

    ComponentName thisWidget = 
      new ComponentName(context, BytesLoungeWidget.class);

    // Fetch all instances of our widget 
    // from the AppWidgetManager manager.
    // The user may have added multiple 
    // instances of the same widget to the 
    // home screen
    int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
    for (int widgetId : allWidgetIds) {

      RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
          R.layout.widget_layout);

      // Create intent that launches the
      // modal popup activity
      Intent intent = new Intent(context, BytesLoungeWidget.class);
      intent.setAction(SHOW_DIALOG_ACTION);
      
      PendingIntent pendingIntent = PendingIntent.getBroadcast(
          context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
      
      // Attach the onclick listener to 
      // the widget button
      remoteViews.setOnClickPendingIntent(R.id.w_show_btn,
          pendingIntent);

      appWidgetManager.updateAppWidget(widgetId, remoteViews);

    }
  }

}

We should note a couple of things in the widget implementation:

The first one is that we are registering the widget button onclick event to launch a specific intent - com.byteslounge.android.widgetshowdialog.

The second one is that we are handling this intent in the widget itself - inside onReceive method. This method will handle the intent and will launch a completely separate activity that will contain the modal popup. The widget is configured to handle this specific intent as we defined in AndroidManifest.xml.

The modal popup activity

We have seen in the previous section that we can launch a separate activity when the user clicks the widget Show button. Now we need to define an activity which look and feel looks like a modal popup. We go back to AndroidManifest.xml and define a new activity:


<activity
  android:name="com.byteslounge.android.WidgetDialogActivity"
  android:noHistory="true"
  android:theme="@android:style/Theme.Dialog" />

We defined our activity to use the Theme.Dialog theme. This will configure our modal popup dialog activity to look like a native Android dialog.

Now we define the activity content in a separate file, lets say /res/layout/widgetdialog_activity.xml:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="220dp"
  android:layout_height="wrap_content"
  android:background="@drawable/modalbckg"
  android:gravity="center_horizontal"
  android:orientation="vertical" >

  <TextView
    android:id="@+id/w_dialog_txt"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="0dp"
    android:layout_marginRight="0dp"
    android:layout_marginTop="5dp"
    android:layout_marginBottom="10dp"
    android:gravity="center_horizontal"
    android:textColor="#000000"
    android:textSize="13sp" />

  <Button
    android:id="@+id/w_dismiss_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Dismiss" />

</LinearLayout>

The activity consists in a layout that holds the modal dialog text and dismiss button. We are also defining the background of the modal popup as @drawable/modalbckg. In this drawable you configure the look and feel of the modal popup itself. In this tutorial we defined the popup with rounded corners and white background:

modalbckg.xml

<?xml version="1.0" encoding="UTF-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
  android:shape="rectangle"> 
  <gradient android:startColor="#FFFFFF" android:endColor="#FFFFFF" 
    android:angle="90"/>

  <corners android:bottomRightRadius="2dp" android:bottomLeftRadius="2dp" 
    android:topLeftRadius="2dp" android:topRightRadius="2dp"/>
     
  <stroke  android:width="1dp" android:color="#888888"/>
      
</shape>

This file should be placed in /res/drawable/modalbckg.xml

Following next is the activity implementation:

Modal dialog activity

package com.byteslounge.android;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class WidgetDialogActivity extends Activity {

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.widgetdialog_activity);

    String dialogText = "This is the dialog text";
    TextView txt = (TextView) findViewById(R.id.w_dialog_txt);
    txt.setText(dialogText);

    Button dismissbutton = (Button) findViewById(R.id.w_dismiss_btn);
    dismissbutton.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        WidgetDialogActivity.this.finish();
      }
    });
  }
}

We basically set the modal dialog text and configure the activity dismiss button to finish the activity itself when pressed.

Now when we press the Show button our modal popup activity will be launched and will look like the following:

Modal popup activity
Android widget - modal popup

Related Articles

Comments

About the author
Gonçalo Marques is a Software Engineer with several years of experience in software development and architecture definition. During this period his main focus was delivering software solutions in banking, telecommunications and governmental areas. He created the Bytes Lounge website with one ultimate goal: share his knowledge with the software development community. His main area of expertise is Java and open source.

GitHub profile: https://github.com/gonmarques

He is also the author of the WiFi File Browser Android application: