Thursday 13 October 2011

Download and Install App programmatically


You can download an apk file of any application and install it thru your app and all this you can do programmatically. Let's see how to do it:

1. First download the apk file programmatically and store it in external storage.

private void download(){
try {
    URL url = new URL("url from apk file is to be downloaded");
    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
    urlConnection.setRequestMethod("GET");
    urlConnection.setDoOutput(true);
    urlConnection.connect();

    File sdcard = Environment.getExternalStorageDirectory();
    File file = new File(sdcard, "filename.ext");

    FileOutputStream fileOutput = new FileOutputStream(file);
    InputStream inputStream = urlConnection.getInputStream();

    byte[] buffer = new byte[1024];
    int bufferLength = 0;

    while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
        fileOutput.write(buffer, 0, bufferLength);
    }
    fileOutput.close();

} catch (MalformedURLException e) {
        e.printStackTrace();
} catch (IOException e) {
        e.printStackTrace();
}
}

Permission: To write to external storage, you need to add this permission:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Note: The above download method can be used to download any file and store the file to external storage.

2. Now initiate installing process.

private void initiateInstallation(){
    Intent intent = new Intent(Intent.ACTION_VIEW);
    Uri uri = Uri.fromFile(new File("/sdcard/filename.apk"));
    intent.setDataAndType(uri, "application/vnd.android.package-archive");
    startActivity(intent);
}



Monday 10 October 2011

Working with Call log







We often need to access call log details i.e. incoming number, outgoing number, missed call. We want to modify the call log i.e. make your own entry, deleting an existing entry. So let's see how can we do all this:



Uri UriCalls = Uri.parse("content://call_log/calls");
Cursor cursor = getApplicationContext().getContentResolver().query(UriCalls, null, null, null, null);


//Reading call log entries...
if(cursor.getCount() > 0){
    cursor.moveToFirst();
    while(!cursor.isAfterLast()){
        String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER)); // for  number
        String name = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME));// for name
        String duration = cursor.getString(cursor.getColumnIndex(CallLog.Calls.DURATION));// for duration
        int type = Integer.parseInt(cursor.getString(cursor.getColumnIndex(CallLog.Calls.TYPE)));// for call type, Incoming or out going
        cursor.moveToNext();
    }
}

//Inserting values in call log...
ContentValues values = new ContentValues();
values.put(CallLog.Calls.NUMBER, number);
values.put(CallLog.Calls.CACHED_NAME, name);
values.put(CallLog.Calls.CACHED_NUMBER_LABEL, label);
values.put(CallLog.Calls.DATE, date);
values.put(CallLog.Calls.DURATION, duration);
values.put(CallLog.Calls.TYPE, myCallType);
getApplicationContext().getContentResolver().insert(CallLog.Calls.CONTENT_URI, values);

//Deleting entry in call log...
String queryString= "NUMBER='" + number + "'";
if (cursor.getCount() > 0){
        getApplicationContext().getContentResolver().delete(UriCalls, queryString, null);
}

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

Note: Please refer this doc over call log for more clearity.



Thursday 29 September 2011

Block Home Key

I searched a lot to block Home key but no success and finally I got it and here it is for you guys.

@Override
public void onAttachedToWindow() {

this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();

}

Note: You should never block the Home key. Please see this post before doing so.

Monday 12 September 2011

Auto App start on Boot Completion

You can start your application when the device starts again thru BroadcastReceiver:

public class PhoneStateReceiver extends BroadcastReceiver{
   
    @Override
    public void onReceive(final Context context, Intent intent) {
       
        if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
            Intent launch = new Intent(context, ActivityToLaunch.class);
            launch.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(launch);
        }
    }
}


In your manifest add this:

<receiver android:name=".receiver.PhoneStateReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>   

Add permission:

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

Monday 5 September 2011

Rating your code from A to F

Assuming that a piece of code is functional and that it complies with its requirements, that piece of code can be rated from A to F based in two parameters, the simplicity and the extensibility.



Simplicity


The simplicity is a characteristic that tells us how easy is to understand and read the code. In order to determine how simple a code is, the following can be taken into consideration.
  • Good identifiers for Class names, variables, methods…
  • Straight forward logic.
  • Crisp and minimal abstractions.
  • Low representational gap. The representational gap is how different is the domain logic of an application from its design, having a low representational gap means that the design has very few differences with the domain logic it represents.
The simplicity is classified in “Very simple”, “Simple” or “Not simple”
Very simple: Code that doesn’t require additional documentation to be understood, any developer can pick up the code and do changes without further explanation.
Simple: Code that requires some additional documentation to be understood, only developers with some background on the design and in the business domain knowledge will be able to do changes.
Not simple: Code that requires lots of additional documentation to be understood, only senior developers with a deep knowledge of the application will be able to do changes.

 

Extensibility


The extensibility is a characteristic that tells us how easy will be to add new functionality on top of the current code, don’t confuse extensibility with over engineering, which is a bad practice. In order to determine how extensible a code is, the following can be taken into consideration.
  • Atomicity, use of DRY.
  • Testability. Code that includes unit tests.
  • Use of design patterns.
  • Low coupling
The extensibility is classified in “Very extensible”, “Extensible” or “Not extensible”
Very extensible: To add new functionality on the top of the code is really easy, no refactoring would be necessary.
Extensible: To add new functionality on the top of the existing code is relatively easy, minor refactoring would be necessary.
Not extensible: To add new functionality on the top of the existing code is difficult, complex refactoring, even redesign would be necessary.

Code Rates

 

A- Excellent code.

A is the best rate for code, it can’t be more simple and it can’t be more extensible, the problem with A codes is that is almost impossible to achieve, usually there is a trade off between extensibility and readability, that’s why I always recommend to produce B codes.

 

B- Good code

B code is good code, B code will ensure that the maintenance of the application will be much easier. This code is the one I recommend to aim for.

 

C- Average code

C code is what some developers consider good enough, if we are under a tight deadline or high pressure we might have to aim for this rate of code. Maintenance of the application is harder than with B code but still is possible.

 

D- Dangerous code

With D code still is possible to maintain the application, but it takes a lot of time to perform any change and the risk to enter new bugs doing so is high, some teams don’t want to refactor D codes because they don’t want to change something that is working, that’s an error, D codes easily become E codes after a few changes and then it will become unmaintainable.

 

E- Bad code

E code is bad code, the application is unmaintainable, urgent changes are necessary, still there is time for reaction to change the code and improve it.

 

F- Start over again

Not only the application is unmaintainable, the code should be scrapped and created again from scratch

Thursday 1 September 2011

Android Intents

//show webapp:

Uri uri = Uri.parse("http://www.google.com");
Intent intent  = new Intent(Intent.ACTION_VIEW,uri);
startActivity(intent);

//show maps:
Uri uri = Uri.parse("geo:38.899533,-77.036476");
Intent intent = new Intent(Intent.Action_VIEW,uri);
startActivity(intent);

//show ways
Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en");
Intent intent = new Intent(Intent.ACTION_VIEW,URI);
startActivity(intent);

//call dial program
Uri uri = Uri.parse("tel:xxxxxx");
Intent intent = new Intent(Intent.ACTION_DIAL, uri); 
startActivity(intent); 

Uri uri = Uri.parse("tel.xxxxxx");
Intent intent =new Intent(Intent.ACTION_CALL,uri);
startActivity(intent);
//don't forget add this config:<uses-permission id="android.permission.CALL_PHONE" />

//send sms/mms
//call sender program
Intent intent = new Intent(Intent.ACTION_VIEW);  
intent.putExtra("sms_body", "The SMS text");  
intent.setType("vnd.android-dir/mms-sms");  
startActivity(intent); 

//send sms
Uri uri = Uri.parse("smsto:0800000123");  
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);  
intent.putExtra("sms_body", "The SMS text");  
startActivity(intent); 

//send mms
Uri uri = Uri.parse("content://media/external/images/media/23");  
Intent intent = new Intent(Intent.ACTION_SEND);  
intent.putExtra("sms_body", "some text");  
intent.putExtra(Intent.EXTRA_STREAM, uri);  
intent.setType("image/png");  
startActivity(intent);

//send email

Uri uri = Uri.parse("mailto:xxx@abc.com");
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
startActivity(intent);

Intent intent = new Intent(Intent.ACTION_SEND);  
intent.putExtra(Intent.EXTRA_EMAIL, "me@abc.com");  
intent.putExtra(Intent.EXTRA_TEXT, "The email body text");  
intent.setType("text/plain");  
startActivity(Intent.createChooser(intent, "Choose Email Client")); 

Intent intent=new Intent(Intent.ACTION_SEND);    
String[] tos={"me@abc.com"};    
String[] ccs={"you@abc.com"};    
intent.putExtra(Intent.EXTRA_EMAIL, tos);    
intent.putExtra(Intent.EXTRA_CC, ccs);    
intent.putExtra(Intent.EXTRA_TEXT, "The email body text");    
intent.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");    
intent.setType("message/rfc822");    
startActivity(Intent.createChooser(intent, "Choose Email Client"));  


//add extra
Intent intent = new Intent(Intent.ACTION_SEND);  
intent.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");  
intent.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/mysong.mp3");  
sendIntent.setType("audio/mp3");  
startActivity(Intent.createChooser(intent, "Choose Email Client"));

//play media
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse("file:///sdcard/song.mp3");
intent.setDataAndType(uri, "audio/mp3");
startActivity(intent);

Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1");  
Intent intent = new Intent(Intent.ACTION_VIEW, uri);  
startActivity(intent); 

//Uninstall
Uri uri = Uri.fromParts("package", strPackageName, null);  
Intent intent = new Intent(Intent.ACTION_DELETE, uri);  
startActivity(intent);

//uninstall apk
Uri uninstallUri = Uri.fromParts("package", "xxx", null);
Intent intent = new Intent(Intent.ACTION_DELETE, uninstallUri);
startActivity(intent);

//install apk
Uri installUri = Uri.fromParts("package", "xxx", null);
Intent intent = new Intent(Intent.ACTION_PACKAGE_ADDED, installUri);
startActivity(intent);

//play audio
Uri playUri = Uri.parse("file:///sdcard/download/everything.mp3");
Intent intent = new Intent(Intent.ACTION_VIEW, playUri);
startActivity(intent);

//send extra
Intent intent = new Intent(Intent.ACTION_SEND); 
intent.putExtra(Intent.EXTRA_SUBJECT, "The email subject text"); 
intent.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/eoe.mp3"); 
sendIntent.setType("audio/mp3"); 
startActivity(Intent.createChooser(intent, "Choose Email Client"));

//search
Uri uri = Uri.parse("market://search?q=pname:pkg_name"); 
Intent intent = new Intent(Intent.ACTION_VIEW, uri); 
startActivity(intent); 
//where pkg_name is the full package path for an application 

//show program detail page
Uri uri = Uri.parse("market://details?id=app_id"); 
Intent intent = new Intent(Intent.ACTION_VIEW, uri); 
startActivity(intent); 
//where app_id is the application ID, find the ID 
//by clicking on your application on Market home 
//page, and notice the ID from the address bar


//search google
Intent intent = new Intent();
intent.setAction(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY,"searchString")
startActivity(intent);

Tuesday 30 August 2011

SQLite

1. SQLite in Android

SQLite is an Open Source Database which is embedded into Android. SQLight supports standard relational database features like SQL syntax, transactions and prepared statements. In addition it requires only little memory at runtime (approx. 250 KByte).

Using SQLite in Android does not require any database setup or administration. You specify the SQL for working with the database and the database is automatically managed for you.

Working with databases in Android can be slow due to the necessary I/O. Therefore is it recommended to perform this task in an AsyncTask . Please see Android Background Processing Tutorial for details.

SQLite supports the data types TEXT (similar to String in Java), INTEGER (similar to long in Java) and REAL (similar to double in Java). All other types must be converted into on of these fields before saving them in the database. SQLight itself does not validate if the types written to the columns are actually of the defined type, you can write an integer into a string column.

If your application creates an database this database is saved in the directory "DATA/data/APP_NAME/databases/FILENAME". "DATA" is the path which Environment.getDataDirectory() returns, "APP_NAME" is your application name and "FILENAME" is the name you give the database during creation. Environment.getDataDirectory() usually return the SD card as location.

A SQlite database is private to the application which creates it. If you want to share data with other applications you can use a Content Provider.

2. SQLiteOpenHelper

To create and upgrade a database in your Android application you usually subclass "SQLiteOpenHelper". In this class you need to override the methods onCreate() to create the database and onUpgrade() to upgrade the database in case of changes in the database schema. Both methods receive an "SQLiteDatabase" object.

SQLiteOpenHelper provides the methods getReadableDatabase() and getWriteableDatabase() to get access to an "SQLiteDatabase" object which allows database access either in read or write mode.

For the primary key of the database you should always use the identifier "_id" as some of Android functions rely on this standard.

3. SQLiteDatabase and Cursor

"SQLiteDatabase" provides the methods insert(), update() and delete() and execSQL() method which allows to execute directly SQL. The object "ContentValues" allow to define key/values for insert and update. The key is the column and the value is the value for this column.

Queries can be created via the method rawQuery() which accepts SQL or query() which provides an interface for specifying dynamic data or SQLiteQueryBuilder. SQLiteBuilder is similar to the interface of an content provider therefore it is typically used in ContentProviders. A query returns always a "Cursor".

The method query has the parameters String dbName, int[] columnNames, String whereClause, String[] valuesForWhereClause, String[] groupBy, String[] having, String[] orderBy. If all data should be selected you can pass "null" as the where clause. The where clause is specified without "where", for example "_id=19 and summary=?". If several values are required via ? you pass them in the valuesForWhereClause array to the query. In general if something is not required you can pass "null", e.g. for the group by clause.

A Cursor represents the result of a query. To get the number of elements use the method getCount(). To move between individual data rows, you can use the methods moveToFirst() and moveToNext(). Via the method isAfterLast() you can check if there is still some data.

Wednesday 17 August 2011

Launching other app from my app

Launch other application of the device from your application:

Intent intent = getPackageManager().getLaunchIntentForPackage(packageName);
      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
      intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
      if (null != intent) {
      try {
             startActivity(intent);
      } catch(Exception e) {  }
    }

Note: You need to know the package name to use the above code. For package name:


Getting Package Name of Installed app

Note: A lot of people need to fetch the package name, application name of the installed application on the device.Here is the code:

ArrayList<PackageInfo> res = new ArrayList<PackageInfo>();
PackageManager pm = ctx.getPackageManager();
List<PackageInfo> packs = pm.getInstalledPackages(0);

for(int i=0;i<packs.size();i++) {
    PackageInfo p = packs.get(i);
    String description = (String) p.applicationInfo.loadDescription(pm);
    String  label= p.applicationInfo.loadLabel(pm).toString();
    String packageName = p.packageName;
    String versionName = p.versionName;
    String versionCode = p.versionCode;
    String icon = p.applicationInfo.loadIcon(pm);
//Continue to extract other info about the app...
}

Note: Add this permission to the manifest file:

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


Calling Programmatically

You can initiate call programmatically. Let's do it:

Intent call = new Intent(Intent.ACTION_CALL);
call.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
call.setData(Uri.parse("tel:" + number));
startActivity(call);

Note: Add the permission to the manifest file:
<uses-permission android:name="android.permission.CALL_PHONE" />

Monday 8 August 2011

Passing values from one Activity to another


Intent intent = new Intent(context, CalledActivity.class);
        intent.putExtra(key, value);
        startActivity(intent);
       
If you want some data back from called Activity then you can use startActivityForResult() as:

Intent intent = new Intent(context, CalledActivity.class);
        intent.putExtra(key, value);
        startActivityForResult(intent, requestCode);
       
In called activity you can set data as:

setResult(RESULT_OK, intent);

Note: Here you set the value in intent and pass it to setResult().       
       

On returning back to calling Activity you can get data by overriding:

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == RESULT_OK){
            //Get data from Intent "data" and do your task here....
        }
    }
   
   
Note: You can pass primitive data type values thru Intent and if you want to pass other types then you have to use Bundle like this.

Bundle data = new Bundle();
        data.putIntArray(key, value);
        //same way you can set other values.......
//Now set this Bundle value to Intent as you do for primitive type....
Intent intent = new Intent(context, CalledActivity.class);
        intent.putExtra(data);
        startActivity(intent);

Receiving data in Activity:

//For primitive values:
DataType var_name = getIntent().getExtras().get(key);

//For Bundle values:
Bundle var_name = getIntent().getExtras().getBundle(key);


Contacts

Note: Here are some useful links:

Getting Contacts:







Using Contact Picker:


Inserting Contact:




Deleting Contacts:


Friday 5 August 2011

Adding Event to Calendar

Let's add events to calendar:

ContentResolver cr = getContentResolver();
       
//Find out which calendars exist...
Cursor cursor_calendar; // = cr.query(Uri.parse("content://com.android.calendar/calendars"), new String[]{ "_id",  "displayname" }, null, null, null);
if (Integer.parseInt(Build.VERSION.SDK) >= 8 ){
    cursor_calendar = cr.query(Uri.parse("content://com.android.calendar/calendars"), new String[]{ "_id", "displayname" }, null, null, null);
}
else{
    cursor_calendar = cr.query(Uri.parse("content://calendar/calendars"), new String[]{ "_id", "displayname" }, null, null, null);
}

cursor_calendar.moveToFirst();
String[] CalNamess = new String[cursor_calendar.getCount()];
int[] CalIdss = new int[cursor_calendar.getCount()];
for (int i = 0; i < CalNamess.length; i++) {
    CalIdss[i] = cursor_calendar.getInt(0);
    CalNamess[i] = cursor_calendar.getString(1);
    cursor_calendar.moveToNext();
}
cursor_calendar.close();

//Call this function to add event...
private void addEventToCalendar(int calender_id, String title, long start_date, long end_date){
   
    ContentValues cv = new ContentValues();
    cv.put("calendar_id", calender_id);
    cv.put("title", title);
    cv.put("dtstart", start_date );
    cv.put("hasAlarm", 1);
    cv.put("dtend", end_date);

    Uri newEvent ;
    if (Integer.parseInt(Build.VERSION.SDK) >= 8 ){
        newEvent = cr.insert(Uri.parse("content://com.android.calendar/events"), cv);
    }   
    else{
        newEvent = cr.insert(Uri.parse("content://calendar/events"), cv);
    }   

    if (newEvent != null)
    {
        long id = Long.parseLong( newEvent.getLastPathSegment() );
        ContentValues values = new ContentValues();
        values.put( "event_id", id );
        values.put( "method", 1 );
        values.put( "minutes", 0 ); // 15 minut Before
        if (Integer.parseInt(Build.VERSION.SDK) >= 8 )
            cr.insert( Uri.parse( "content://com.android.calendar/reminders" ), values );
        else
            cr.insert( Uri.parse( "content://calendar/reminders" ), values );
    }
}

Note: I tested this code at API level 10 and it worked fine.

Retrieving Events from Calendar

ContentResolver cr = getContentResolver();
       
//Find out which calendars exist...

Cursor cursor_calendar;
if (Integer.parseInt(Build.VERSION.SDK) >= 8 ){
    cursor_calendar = cr.query(Uri.parse("content://com.android.calendar/calendars"), new String[]{ "_id", "displayname" }, null, null, null);
}   
else{
    cursor_calendar = cr.query(Uri.parse("content://calendar/calendars"), new String[]{ "_id", "displayname" }, null, null, null);
}   

cursor_calendar.moveToFirst();
String[] CalNamess = new String[cursor_calendar.getCount()];
int[] CalIdss = new int[cursor_calendar.getCount()];
for (int i = 0; i < CalNamess.length; i++) {
    CalIdss[i] = cursor_calendar.getInt(0);
    CalNamess[i] = cursor_calendar.getString(1);
    cursor_calendar.moveToNext();
}
cursor_calendar.close();

//Find out stored events in Calendar...

Cursor cursor_event;
if (Integer.parseInt(Build.VERSION.SDK) >= 8 ){
  cursor_event = cr.query(Uri.parse("content://com.android.calendar/events"), new String[]{ "calendar_id", "title", "description", "dtstart", "dtend", "eventLocation" }, null, null, null);
else{
    cursor_event = cr.query(Uri.parse("content://calendar/events"), new String[]{ "calendar_id", "title", "description", "dtstart", "dtend", "eventLocation" }, null, null, null);
}
   
String add = null;
cursor_event.moveToFirst();
String[] CalNames = new String[cursor_event.getCount()];
int[] CalIds = new int[cursor_event.getCount()];
for (int i = 0; i < CalNames.length; i++) {
  CalIds[i] = cursor_event.getInt(0);
  CalNames[i] = "Event"+cursor_event.getInt(0)+": \nTitle: "+ cursor_event.getString(1)+"\nDescription: "+cursor_event.getString(2)+"\nStart Date: "+new Date(cursor_event.getLong(3))+"\nEnd Date : "+new Date(cursor_event.getLong(4))+"\nLocation : "+cursor_event.getString(5);
  if(add == null)
      add = CalNames[i];
  else{
      add += CalNames[i];
  }          
  cursor_event.moveToNext();
}
cursor_event.close();

Note: I tested this code on API level 10 and it is working fine.


Thursday 4 August 2011

Rounded Corner Button

Note: Here is rounded_corner_button.xml. Save it in your drawable folder and use it in place of image.

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
<corners android:radius="8dp" />
<gradient
    android:angle="45"
    android:startColor="#FFFF0000"
    android:endColor="#80FF00FF" />
<padding
    android:left="2dp"
    android:top="2dp"
    android:right="2dp"
    android:bottom="2dp" />
<solid
    android:color="#0f7fb6" />
</shape>


Enable - Disable Silent Mode

public void changeRingerMode(Context context){
   
AudioManager audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
   
    /**
    * To Enable silent mode.....
    */
    audio.setRingerMode(AudioManager.RINGER_MODE_SILENT);
   
    /**
    * To Enable Ringer mode.....
    */
    audio.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
   
}


NotificationManager & Status Bar Icon

How to set the icon of the app in Device's Status Bar and do notification process? Here it is how to do it:

public static void notifyIcon(Context context){

NotificationManager notifier = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.your_app_notification, "", System.currentTimeMillis());

/**
*Setting these flags will stop clearing your icon
*from the status bar if the user does clear all 
*notifications.
*/
    notification.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT;
    RemoteViews contentView = new RemoteViews(context.getPackageName(), R.layout.custom_notification_layout);
    notification.contentView = contentView;
   
//If you want to open any activity on the click of the icon.

    Intent notificationIntent = new Intent(context, YourActivity.class);
    PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
    notification.contentIntent = contentIntent;
   
    notification.setLatestEventInfo(context, "title", null, contentIntent);
    notifier.notify(1, notification);

//To cancel the icon ...
    notifier.cancel(1);

}

Here is custom_notification_layout.xml

<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="3dp" >

</LinearLayout>

Note: Don't forget to clear your app icon when appropriate If you set above flag.



Wednesday 3 August 2011

Custom List Adapter

Note: You want to customize your List Adapter as per your requirement then here is some useful code for you but  modify it as you require ....... It is just a trailor, rest is in your hands.

import java.util.Vector;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class YourAdapterName extends BaseAdapter{

private Context mContext;
private Vector mValuestoShow;

/**
 * Constructor to be called to initialize adapter with values.
 * @param context
 * @param vector
 */
public YourAdapterName(Context context, Vector vector){
    mContext = context;
    mValuestoShow = vector;
}

public int getCount() {
    if(null != mValuestoShow){
        return mValuestoShow.size();
    }
    return 0;
}

public Object getItem(int position) {
    if(position < mValuestoShow.size())
        return  mValuestoShow.get(position);
    else
        return null;
}

public long getItemId(int position) {
    return 0;
}

/**
 * This method can be override to enable/disable particular list row.
 */
@Override
public boolean isEnabled(int position) {
    //Write your code here......
    return super.isEnabled(position);
}

public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder ;
    if(convertView == null){
        LayoutInflater li =(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = li.inflate(R.layout.your_layout, null);
        holder = new ViewHolder();
        holder.txt_name = (TextView) convertView.findViewById(R.id.name_txt);
        convertView.setTag(holder);
    }else{
        holder = (ViewHolder) convertView.getTag();
    }
  
    /**
 * Use of enable method how to set different color for disabled row....
 * You can also customize your row background color or text color without using enable method
 * in the same way as below is done as per your conditions.
 */
    if(!isEnabled(position)){
        holder.txt_name.setBackgroundColor(mContext.getResources().getColor(R.color.color_code));
        holder.txt_name.setTextColor(mContext.getResources().getColor(R.color.white));
    }else{
        holder.txt_name.setBackgroundColor(mContext.getResources().getColor(R.color.color_code));
        holder.txt_name.setTextColor(mContext.getResources().getColor(R.color.black));
    }
  
    holder.txt_name.setText(getItem(position).toString());
  
    return convertView;
}

class ViewHolder {
    TextView txt_name;
}

}

your_layout.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 = "wrap_content"
    android:padding = "10dp" >
   
<TextView
    android:id = "@+id/txt_type1"
    android:layout_width = "wrap_content"
    android:layout_height = "wrap_content" />
   
<TextView
    android:id = "@+id/txt_type2"
    android:layout_width = "wrap_content"
    android:layout_height = "wrap_content" />
   
<ImageView
    android:id = "@+id/image"
    android:src = "@drawable/image"
    android:layout_width = "wrap_content"
    android:layout_height = "wrap_content" />
           
</RelativeLayout>

Note:You can add more views like Button , ImageButton, EditText as per your need.