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