Monday, March 24, 2014

Android Widget Tutorial

Android Widget Tutorial - Hallo sahabat Google Android Developer Tutorial, Pada Artikel yang anda baca kali ini dengan judul Android Widget Tutorial, kami telah mempersiapkan artikel ini dengan baik untuk anda baca dan ambil informasi didalamnya. mudah-mudahan isi postingan Artikel Android widget tutorial, Artikel Contacts content provider, yang kami tulis ini dapat anda pahami. baiklah, selamat membaca.

Judul : Android Widget Tutorial
link : Android Widget Tutorial

Baca juga


Android Widget Tutorial

Android Widget Tutorial
              Android operating system has unique features in which one can create interactive app widgets a small gadget or control that display in other applications such as the home screen Widgets can be very handy as they allow you to put your favourite applications on your homescreen in order to quickly access them. Some common widgets you have probably seen are  music widget , weather widget , clock widget e.t.c.
Widgets can receive periodic updates such as RSS feeds, weather updates, and news articles. Most Android users expect their favorite applications to provide a widget for quick and easy access to information they need, an application executing a long-running task can publish the progress indicator as home screen widget.
We also have to take in to consideration widgets with constantly refreshing data will use battery life and consume data for those users on limited bandwidth mobile data plans. Please keep these factors in mind while you are creating widgets as your users will not be very happy if they get an unexpectedly large cellular bill or if their battery life decreases significantly after installing your widget.
Widgets a technical overview
A Widget runs as part of the process of its host. This requires that Widgets preserve the permissions of their application.To create a Widget one needs to extend AppWidgetProvider class which  is basically a BroadcatReceiver.Widgets use RemoteViews to create there user interface. A RemoteView can be executed by another process with the same permissions as the original application. This way the Widget runs with the permissions of its defining application.The user interface for a Widget is defined by an BroadcastReceiver. This BroadcastReceiver inflates its layout into an object of type RemoteViews. This RemoteViews object is delivered to Android, which hands it over the HomeScreen application.
Widget Creation
To create a Widgets one has to 1.Define a layout file for widget2 .Create an XML file (AppWidgetProviderInfo) which describes the properties of the widget, e.g. size or the fixed update frequency..3Create a BroadcastReceiver which is used to build the user interface of the Widget.4.Enter the Widget configuration in the AndroidManifest.xml file.5.Optionaly you can specify a configuration activity which is called once a new instance of the widget is added to the widget host.

Widget size

A Widget will take a certain amount of cells on the homescreen. A cell is usually used to display the icon of one application. As a calculation rule you should define the size of the widget with the formula: ((Number of columns / rows)* 74) - 2. These are device independent pixels and the -2 is used to avoid rounding issues.
As of Android 3.1 a Widgets can be flexible in size, e.g. the user can make it larger or smaller. To enable this forWidgets you can use the android:resizeMode="horizontal|vertical" attribute in the XML configuration file for the widget.

AppWidgetprovider class methods and Lifecycle.
The following table provides purpose of various AppWidgetprovider class which is the class needed to create an AppWidget. The AppWidgetProvider class implements the onReceive() method, extracts the required information and calls the following widget lifecycle methods.
As you can add several instances of a widget to the homescreen you have lifecycle methods which are called only for the first instance added / removed to the homescreen and others which are called for every instance of your widget.

void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions)
Called in response to the ACTION_APPWIDGET_OPTIONS_CHANGED broadcast when this widget has been layed out at a new size.
void onDeleted(Context context, int[] appWidgetIds)
Called in response to the ACTION_APPWIDGET_DELETED broadcast when one or more AppWidget instances have been deleted. Override this method to implement your own AppWidget functionality.
void onDisabled(Context context) Called once the last instance of your widget is removed from the homescreen.Called in response to the ACTION_APPWIDGET_DISABLED broadcast, which is sent when the last AppWidget instance for this provider is deleted. Override this method to implement your own AppWidget functionality.
void  onEnabled(Context context)
Called the first time an instance of your widget is added to the homescreen.Called in response to the ACTION_APPWIDGET_ENABLED broadcast when the a AppWidget for this provider is instantiated. Override this method to implement your own AppWidget functionality.
void  onReceive(Context context, Intent intent)
Implements onReceive(Context, Intent) to dispatch calls to the various other methods on AppWidgetProvider.
void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
Called for every update of the widget. Contains the ids of appWidgetIds for which an update is needed. Note that this may be all of the AppWidget instances for this provider, or just a subset of them, as stated in the methods JavaDoc. For example if more than one widget is added to the homescreen, only the last one changes (until reinstall).Called in response to the ACTION_APPWIDGET_UPDATE broadcast when this AppWidget provider is being asked to provide RemoteViews for a set of AppWidgets. Override this method to implement your own AppWidget functionality.
All long running operations in these methods should be performed in a service, as the execution time for a broadcast receiver is limited. Using asynchronous processing in the onReceive() method does not help as the system can kill the broadcast process after his onReceive() method.                                                                                                                A widget is restricted in the View classes it can use. As layouts you can use the FrameLayout, LinearLayout andRelativeLayout classes.As views you can use AnalogClock, Button, Chromometer, ImageButton, ImageView,ProgressBar and TextView.                                                                                                           As of Android 3.0 more views are available: GridView, ListView, StackView, ViewFlipper and AdapterViewFlipper.The only interaction that is possible on the Views of a Widget is via on OnClickListener. This OnClickListener can be registered on a widget and is triggered by the user.
Remote Views
          The workhorse behind Android AppWidgets is the RemoteViews widget. RemoteViews is a parcelable data structure (so it can be sent through Android IPC) that captures an entire view structure. The creator of the RemoteViews sets up this data structure, by specifying the base layout and setting field values. This has no effect on the UI and therefore background components like services, broadcast event handlers, etc. can also do it. In fact, AppWidgets are broadcast event receivers, they process broadcasts from Launcher and respond with RemoteViews. When the RemoteViews data structure is received and deserialized, it can be applied to any ViewGroup of the UI and can therefore appear on the UI of another application. From this point of view, it works just like a hypertext document except that RemoteViews describes Android views and not general web controls.
4. Widget updates
                   A Widget gets its data on a periodic timetable. There are two methods to update a widget, one is based on an XML configuration file and the other is based on the Android AlarmManager service.
In the widget configuration file you can specify a fixed update interval. The system will wake up after this time interval and call your broadcast receiver to update the widget. The smallest update interval is 1800000 milliseconds (30 minutes).
The AlarmManager allows you to be more resource efficient and to have a higher frequency of updates. To use this approach you define a service and schedule this service via the AlarmManager regularly. This service updates the widget.
Please note that a higher update frequency will wake up the phone from the energy safe mode. As a result your widget consumes more energy.
This Demonstrative project creates a Home screen widget which fetches all the contacts list in ascending order and makes it available with photo,name and number available in widget in a customized manner so that user can move through the contacts with simple tap on forward and reverse buttons and make call to people easily.


1.Create  Android project with details as listed in the table below.
Property name
Property value
Project name
SRM_WidgetTutorial
Package name
in.ac.srmuniv.widgettutorial
Activity name
-
Layout xml name
Contacts.xml
2.Copy the code  to the file contacts.xml in res/layout folder 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LinearLayout1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/contactsviewbackground"
    android:orientation="vertical" >

    <Button
        android:id="@+id/phone"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center|bottom"
         android:background="@drawable/buttonbackground"
        android:text="phone no"
        android:textColor="#003399"
        android:textSize="26sp"
        android:textStyle="bold" />
       <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center">
            <ImageView
        android:id="@+id/widget_image"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_gravity="center"
        android:src="@drawable/me" />
       <RelativeLayout
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
 >
 <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center|top"
        android:layout_alignParentTop="true"
        android:text="Name"
        android:textColor="#003399"
        android:textSize="24sp"
        android:textStyle="bold" />
             <ImageView
        android:id="@+id/imageButton1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:src="@drawable/forwardicon"
        android:layout_gravity="bottom"/>
       </RelativeLayout>
     </FrameLayout>
 
</LinearLayout>
3.Copy the code in ContactsWidgetProvider.java. AppWidgetProvider.
packagein.ac.srmuniv.widgettutorial;

importjava.io.FileNotFoundException;
import java.io.IOException;
importin.ac.srmuniv.widgettutorial.R;
importandroid.app.PendingIntent;
importandroid.appwidget.AppWidgetManager;
importandroid.appwidget.AppWidgetProvider;
importandroid.content.ComponentName;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.database.Cursor;
importandroid.graphics.Bitmap;
import android.net.Uri;
importandroid.provider.ContactsContract;
importandroid.provider.MediaStore;
import android.util.Log;
importandroid.widget.RemoteViews;

public classContactsWidgetProvider extends AppWidgetProvider {

       private static int clickCount = 0;
       private static boolean flag=true;
       String Number="09840889310";

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

              RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.contacts);
              remoteViews.setOnClickPendingIntent(R.id.widget_image, buildPendingIntent(context,"in.ac.srmuniv.action.CHANGE_PICTURE"));
              remoteViews.setOnClickPendingIntent(R.id.phone,buildPendingIntent(context,"in.ac.srmuniv.action.MAKE_PHONE"));
              remoteViews.setOnClickPendingIntent(R.id.forwardbackimage
              pushWidgetUpdate(context, remoteViews);
       }


       @Override
       public void onReceive(Context context, Intent intent) {
              if(intent.getAction().equals("in.ac.srmuniv.action.CHANGE_PICTURE")){
                     Log.w("Widget", "OnRecive called");
                     // Build the intent to call the service
                     updateWidgetPictureListener(context);
              }
              if(intent.getAction().equals("in.ac.srmuniv.action.MAKE_PHONE")){
                     Log.w("Widget", "BUTTON PRESSED");
                     Intent callIntent = new Intent(Intent.ACTION_CALL);
                     callIntent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);

                     callIntent.setData(Uri.parse("tel:"+updateWidgetButtonListener(context)));
                     context.startActivity(callIntent);
              }
              if(intent.getAction().equals("in.ac.srmuniv.action.FORWARD_BACK")){
                     Log.w("Widget", "Forward Back");
                     RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.contacts);
                     if(flag)
                     {
                           flag=false;
                           remoteViews.setImageViewResource(R.id.forwardbackimage

                     }
                     else
                     {
                           flag=true;
                           remoteViews.setImageViewResource(R.id.forwardbackimage


                     }
                     pushWidgetUpdate(context.getApplicationContext(), remoteViews);
              }
              super.onReceive(context, intent);
       }
       public  PendingIntent buildPendingIntent(Context context,String action) {
              Intent intent = new Intent();
              intent.setAction(action);
              return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
       }

       public static voidpushWidgetUpdate(Context context, RemoteViews remoteViews) {
              ComponentName myWidget = new ComponentName(context, ContactsWidgetProvider.class);
              AppWidgetManager manager = AppWidgetManager.getInstance(context);
              manager.updateAppWidget(myWidget, remoteViews);       
       }

       private String updateWidgetButtonListener(Context context) {
              Cursor phones = context.getContentResolver().query(
                           ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,
                           null,"UPPER(" + ContactsContract.Contacts.DISPLAY_NAME + ") ASC");
              int count = phones.getCount();
              Log.w("Widget","Number " + Number+" and count: "+count);

              phones.moveToPosition(((clickCount-1)%count)) ;

              String Number = phones
                           .getString(phones
                                         .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
              phones.close();
              return Number;

       }
       private voidupdateWidgetPictureListener(Context context) {
              Cursor phones = context.getContentResolver().query(
                           ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,
                           null,"UPPER(" + ContactsContract.Contacts.DISPLAY_NAME + ") ASC");
              int count = phones.getCount();
              Log.w("Widget","count: "+count);
              if(flag)

                     phones.moveToPosition(clickCount++%count) ;
              else
              {
                     phones.moveToPosition(clickCount--%count) ;
                     if(clickCount==0)
                           clickCount=count;
              }
              Log.w("Widget", "ClickCount"+clickCount);
              String Name = phones
                           .getString(phones
                                         .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
              String Number = phones
                           .getString(phones
                                         .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

              String image_uri = phones
                           .getString(phones
                                         .getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));

              Log.w("Widget", Name + ", Number " + Number
                           + ", image_uri " + image_uri);


              phones.close();
              RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.contacts);

              Bitmap bitmap;
              try {
                     Uri imageUri = Uri.parse( image_uri);
                     bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), imageUri);
                     remoteViews.setImageViewBitmap(R.id.widget_image,bitmap);
              }
              catch(NullPointerException e) {

                     remoteViews.setImageViewResource(R.id.widget_image,R.drawable.personicon);

              }catch(FileNotFoundException e) {

                     remoteViews.setImageViewResource(R.id.widget_image,R.drawable.personicon);

              } catch (IOException e) {
                     remoteViews.setImageViewResource(R.id.widget_image,R.drawable.personicon);
              }
              remoteViews.setTextViewText(R.id.name, Name);
              remoteViews.setTextViewText(R.id.phone,Number);
              pushWidgetUpdate(context.getApplicationContext(), remoteViews);
       }
}
4.Create xml folder in res directory and add app-widgetprovider xml file named as contacts_widgetprovider.xml
<?xml version="1.0"encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/contacts"
    android:minHeight="146dp"
    android:minWidth="146dp"
    android:updatePeriodMillis="180000"
    >
</appwidget-provider>
5.Create buttonbackground.xml file in drawable-hpdi folder for drawing button background.
<?xml version="1.0"encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <stroke
        android:width="2dp"
        android:color="#FFFFFFFF" />

    <gradient
        android:angle="225"
        android:endColor="#DD0D6AD9"
        android:startColor="#DD86F4F3" />

    <corners
        android:bottomLeftRadius="7dp"
        android:bottomRightRadius="7dp"
        android:topLeftRadius="7dp"
        android:topRightRadius="7dp" />

</shape>
6.Similarly Create contactsbackground.xml file in drawable-hpdi folder for drawing contacts image background.
<?xml version="1.0"encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <stroke
        android:width="2dp"
        android:color="#FFFFFFFF" />

    <gradient
        android:angle="225"
        android:endColor="#EE320972"
        android:startColor="#EE98F0EB" />

    <corners
        android:bottomLeftRadius="7dp"
        android:bottomRightRadius="7dp"
        android:topLeftRadius="7dp"
        android:topRightRadius="7dp" />
</shape>
7.Modify the AndroidManifest file with added permissions as listed below.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="in.ac.srmuniv.widgettutorial"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="11"
        android:targetSdkVersion="17" />

    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.CALL_PHONE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <receiver android:name="in.ac.srmuniv.widgettutorial.ContactsWidgetProvider">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
                <action android:name="in.ac.srmuniv.action.CHANGE_PICTURE"/>
                <action android:name="in.ac.srmuniv.action.MAKE_PHONE"/>
                <action android:name="in.ac.srmuniv.action.FORWARD_BACK"/>
              
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/contacts_widgetprovider"/>
        </receiver> 
    </application>
</manifest>
8.Run the program in emulator/device with already added contacts preferably with images of people contacts.
9.Drag the widget from widgets to Home screen to instaniate widget.
                                                                       
Figure 1 Shows Widget when installed.  Figure 2 Shows when widget is dragged to Home Screen 
10.Click the contact to change contacts.Click forward and reverse button to move contacts forward or backword.Click contact button to make phone call.

Figure 3 Shows tapping the image will move to next contact  in descending direction  Figure 4 Shows moving contacts from list in ascending direction.
Figure 5 Shows When phone number button is pressed phone call Activity is called
Code Explanation::
             The widget layout is designed to have a compact and easy access to user.When widget is loaded to the home screen default image and text are shown (Refer Figure 2).Frame layout is used .A overlap of contacts people picture,name and forward/reverse contacts navigation  buttons appear on top of it .
                          When Widget is dragged to the Home Screen onEnabled() method  followed by onUpgrade() method is called.OnUpgarde() method is called when ever AppWidget provider is being asked to provide RemoteViews for a set of AppWidgets.We have registered for broadcast  action ACTION_APPWIDGET_UPDATE in our manifest file.
  There are three remote views in our application.Event handling for all these three views   are registered  with pending intent which will broadcast action message.It will be received by onRecive() method in AppWidgetProvider class.onRecive() method  will dispatch calls to various other methods of AppWidgetProvider.
1.widget_image: It is an image view when clicked  onRecive() method is called with broadcast action messag"in.ac.srmuniv.CHANGE_PICTURE". Contacts content provider Cursor is moved to next (or) previous contact.Contacts PhotoUri, phone number and name are fetched.widget_image  will display person photo from Contacts photo uri if photo does not exist default image is displayed.Phone number is updated in phone button Name of the contact is displayed in TextView.
2.forwardbackimage:It is also an image view when clicked  onRecive() method is called with broadcast action messag"in.ac.srmuniv.FORAWRD_BACK".Here a toggle flag is changed to decide the logic  either to move contact cursor forward or backward.The toggle flag enables  to fetch contacts in ascending order or descending order on widget_image click (Refer Figure 3 and Figure 4).
               if(flag)
                      phones.moveToPosition(clickCount++%count) ;
               else
               {
                      phones.moveToPosition(clickCount--%count) ;
                      if(clickCount==0)
                            clickCount=count;
               }               
3.phone: It is a Button when clicked  onRecive() method is called with broadcast action messag"in.ac.srmuniv.MAKE_PHONE". On click of  the phone_button phone call intent will be called.with phone no fetched from current cursor position from the Contacts content provider.The following code shows the Activity call from a widget.(Refer Figure 5)
           Intent callIntent = new Intent(Intent.ACTION_CALL);
                      callIntent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
                      
 callIntent.setData(Uri.parse("tel:"+updateWidgetButtonListener(context)));

                           context.startActivity(callIntent);

Every time  pushWidgetUpdate(context.getApplicationContext(), remoteViews);
is called to update views .

   


Demikianlah Artikel Android Widget Tutorial

Sekianlah artikel Android Widget Tutorial kali ini, mudah-mudahan bisa memberi manfaat untuk anda semua. baiklah, sampai jumpa di postingan artikel lainnya.

Anda sekarang membaca artikel Android Widget Tutorial dengan alamat link https://googleandroiddevelopertutorial.blogspot.com/2014/03/android-widget-tutorial.html

Artikel Terkait

Android Widget Tutorial
4/ 5
Oleh

Berlangganan

Suka dengan artikel di atas? Silakan berlangganan gratis via email