Thursday, 13 October 2011

Custom Notification with Progress bar and Downloading animation

Setting the Custom notification with the progress bar and the downloading animation.

Create a XML layout for custom animated progress notification.

Below is the XML layout for custom notification. (res/layout/custom_progress_animation.xml)


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:background="#FFFFFF">
  
  <ImageView android:id="@+id/progress_anim_notify_image"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_margin="10dp">
  </ImageView>
  
  <RelativeLayout android:id="@+id/progress_anim_content_layout"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_marginTop="10dp"
  android:layout_toRightOf="@+id/progress_anim_notify_image">
 
  <TextView android:id="@+id/progress_anim_title_text"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="Title Content"
  android:textStyle="bold"
  android:textSize="15sp"
  android:textColor="#000000">
  </TextView>
 
  <TextView android:id="@+id/progress_anim_percentage"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_alignParentRight="true"
  android:layout_marginRight="5dp"
  android:text="100 / 100"
  android:textStyle="normal"
  android:textSize="15sp"
  android:textColor="#000000">
  </TextView>
 
  <ProgressBar android:id="@+id/anim_progressBar1"
style="?android:attr/progressBarStyleHorizontal" 
android:layout_width="fill_parent"
android:layout_height="wrap_content" 
android:layout_below="@+id/progress_anim_title_text"
android:layout_marginTop="3dp"
android:indeterminate="false"
android:max="10" 
android:padding="4dip">
</ProgressBar>
 
  </RelativeLayout>
  
</RelativeLayout>


I added one ImageView for downloading animation.
Progress bar for downloading progress and percentage if downloaded.
One TextView for indication downloading in progress and complete.
Another TextView for indicating the percentage level.


Thread and Handler class is used for updating the progress bar.
Thread is used for background process, and it is used to initialize the value of the progress.
You cant call the UI thread in another thread, Progress bar is updated only in the UI thread. For updating the progress bar using background thread, Handler class is used.

Created an int array image_loader for storing the downloading animation images.

noti_anim.flags = Notification.FLAG_ONGOING_EVENT; 
this is a notification flag, by setting this flag, your notification will diaplay in the ongoing event part.


noti_anim.flags = Notification.FLAG_NO_CLEAR; 
this is also the notification flag, by setting this flag, your notification will not be cleared by using the clear button in the notification bar.


You have to add the icon level_list.xml in the res/drawable folder, for animating the image in the notification bar.



<level-list xmlns:android="http://schemas.android.com/apk/res/android">
       <item android:maxLevel="0" android:drawable="@drawable/alert_download_progress_0" />
       <item android:maxLevel="1" android:drawable="@drawable/alert_download_progress_1" />
       <item android:maxLevel="2" android:drawable="@drawable/alert_download_progress_2" />
       <item android:maxLevel="3" android:drawable="@drawable/alert_download_progress_3" />
       <item android:maxLevel="4" android:drawable="@drawable/alert_download_progress_4" />
       <item android:maxLevel="5" android:drawable="@drawable/alert_download_progress_5" />
  </level-list>

For displaying the animation icon, you have to set the icon and icon level in the votification like below


noti_anim.icon = R.drawable.level_list;

noti_anim.iconLevel = 0;


the icon level will be updated in the thread and handler class.


Below is the code for custom notification with progress bar and the downloading animation.



package com.sample.notification;


import java.util.Calendar;


import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RemoteViews;
import android.widget.RemoteViews.RemoteView;


public class Test extends Activity
{
private Button button1;
private static final int NOTIFICAION_ID = 1;

public int[] image_loader={R.drawable.alert_download_progress_0,
R.drawable.alert_download_progress_1,
R.drawable.alert_download_progress_2,
R.drawable.alert_download_progress_3,
R.drawable.alert_download_progress_4,
R.drawable.alert_download_progress_5};

Handler anim_handler=null;

Notification noti_anim;
NotificationManager noti_anim_man;
boolean isStopped=false;
public int image_update_value=0;

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        button1 = (Button) findViewById(R.id.button01);
        button1.setOnClickListener(button1Listner);
        
        onPush("Notification 2","Channel 2");
    }
    
public void onPush(String notification, String channel) 
{
// For Notification with progress bar and download animation
customProgressAnimationNotification(notification, channel); 
}

public void customProgressAnimationNotification(String title, String message)
{
anim_handler=new Handler();

noti_anim_man = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
noti_anim = new Notification();


        Intent notificationIntent = new Intent();        
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);


        RemoteViews contentView = new RemoteViews(getPackageName(),R.layout.custom_progress_animation);
        contentView.setImageViewResource(R.id.progress_anim_notify_image, R.drawable.globe_vista);
contentView.setTextViewText(R.id.progress_anim_title_text, "Download in progress...");
contentView.setProgressBar(R.id.anim_progressBar1, 100, progress, false);
contentView.setTextViewText(R.id.progress_anim_percentage, "0 / 100");


noti_anim.contentView = contentView;
noti_anim.contentIntent = contentIntent;

// Adds the notification as Ongoing event
noti_anim.flags = Notification.FLAG_ONGOING_EVENT; 

// Can not clear the notification using the clear button.
//noti_anim.flags = Notification.FLAG_NO_CLEAR; 

noti_anim.icon = R.drawable.level_list;


noti_anim.iconLevel = 0;
        


Runnable anim_runnable=new Runnable(){


@Override
public void run() 
{
// TODO Auto-generated method stub
for(int i=0;i<=101;i++)
{
final int value=i;
Log.v("Test", "i Value=========>>>"+i);
try 
{
Thread.sleep(300);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
anim_handler.post(new Runnable(){


@Override
public void run() 
{
// TODO Auto-generated method stub

if (noti_anim.iconLevel < 5) 
           {
            noti_anim.iconLevel++;
            image_update_value++;
           }
           else 
           {
            noti_anim.iconLevel = 0;
            image_update_value=0;
           }

if(value==101)
{
Log.v("Test", "=========== Notification Cancelling ==============");
noti_anim.contentView.setTextViewText(R.id.progress_anim_title_text, "Downloading Completed");
noti_anim_man.notify(NOTIFICAION_ID, noti_anim);

// Cancel the Notification
//noti_anim_man.cancel(NOTIFICAION_ID);
}
else
{
noti_anim.contentView.setImageViewResource(R.id.progress_anim_notify_image, image_loader[image_update_value]);
noti_anim.contentView.setProgressBar(R.id.anim_progressBar1, 100, value, false);
noti_anim.contentView.setTextViewText(R.id.progress_anim_percentage, value+" / 100");
noti_anim_man.notify(NOTIFICAION_ID, noti_anim);
}

}
});
}
}
};
new Thread(anim_runnable).start();

}

private OnClickListener button1Listner = new View.OnClickListener() {

public void onClick(View arg0)
{
startActivity(new Intent("com.sample.notification.Notificaions"));
}
};
}


Displayed the notification download animated
 icon at the first left if the notification bar.


Notification with animated image,
progress bar updation, downloading in
progress message and percentage
completed text

Download completed message in the
notification

Display the notification in the notification
area, but this will not cleared by the clear
button.
Animated image downloading notification
displayed at the third icon from the left.
Thos refers, notification is in the
ongoing event

Animated Notification without clear button
but in below of ongoing

Custom Notification with Progress bar

Setting the Progress bar in the custom notification and display that custom notification in the notification bar.

You have to create a XML layout for custom notification.

Below is the XML layout file. (res/layout/custom_progress_notify.xml)


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:background="#FFFFFF">
  
  <ImageView android:id="@+id/progress_notify_image"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:background="@drawable/globe_vista"
  android:layout_margin="10dp">
  </ImageView>
  
  <RelativeLayout android:id="@+id/progress_content_layout"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_marginTop="10dp"
  android:layout_toRightOf="@+id/progress_notify_image">
 
  <TextView android:id="@+id/progress_title_text"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="Title Content"
  android:textStyle="bold"
  android:textSize="15sp"
  android:textColor="#000000">
  </TextView>
 
  <TextView android:id="@+id/progress_percentage"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_alignParentRight="true"
  android:layout_marginRight="5dp"
  android:text="100 / 100"
  android:textStyle="normal"
  android:textSize="15sp"
  android:textColor="#000000">
  </TextView>
 
  <ProgressBar android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal" 
android:layout_width="fill_parent"
android:layout_height="wrap_content" 
android:layout_below="@+id/progress_title_text"
android:layout_marginTop="3dp"
android:indeterminate="false"
android:max="10" 
android:padding="4dip">
</ProgressBar>
 
  </RelativeLayout>
  
</RelativeLayout>


I have added one Imageview, Two Textview and one Progress bar in the layout file.


For loading custom layout in the notification bar,  have to use RemoteView.


Thread and Handler class is used for updating the progress bar.
Thread is used for background process, and it is used to initialize the value of the progress.
You cant call the UI thread in another thread, Progress bar is updated only in the UI thread. For updating the progress bar using background thread, Handler class is used.

Below is the code for Custom Notification with Progress bar.


package com.sample.notification;


import java.util.Calendar;


import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RemoteViews;
import android.widget.RemoteViews.RemoteView;


public class Test extends Activity
{
private Button button1;
private static final int NOTIFICAION_ID = 1;

int progress=0;
Handler handler=null;

RemoteViews v=null;
Notification noti=null;
NotificationManager notiman=null;

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        button1 = (Button) findViewById(R.id.button01);
        button1.setOnClickListener(button1Listner);
        
        onPush("Notification 2","Channel 2");
    }
    
public void onPush(String notification, String channel) 
{
customProgressNotification(notification, channel); // For Notification with progress bar
}

public void customProgressNotification(String title, String message)
{
handler=new Handler();
NotificationManager notfManager = (NotificationManager) 
                                           getSystemService(NOTIFICATION_SERVICE);

CharSequence tickerText  = "Custom Progress Notification";
long when = System.currentTimeMillis();
int icon = R.drawable.notf_icon;
Notification notification = new Notification(icon, tickerText, when);

RemoteViews contentView = new RemoteViews(getPackageName(), 
                                           R.layout.custom_progress_notify);
contentView.setImageViewResource(R.id.progress_notify_image, 
                                                   R.drawable.globe_vista);
contentView.setTextViewText(R.id.progress_title_text, title);
contentView.setProgressBar(R.id.progressBar1, 100, progress, false);
contentView.setTextViewText(R.id.progress_percentage, "0 / 100");
notification.contentView = contentView;

v=contentView;
noti=notification;
notiman=notfManager;

Intent notificationIntent=new Intent(this, Notification.class);
PendingIntent pendingContentIntent=PendingIntent.getActivity(this, 0, 
                                                                            notificationIntent, 0);
notification.contentIntent=pendingContentIntent;

Runnable runnable=new Runnable(){


@Override
public void run() 
{
// TODO Auto-generated method stub
for(int i=0;i<=100;i++)
{
final int value=i;
Log.v("Test", "i Value=========>>>"+i);
try 
{
Thread.sleep(200);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
handler.post(new Runnable(){


@Override
public void run() 
{
// TODO Auto-generated method stub
noti.contentView.setProgressBar(R.id.progressBar1, 
                                                                                      100, value, false);
noti.contentView.setTextViewText(R.id.progress_percentage,
                                                                                              value+" / 100");
notiman.notify(NOTIFICAION_ID, noti);
}
});
}
}
};
new Thread(runnable).start();

}

private OnClickListener button1Listner = new View.OnClickListener() {

public void onClick(View arg0)
{
startActivity(new Intent("com.sample.notification.Notificaions"));
}
};
}


Below is the Screen shot.






Custom Notification

Setting the Custom Notification in Notification Bar.

Required a custom XML Layout for setting the custom notification.

Following is the XML layout file. (res/layout/custom_notify).


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:background="#FFFFFF">
  
  <ImageView android:id="@+id/notify_image"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:background="@drawable/correct_image"
  android:layout_margin="10dp">
  </ImageView>
  
  <RelativeLayout android:id="@+id/content_layout"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_marginTop="10dp"
  android:layout_toRightOf="@+id/notify_image">
 
  <TextView android:id="@+id/title_text"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="Title Content"
  android:textStyle="bold"
  android:textSize="15sp"
  android:textColor="#000000">
  </TextView>
 
  <TextView android:id="@+id/message_text"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_below="@+id/title_text"
  android:layout_marginTop="3dp"
  android:text="Message Content"
  android:textSize="15sp"
  android:textColor="#000000">
  </TextView>
 
  </RelativeLayout>
  
</RelativeLayout>


I have used one Imageview and two TextView in the custom notofication layout.


You have to use RemoteView for setting the custom notification in the notification bar.

Following is the code for setting custom notification in the notification bar.


package com.sample.notification;


import java.util.Calendar;


import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RemoteViews;
import android.widget.RemoteViews.RemoteView;


public class Test extends Activity
{
private Button button1;
private static final int NOTIFICAION_ID = 1;

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        button1 = (Button) findViewById(R.id.button01);
        button1.setOnClickListener(button1Listner);
        
        onPush("Notification 2","Channel 2");
    }
    
public void onPush(String notification, String channel) 
{
customNotification(notification, channel); // For Custom Notification
}

public void customNotification(String title, String message)
{
NotificationManager notfManager = (NotificationManager) 
                       getSystemService(NOTIFICATION_SERVICE);

CharSequence tickerText  = "Custom Notificaions";
long when = System.currentTimeMillis();
int icon = R.drawable.notf_icon;
Notification notification = new Notification(icon, tickerText, when);

RemoteViews contentView = new RemoteViews(getPackageName(),  
                                                       R.layout.custom_notify);
contentView.setImageViewResource(R.id.notify_image,
                                                            R.drawable.correct_image);
contentView.setTextViewText(R.id.title_text, title);
contentView.setTextViewText(R.id.message_text, message);
notification.contentView = contentView;

Intent notificationIntent=new Intent(this, Notification.class);
PendingIntent pendingContentIntent=PendingIntent.getActivity(this, 
                                                                                  0, notificationIntent, 0);
notification.contentIntent=pendingContentIntent;

notfManager.notify(NOTIFICAION_ID, notification);
}

private OnClickListener button1Listner = new View.OnClickListener() {

public void onClick(View arg0)
{
startActivity(new Intent("com.sample.notification.Notificaions"));
}
};
}


Following is the Screen shot for Custom Notification.





You can also add the vibration and LED light color Display like the default notification.

Refer this link for below link for default notification, adding vibration and LED light color change.
http://tjkannan.blogspot.com/2011/10/default-notification.html


Default Notification

Setting the default notification to the notification bar.

For setting the default notification, we have to use the android Notification Manager, Notification, Pending Intent.

Notification Manager - For getting notification service and setting the notification.
Notification - For adding contents inside the notification.
Pending Intent- For calling the activity on clicking the notification.

In notification, first we have to instantiate the notification, that will describe which application notification you are receiving..

For Instantiating the notification, below code is used.


               CharSequence tickerText  = "Default Notificaion";
long when = System.currentTimeMillis();
int icon = R.drawable.notf_icon;
Notification notification = new Notification(icon, tickerText, when);


This code will display a small icon at left side followed by the notification text.

At the time of receiving notification, you can set the vibration or display light color.

For setting the vibration, Below code is used.and you have to add permission in the manifest file.


notification.defaults = Notification.DEFAULT_VIBRATE; 


this will set the default vibration.

                         (or)


You can also define the your own vibration pattern.

int dot = 200;      // Length of a Morse Code "dot" in milliseconds
int dash = 500;     // Length of a Morse Code "dash" in milliseconds
int short_gap = 200;    // Length of Gap Between dots/dashes
int medium_gap = 500;   // Length of Gap Between Letters
int long_gap = 1000;    // Length of Gap Between Words
long[] pattern = {
   0,  // Start immediately
   dot, short_gap, dot, short_gap, dot,    // s
   medium_gap,
   dash, short_gap, dash, short_gap, dash, // o
   medium_gap,
   dot, short_gap, dot, short_gap, dot,    // s
   long_gap
};
notification.vibrate=pattern;


For setting the LED light color, the below code is used. Setting LED light color is fully depends upon the Hardware support.


notification.defaults=Notification.DEFAULT_LIGHTS;


this will set the default LED light.
                               
                                  (or)
You can also define your owl light color by using the below code.

notification.ledARGB = 0xff0000ff;
notification.ledOnMS = 300;
notification.ledOffMS = 1000;
notification.flags |= Notification.FLAG_SHOW_LIGHTS;


The complete code for Default Notification with Vibration and the LED light display is as follows.



package com.sample.notification;

import java.util.Calendar;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RemoteViews;
import android.widget.RemoteViews.RemoteView;

public class Test extends Activity
{
private Button button1;
private static final int NOTIFICAION_ID = 1;
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        button1 = (Button) findViewById(R.id.button01);
        button1.setOnClickListener(button1Listner);
        
        onPush("Notification 2","Channel 2");
    }
    
public void onPush(String notification, String channel) 
{
stausBarNotificaion(notification, channel); // For Default Notification
}
public void stausBarNotificaion(String message, String Channel)
{
String ns = NOTIFICATION_SERVICE;
NotificationManager notfManager = (NotificationManager) getSystemService(ns);
CharSequence tickerText  = "Default Notificaion";
long when = System.currentTimeMillis();
int icon = R.drawable.notf_icon;
Notification notification = new Notification(icon, tickerText, when);
Context context = this.getApplicationContext();
CharSequence contentTitle = "A.B.C.E.F.G.H | TESTING";
CharSequence contentText = message;
Intent notificaionIntent = new Intent("com.sample.notification.Notificaions");
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificaionIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
//notification.defaults = Notification.DEFAULT_VIBRATE;
int dot = 200;      // Length of a Morse Code "dot" in milliseconds
int dash = 500;     // Length of a Morse Code "dash" in milliseconds
int short_gap = 200;    // Length of Gap Between dots/dashes
int medium_gap = 500;   // Length of Gap Between Letters
int long_gap = 1000;    // Length of Gap Between Words
long[] pattern = {
   0,  // Start immediately
   dot, short_gap, dot, short_gap, dot,    // s
   medium_gap,
   dash, short_gap, dash, short_gap, dash, // o
   medium_gap,
   dot, short_gap, dot, short_gap, dot,    // s
   long_gap
};
notification.vibrate=pattern;
//notification.defaults=Notification.DEFAULT_LIGHTS;
notification.ledARGB = 0xff0000ff;
notification.ledOnMS = 300;
notification.ledOffMS = 1000;
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
notfManager.notify(NOTIFICAION_ID,notification);
}
private OnClickListener button1Listner = new View.OnClickListener() {
public void onClick(View arg0)
{
startActivity(new Intent("com.sample.notification.Notificaions"));
}
};
}

Screen shot for the Results.