Android Development 5: Implementation of App Widgets, an application widget, androidwidgets

Source: Internet
Author: User

Android Development 5: Implementation of App Widgets, an application widget, androidwidgets

 

Preface

This is mainly to implement an Android Application that implements static broadcast and dynamic broadcast to change the widget content, that is, to modify the content based on the experiment in the previous blog, so the focus of this experiment is the implementation of AppWidget widgets ~

First, let's briefly talk about what a Widget is ~

Application widgets are tiny application views that can be embedded into other applications (such as desktops) and receive periodic updates. You can use an App Widget provider to publish a Widget. The application component that can hold other App widgets is called the App Widget host.

Widgets are a piece of information displayed on the desktop. You can also click widgets to jump to a program. The system comes with a program. The typical Widget is music. This Android built-in music playing applet. This is a typical Widget + app application. A program can be started either through a Widget or through an App. Widget is an AppWidgetProvider + UI interface display (a lot of Intent is pre-bound). The information on the interface can be changed through program control. Click the Widget and the control on can only send one Intent, or send a Service Startup notification. AppWidgetProvider can intercept this Intent and process it accordingly (for example, display new information ).

 

Basic knowledge

To create an App Widget, you need the following:

AppWidgetProviderInfo object

Describe the metadata of an App Widget, such as the layout, update frequency, and AppWidgetProvider class of the App Widget. This should be defined in XML.

Implementation of the AppWidgetProvider class

Define basic methods to allow you to program and connect to App widgets, which is based on broadcast events. When the App Widget is updated, enabled, disabled, or deleted, you will receive broadcast notifications.

View Layout

Define the initial layout for this App Widget in XML.

In addition, you can implement an App Widget configuration activity. This is an optional Activity. When you add an App Widget, it is loaded and allowed to modify the settings of the App Widget during creation.

 

Add widgets: press the menu key and click the widgets option. Find the corresponding widget and drag it to the desktop. Different API versions are displayed slightly differently.

 

 

A typical Android Widget has three main components: a border, a frame, graphical controls, and other elements. After a Widget class is created in Android Studio, related files are generated directly.

 

First, declare the AppWidgetProvider class in the AndroidManifest. xml file of the application, for example:

<receiver Android:name="ExampleAppWidgetProvider" >    <intent-filter>        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />    </intent-filter>    <meta-data android:name="android.appwidget.provider"               android:resource="@xml/example_appwidget_info" /></receiver>

The <Cycler> element requires the android: name attribute, which specifies the AppWidgetProvider used by the App Widget.

The <intent-filter> element must contain an <action> element containing the android: name attribute. This element specifies that AppWidgetProvider accepts ACTION_APPWIDGET_UPDATE broadcast. This is the only broadcast that you must explicitly declare. When necessary, AppWidgetManager automatically sends all other App widgets to AppWidgetProvider.

The <meta-data> element specifies the AppWidgetProviderInfo resource and requires the following attributes:

      • Android: name-specifies the metadata name.
      • Android: resource-specifies the AppWidgetProviderInfo resource path.

 

1.Widget layout file widget_demo.xmlThe layout contains an ImageView and a TextView. Requirement: The text color is red, the size is 20dp, and the overall background is transparent. The final effect is as follows:

  

 

2.Add AppWidgetProviderInfo metadata

AppWidgetProviderInfo defines the basic features of an App Widget, such as the minimum layout size, initial layout resource, refresh frequency, and (optional) a configuration activity loaded during creation. Use a separate <appwidget-provider> element to define the AppWidgetProviderInfo object in the XML resource and save it to the res/xml/directory of the project.

The Widget content provider file widget_demo_info.xml is used to edit the file and set its size attributes and layout, for example:

  

MinWidth indicates the minimum width, minHeight indicates the minimum height, and initialLayout indicates the initial layout.

 

3.Modify WidgetDemo. java code, Override the onUpdate method, and add events for the Widget to return to the home page.

The RemoteView architecture is used to access the home screen and modify the content of a specific area by a user program. The RemoteView architecture allows a user program to update the View on the home screen. When a Widget is clicked to activate and click an event, Android forwards the event to the user program, which is processed by the AppWidgetProviders class so that the user program can update the widgets on the home screen.

 

 

  PendingIntent is a special Intent. The main difference is that the execution of the Intent is immediate, and the execution of the pendingIntent is not immediate. The static method of this method class is getActivity (Context, int, Intent, int), corresponding to the operation of the Intent jump to an activity component.

 

Use the AppWidgetProvider class

You must declare your AppWidgetProvider class as a broadcast receiver by using the <javaser> element in the inventory file (see Declaring an App Widget in the Manifest above ).

The AppWidgetProvider class extends BroadcastReceiver to a simple class to process App Widget broadcasts. AppWidgetProvider only receives event broadcasts related to this App Widget. For example, this App Widget is updated, deleted, enabled, and disabled. When these broadcast events occur, AppWidgetProvider receives the following method call:

OnUpdate (Context, AppWidgetManager, int [])

This method is called to Update App widgets cyclically. The interval is defined by the updatePeriodMillis attribute in AppWidgetProviderInfo (see add AppWidgetProviderInfo metadata ). This method is also called when the user adds an App Widget. Therefore, it should perform basic settings, such as defining the event processor for the view and starting a temporary Service, if needed. However, if you have already declared a configuration activity, this method will not be called when users add App widgets, but will only be called when subsequent updates are made. The configuration activity should be responsible for the first update when the configuration is complete. (See Creating an App Widget Configuration Activity below to create an App Widget Configuration Activity .)

OnDeleted (Context, int [])

Called when the App Widget is deleted from the host.

OnEnabled (Context)

It is called when an App Widget instance is created for the first time. For example, if a user adds two widgets to your App, they will only be called for the first time. If you need to open a new database or execute other settings that only happen once for all App Widget instances, this is a good place to complete this job.

OnDisabled (Context)

This API is called when the last instance of your App Widget is deleted from the host. You should clean up onEnabled (Context), such as deleting a temporary database.

OnReceive (Context, Intent)

This is called when each broadcast is received, and before the preceding callback function. You usually do not need to implement this method, because the default AppWidgetProvider is used to filter all App Widget broadcasts and call the above method properly.

Note:In Android 1.5, there is a known issue that the onDeleted () method is not called during this call. To avoid this problem, you can implement onReceive () as described in Group post to receive the onDeleted () callback.

The most important AppWidgetProvider callback function is onUpdated (), because it is called when each App Widget is added to the host (unless you use a configuration activity ). If your App Widget needs to accept any user interaction event, you need to register the event processor in this callback function. If your App Widget does not create temporary files or databases, or performs other work to be cleared, onUpdated () may be the only callback function you need to define.

 

4.Override onReceive Method

Override the onReceive method in the Widget class. You need to use RemoteView and Bundle here. Data processing is performed when the corresponding broadcast is received.

The main functions used in the if Condition Statement are setTextViewText and setImageViewResource. Then, update the Widget using the AppWidgetManager class.

 

Lab content

Implement an Android Application, static broadcast, and dynamic broadcast to change the widget content. Modified based on the previous verification, so some content about static dynamic broadcast will be brief.

Specific requirements:

 

(1) This interface is displayed after the application is started.

  

The initial situation of the widget is as follows:

  

 

(2) Click the static Registration button to jump to the following interface.

  

Click form project. For example, banana. The widget changes accordingly. Click the image on the Widget to jump back to the home page.

  

 

(3) Click the Dynamic Registration button to jump to the following interface. Implement the following functions:

A) You can edit the broadcast information and click Send to Send the broadcast.

B) set a button to register and deregister the broadcast receiver.

C) if the broadcast receiver has been registered, the sent broadcast information can promptly update the text content on the Widget on the desktop and update it to the default dynamic image.

D) Click the image on the Widget to jump back to the home page.

  

 

Lab procedure

First, create a Widget class in Android Studio and directly generate relevant files, including the XML file of the interface layout, the provider file of the widget (xml), and AndroidMenifest in the project. the xml file adds a handler tag. We need to add a filter update event and point it to the Widget class we created previously.

AndroidMenifest. in the xml file, the intent-filter filters out the APPWIDGET_UPDATE event, which is an update event triggered by the system. Each widget must contain this event; the meta-data tag describes the pointer of the widget configuration file, which describes some basic information of the widget (the staticreceiver is also filtered out in intent-filter because it needs to be implemented in static registration ):

<receiver            android:name=".MyAppWidget"            android:enabled="true"            android:exported="true">            <intent-filter>                <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>                <action android:name="com.example.yanglh6.myapplication4.staticreceiver" />            </intent-filter>            <meta-data                android:name="android.appwidget.provider"                android:resource="@xml/my_app_widget_info"/></receiver>

  

Next, compile the widget's provider File Information (xml) as required. minWidth and minHeight are the minimum width and height of the widget. This value is a reference value and the system will change according to the actual situation, the initialLayout attribute specifies the view layout file of the widge. The updatePeriodMillis attribute specifies the update interval of the widget, in milliseconds:

<?xml version="1.0" encoding="utf-8"?><appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"    android:initialKeyguardLayout="@layout/my_app_widget"    android:initialLayout="@layout/my_app_widget"    android:minHeight="55dp"    android:minWidth="200dp"    android:previewImage="@drawable/example_appwidget_preview"    android:resizeMode="horizontal|vertical"    android:updatePeriodMillis="86400000"    android:widgetCategory="home_screen"></appwidget-provider>

 

The following figure shows the interface layout. In this example, an ImageView control and a TextView control are required:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:gravity="center">    <ImageView        android:id="@+id/WidgetImage"        android:layout_width="60dp"        android:layout_height="60dp"        android:gravity="center"        android:src="@mipmap/apple"/>    <TextView        android:id="@+id/WidgetName"        android:layout_width="wrap_content"        android:layout_height="60dp"        android:textColor="@color/red"        android:textSize="20dp"        android:layout_toRightOf="@+id/WidgetImage"        android:text="Apple"        android:gravity="center"/></RelativeLayout>

 

The layout file implements a layout as follows:

 

In the Widget, rewrite the onUpdate method to add events to the Widget so that the Widget can return to the home page. Here, we need to use a RemoteView architecture that allows a user program to access the home screen and modify content in a specific area. The RemoteView architecture allows a user program to update the View on the home screen. When a Widget is clicked to activate and click an event, Android forwards the event to the user program, which is processed by the AppWidgetProviders class so that the user program can update the widgets on the home screen.

    @Override    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {        super.onUpdate(context, appWidgetManager, appWidgetIds);        Intent clickInt = new Intent(context, MainActivity.class);        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, clickInt, 0);        RemoteViews view = new RemoteViews(context.getPackageName(),R.layout.my_app_widget);        view.setOnClickPendingIntent(R.id.WidgetImage, pendingIntent);        appWidgetManager.updateAppWidget(appWidgetIds, view);    }

 

Next, rewrite the onReceive method in the Widge class. You need to use RemoteView and Bundle here. Data processing is performed when the corresponding broadcast is received (because we use AndroidMenifest. when registering an xml file, the APPWIDGET_UPDAT event and staticreceiver both point to the Widge class. So here we delete the StaticReceiver class and add the rewriting Part Of The OnReceive function to the Widget class ):

@ Override public void onReceive (Context context, Intent intent) {Log. I ("debug", intent. toString (); super. onReceive (context, intent); RemoteViews view = new RemoteViews (context. getPackageName (), R. layout. my_app_widget); Bundle bundle = intent. getExtras (); String widgetName = bundle. getString ("name"); int widgetImage = bundle. getInt ("ItemImage"); if (intent. getAction (). equals ("com. example. yanglh6.myapplication4. staticreceiver ") {view. setTextViewText (R. id. widgetName, widgetName); view. setImageViewResource (R. id. widgetImage, widgetImage); AppWidgetManager appWidgetManager = AppWidgetManager. getInstance (context); appWidgetManager. updateAppWidget (new ComponentName (context, MyAppWidget. class), view); Bitmap bitmap = BitmapFactory. decodeResource (context. getResources (), bundle. getInt ("ItemImage"); int imageId = (int) bundle. get ("ItemImage"); icationicationmanager icationmanager = (icationicationmanager) context. getSystemService (Context. NOTIFICATION_SERVICE); Notification. builder builder = new Notification. builder (context); builder. setContentTitle ("static broadcast "). setContentText (bundle. getString ("name ")). setLargeIcon (bitmap ). setSmallIcon (imageId ). setTicker ("You have a new message "). setAutoCancel (true); Intent Intent1 = new Intent (context, MainActivity. class); PendingIntent pendingIntent = PendingIntent. getActivity (context, 0, Intent1, 0); builder. setContentIntent (pendingIntent); Notification using Y = builder. build (); icationicationmanager. Y (0, notify );}}

 

Rewrite the onReceive method of the Widget:

public void onReceive(Context context, Intent intent) {        Log.i("debug", intent.toString());        super.onReceive(context, intent);        RemoteViews view = new RemoteViews(context.getPackageName(),R.layout.my_app_widget);        Bundle bundle = intent.getExtras();        String widgetName = bundle.getString("name");        int widgetImage = bundle.getInt("ItemImage");        if (intent.getAction().equals("com.example.yanglh6.myapplication4.staticreceiver")) {            view.setTextViewText(R.id.WidgetName, widgetName);            view.setImageViewResource(R.id.WidgetImage, widgetImage);            AppWidgetManager appWidgetManager=AppWidgetManager.getInstance(context);            appWidgetManager.updateAppWidget(new ComponentName(context, MyAppWidget.class), view);     }    }

 

For dynamic registration, you do not need to add a handler in AndroidMenifest. xml, but register in DynamicActivity:

 dynamicReceiver = new DynamicReceiver();                    IntentFilter dynamic_filter = new IntentFilter();                    dynamic_filter.addAction("com.example.yanglh6.myapplication4.dynamicreceiver");                    registerReceiver(dynamicReceiver, dynamic_filter);

 

Therefore, the Onreceive function can only be rewritten in DynamicReceiver during dynamic registration to update the Widget (similar to static registration ):

@ Override public void onReceive (Context context, Intent intent) {if (intent. getAction (). equals ("com. example. yanglh6.myapplication4. dynamicreceiver ") {Bundle bundle = intent. getExtras (); Bitmap bitmap = BitmapFactory. decodeResource (context. getResources (), bundle. getInt ("ItemImage"); int imageId = bundle. getInt ("ItemImage"); RemoteViews view = new RemoteViews (context. getPackageName (), R. layout. my_app_widget); String widgetName = bundle. getString ("name"); view. setTextViewText (R. id. widgetName, widgetName); view. setImageViewResource (R. id. widgetImage, imageId); AppWidgetManager appWidgetManager = AppWidgetManager. getInstance (context); appWidgetManager. updateAppWidget (new ComponentName (context, MyAppWidget. class), view); icationicationmanager icationmanager = (icationicationmanager) context. getSystemService (Context. NOTIFICATION_SERVICE); Notification. builder builder = new Notification. builder (context); builder. setContentTitle ("dynamic broadcast "). setContentText (widgetName ). setLargeIcon (bitmap ). setSmallIcon (imageId ). setTicker ("You have a new message "). setAutoCancel (true); Intent mIntent = new Intent (context, MainActivity. class); PendingIntent pendingIntent = PendingIntent. getActivity (context, 0, mIntent, 0); builder. setContentIntent (pendingIntent); Notification using Y = builder. build (); icationicationmanager. Y (0, notify );}}

Complete lab ~

 

Run

  

  

 

Notes

You must fully understand the meaning of each part of AndroidMenifest. xml and the Android mechanism. The registration and orientation of AndroidMenifest. xml must be clear.

For static scenarios, after the sendBroadcast (intent) implementation. xml finds the receiver at intent registration and points to the corresponding broadcast receiving function to implement various events in this function; for dynamic, because it is registered in DynamicActivity, at that time, you can define the dynamic broadcast receiving class.

 

Note

1. experiment environment:

Operating System Windows 10

Experimental software Android Studio 2.2.1

Virtual Device: Galaxy_Nexus

API: 21

2. The code format is not very strict due to the size of the inserted code box during code pasting. Sorry ~

 

Thank you ~

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.