Show Download Progress in NotificationBar in Android with Notification Event Listeners

Below Sample code shows you how to download images from a url with progress in the notification bar.

Notification Access Download

package com.coderzheaven.customnotificationdownloaddemo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;

public class MainActivity extends ActionBarActivity {

	NotificationCompat.Builder mBuilder;
	NotificationManager mNotifyManager;
	int id = 1;
	String urlsToDownload[] = { "http://www.devoxx.be/wp-content/uploads/2014/10/android.png", "http://www.devoxx.be/wp-content/uploads/2014/10/android.png",
			"http://www.devoxx.be/wp-content/uploads/2014/10/android.png", "http://www.devoxx.be/wp-content/uploads/2014/10/android.png",
			"http://www.devoxx.be/wp-content/uploads/2014/10/android.png" };
	int counter = 0;
	private NotificationReceiver nReceiver;
	ArrayList<AsyncTask<String, String, Void>> arr;

	class NotificationReceiver extends BroadcastReceiver {
		@Override
		public void onReceive(Context context, Intent intent) {
			String event = intent.getExtras().getString(NLService.NOT_EVENT_KEY);
			Log.i("NotificationReceiver", "NotificationReceiver onReceive : " + event);
			if (event.trim().contentEquals(NLService.NOT_REMOVED)) {
				killTasks();
			}
		}
	}

	private void killTasks() {
		if (null != arr & arr.size() > 0) {
			for (AsyncTask<String, String, Void> a : arr) {
				if (a != null) {
					Log.i("NotificationReceiver", "Killing download thread");
					a.cancel(true);
				}
			}
			mNotifyManager.cancelAll();
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
		mBuilder = new NotificationCompat.Builder(this);
		mBuilder.setContentTitle("Downloading images...").setContentText("Download in progress").setSmallIcon(R.drawable.ic_launcher);
		// Start a lengthy operation in a background thread
		mBuilder.setProgress(0, 0, true);
		mNotifyManager.notify(id, mBuilder.build());
		mBuilder.setAutoCancel(true);

		arr = new ArrayList<AsyncTask<String, String, Void>>();
		int incr;
		for (incr = 0; incr < urlsToDownload.length; incr++) {
			ImageDownloader imageDownloader = new ImageDownloader();
			imageDownloader.execute(urlsToDownload[incr]);
			arr.add(imageDownloader);
		}

		ContentResolver contentResolver = getContentResolver();
		String enabledNotificationListeners = Settings.Secure.getString(contentResolver, "enabled_notification_listeners");
		String packageName = getPackageName();

		// check to see if the enabledNotificationListeners String contains our
		// package name
		if (enabledNotificationListeners == null || !enabledNotificationListeners.contains(packageName)) {
			// in this situation we know that the user has not granted the app
			// the Notification access permission
			// Check if notification is enabled for this application
			Log.i("ACC", "Dont Have Notification access");
			Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
			startActivity(intent);
		} else {
			Log.i("ACC", "Have Notification access");
		}

		nReceiver = new NotificationReceiver();
		IntentFilter filter = new IntentFilter();
		filter.addAction(NLService.NOT_TAG);
		registerReceiver(nReceiver, filter);

	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		killTasks();
		unregisterReceiver(nReceiver);
	}

	private void downloadImagesToSdCard(String downloadUrl, String imageName) {
		FileOutputStream fos;
		InputStream inputStream = null;

		try {
			URL url = new URL(downloadUrl);
			/* making a directory in sdcard */
			String sdCard = Environment.getExternalStorageDirectory().toString();
			File myDir = new File(sdCard, "DemoDownload");

			/* if specified not exist create new */
			if (!myDir.exists()) {
				myDir.mkdir();
				Log.v("", "inside mkdir");
			}

			/* checks the file and if it already exist delete */
			String fname = imageName;
			File file = new File(myDir, fname);
			Log.d("file===========path", "" + file);
			if (file.exists())
				file.delete();

			/* Open a connection */
			URLConnection ucon = url.openConnection();

			HttpURLConnection httpConn = (HttpURLConnection) ucon;
			httpConn.setRequestMethod("GET");
			httpConn.connect();
			inputStream = httpConn.getInputStream();

			/*
			 * if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
			 * inputStream = httpConn.getInputStream(); }
			 */

			fos = new FileOutputStream(file);
			// int totalSize = httpConn.getContentLength();
			// int downloadedSize = 0;
			byte[] buffer = new byte[1024];
			int bufferLength = 0;
			while ((bufferLength = inputStream.read(buffer)) > 0) {
				fos.write(buffer, 0, bufferLength);
				// downloadedSize += bufferLength;
				// Log.i("Progress:", "downloadedSize:" + downloadedSize +
				// "totalSize:" + totalSize);
			}
			inputStream.close();
			fos.close();
			Log.d("test", "Image Saved in sdcard..");
		} catch (IOException io) {
			inputStream = null;
			fos = null;
			io.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {

		}

	}

	private class ImageDownloader extends AsyncTask<String, String, Void> {

		@Override
		protected Void doInBackground(String... param) {
			downloadImagesToSdCard(param[0], "Image" + counter + ".png");
			return null;
		}

		protected void onProgressUpdate(String... values) {
		}

		@Override
		protected void onPreExecute() {
			Log.i("Async-Example", "onPreExecute Called");
		}

		@Override
		protected void onPostExecute(Void result) {
			Log.i("Async-Example", "onPostExecute Called");

			float len = urlsToDownload.length;
			// When the loop is finished, updates the notification
			if (counter >= len - 1) {
				mBuilder.setContentTitle("Done.");
				mBuilder.setContentText("Download complete")
				// Removes the progress bar
						.setProgress(0, 0, false);
				mNotifyManager.notify(id, mBuilder.build());
			} else {
				int per = (int) (((counter + 1) / len) * 100f);
				Log.i("Counter", "Counter : " + counter + ", per : " + per);
				mBuilder.setContentText("Downloaded (" + per + "/100");
				mBuilder.setProgress(100, per, false);
				// Displays the progress bar for the first time.
				mNotifyManager.notify(id, mBuilder.build());
			}
			counter++;

		}

	}
}

“NLService” Class is the actual Notification Listener class that can hear events in your notification.
But before everything you need to be sure that, you have enabled notification access for your app.

package com.coderzheaven.customnotificationdownloaddemo;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;

@SuppressLint("NewApi")
public class NLService extends NotificationListenerService {
	private String TAG = this.getClass().getSimpleName();
	public static final String NOT_TAG = "com.coderzheaven.NOTIFICATION_LISTENER";
	public static final String NOT_POSTED = "POSTED";
	public static final String NOT_REMOVED = "REMOVED";
	public static final String NOT_EVENT_KEY = "not_key";

	@Override
	public void onCreate() {
		super.onCreate();
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
	}

	@Override
	public void onNotificationPosted(StatusBarNotification sbn) {
		Log.i(TAG, "**********  onNotificationPosted");
		Intent i = new Intent(NOT_TAG);
		i.putExtra(NOT_EVENT_KEY, NOT_POSTED);
		sendBroadcast(i);
	}

	@Override
	public void onNotificationRemoved(StatusBarNotification sbn) {
		Log.i(TAG, "********** onNOtificationRemoved");
		Intent i = new Intent(NOT_TAG);
		i.putExtra(NOT_EVENT_KEY, NOT_REMOVED);
		sendBroadcast(i);
	}

}

Make sure you add the “services” in the AndroidManifest file.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.coderzheaven.customnotificationdownloaddemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="22" />

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service
            android:name="com.coderzheaven.customnotificationdownloaddemo.NLService"
            android:label="@string/app_name"
            android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
            <intent-filter>
                <action android:name="android.service.notification.NotificationListenerService" />
            </intent-filter>
        </service>
    </application>

</manifest>

You can download the complete source code from here..

NSNotificationCenter Example in Swift

Here is a simple demo on how to use “NSNotificationCenter” in swift.

NSNotificationCenter is particularly useful when there are multiple class or struct instances that need to take action based on something that happens elsewhere in your application.

To Register the notification… we will call

 NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateOnNotification", name: notificationKey, object: nil)

Now to trigger the notification…

 @IBAction func broadcastNotification(sender: UIButton){
    NSNotificationCenter.defaultCenter().postNotificationName(notificationKey, object: self)
}

//This will be triggered once the notification is sent.
func updateOnNotification() {
    println("Notification Sent");
}

The “notificationKey” should be unique for each notification to identify different broadcasts.

for eg : let notificationKey = “notification_key”

IMPORTANT NOTE : A notification observer will be removed once you close a ViewController in which it is added. i.e an observer will be removed once dealloc is called from a ViewController. In Swift it is by default.

Please leave your valuable comments below.

Sync Adapter in Android – A Simple Example…

Hello all,

In Today’s article we will be discussing about the SyncAdapters in Android.
SyncAdapter is just a simple plugin like structure for syncing your server and Device.

Check out this post about Account authenticator before proceeding.

Android Sync Adapter

Why do we use SyncAdapter instead of Using Alarm Manger to Sync?

Automated execution
    Sync can be requested based on variety of criteria, including data changes, elapsed time, or time of day.
Automated network checking
     The system only runs your data transfer when the device has network connectivity.
Improved battery performance
     Allows you to centralize all of your app’s data transfer tasks in one place, so that they all run at the same time. Your data transfer is also scheduled in conjunction with data transfers from other apps. These factors reduce the number of times the system has to switch on the network, which reduces battery usage.
Account management and authentication
     If your app requires user credentials or server login, you can optionally integrate account management and authentication into your data transfer.
Automatic Retry
     Failed syncs are retried with exponential backoffs.

What makes the Sync Adapter?

There are three components that makes up the SyncAdapter..

1.A Content-provider that extends ContentProvider.
2. An Adapter that extends AbstractThreadedSyncAdapter.
3. A Service that extends Service – this links the content provider with the sync adapter

The Content- provider and the Service need to be declared in AndroidManifest.xml.

For example the declaration will look like this…


   <provider
            android:name="MyContentProvider"
            android:authorities="@string/content_authority"
            android:exported="false"
            android:label="MyContentProvider"
            android:syncable="true" />
            
   <service
            android:name="AuthenticatorService"
            android:exported="true"
            android:process=":auth" >
            <intent-filter>
                <action android:name="android.accounts.AccountAuthenticator" />
            </intent-filter>

            <meta-data
                android:name="android.accounts.AccountAuthenticator"
                android:resource="@xml/authenticator" />
    </service>
    
	<service
		android:name="SyncService"
		android:exported="true"
		android:process=":sync" >
		<intent-filter>
			<action android:name="android.content.SyncAdapter" />
		</intent-filter>

		<meta-data
			android:name="android.content.SyncAdapter"
			android:resource="@xml/sync_adapter" />
	</service>

Now create a folder inside the “res” folder named “xml” and create two xmls, one for the autheticator and other for the Adapter.

authenticator.xml

<account-authenticator 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:accountType="@string/auth_type"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:smallIcon="@drawable/ic_launcher" />

sync_adapter.xml

<?xml version="1.0" encoding="utf-8"?>
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
              android:contentAuthority="@string/content_authority"
              android:accountType="@string/auth_type"
              android:userVisible="true"
              android:allowParallelSyncs="true"
              android:isAlwaysSyncable="true"
              android:supportsUploading="false"/>

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Android Account Authenticator</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string name="auth_type">com.coderzheaven.auth_example</string>
    <string name="content_authority">com.coderzheaven.mycont_provider</string>
</resources>

NOTE : The “android:authorities” in the Provider Declaration and “android:contentAuthority” in the Sync Adapter should match.
That is why I put it in the strings.xml and gave a common name.

Authority is the string which establishes the relationship among the service, content provider and sync adapter.
In the above example “com.coderzheaven.mycont_provider”.

To Start Sync.

ContentResolver.requestSync(account, authority, bundle);  

The account should be valid.

For periodic Syncing.

ContentResolver.addPeriodicSync (account, authority, extras,frequency)

When you request Sync, the System may not start the Syncing immediately, because it will wait for the best battery performance.

Sync Immediately.

If we want to Sync immediately…

 Bundle bundle = new Bundle();  
 //Set below two flags
 bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);  
 bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);  
 ContentResolver.requestSync(account, authority, bundle);  

NOTE : Periodic syncs are not allowed to have any of SYNC_EXTRAS_DO_NOT_RETRY, SYNC_EXTRAS_IGNORE_BACKOFF,
SYNC_EXTRAS_IGNORE_SETTINGS, SYNC_EXTRAS_INITIALIZE, SYNC_EXTRAS_FORCE,SYNC_EXTRAS_EXPEDITED, SYNC_EXTRAS_MANUAL set to true.
If any are supplied then an IllegalArgumentException will be thrown.

if we request an immediate sync when another sync is already in progress, then sync would be retried after 10 seconds.

NOTE : In Some devices Periodic Sync will not work unless “Auto-Sync” is turned on.

Full Source code that implements Android Authenticator and Sync Adapter is available here.

Please leave your valuable comments below.

What are Generics and Why should we use Generics?

The Java Generics programming is introduced in J2SE 5 to deal with type-safe objects.

Advantage of Java Generics

There are mainly 3 advantages of generics. They are as follows:

1) Type-safety : We can hold only a single type of objects in generics. It doesn’t allow to store other objects.

2) Type casting is not required: There is no need to typecast the object.

Before Generics, we need to type cast.

    List list = new ArrayList();  
    list.add("CoderzHeaven");  
    String s = (String) list.get(0);   //typecasting  

After Generics, we don’t need to typecast the object.

    List<String> list = new ArrayList<String>();  
    list.add("hello");  
    String s = list.get(0);  

3) Compile-Time Checking: It is checked at compile time so problem will not occur at runtime. The good programming strategy says it is far better to handle the problem at compile time than runtime.

    List<String> list = new ArrayList<String>();  
    list.add("CoderzHeaven");  
    list.add(23);   //Compile Time Error  

Please leave your valuable comments below.

A Simple Chat Application in Android Using GCM and Server Side – PHP.

Hi all,

In Today’s Tutorial I will help you to make a simple chat application in Android using Google Cloud Messaging. I am using PHP as server side script.

Here are the things you need to follow to make this application.

1. You need to register to Google for GCM.
2. You need a server where your script resides.[We will use our own system as Server in this application].

Please read this before starting with the application
After reading the above link, you will get a API key and Sender ID , which distinguishes your application.
So you will need it in the code, keep it somewhere safe.

You need to change the API Key inside Android source code in the sample Provided below.
Your API Key and SENDER ID will look something similar to this.

 
 String SENDER_ID = "243750827028";
 String API_KEY   = "AIzaSyCBI_c2izVrEPcJ509uZGVLdfWUAW-rg48";
	

Next Go through this link, till step 2 in that page because I have provided the source code below.

The usual flow of a simple GCM application is like this

1. User launches your application for the first time.
2. Your application will call “register” to register with GCM.
3. Google will send you back a “Registration ID” which will be unique for that device.
But beware these “Registration ID’s” will change when you update the application or reinstall it after uninstalling. So don’t use it to uniquely identify a user. A username/password combination or a Phone Number usually does the trick.

4. The device gets the “Registration ID” and store it locally, so that the device don’t need to register again each time the user run the
application.
5. Send this registration ID to your server and Store it there along with a unique identifier for the user. [Here we will use ‘username’ for the time being].
6. When the user taps send message button you need to call a server side script that will communicate with GCM server which will
send this message to corresponding device.
ie. User taps the button -> send the device_reg_id and message to your server -> send these parameters from your server to GCM
-> GCM send the message to Device identified by reg id.

So I am not going to paste the whole code here.
You can directly download it from below links

Client Complete Android source code.

PHP server side source code.

Here I have used a simple database structure for simplicity.
I am using username for identifying each user.

You need to make the same structure for the below sample to work.

GCM Sample DB structure

GCM Sample DB structure

For Server Side I am using XAMPP for Mac.
You can download the Server side source code and put it inside htdocs folder inside XAMPP/Applications.

Start your servers.

Please check the Screenshot below.

GCM Sample DB structure

Then Go to your browser and type “localhost”. if your server is running, then you will see “phpMyAdmin” Page.

For testing it in your system and in your device, Both should be in the same network, for example : both should be in the same WIFI netwrok of your home.
Please type “ifconfig” for Mac in terminal and check inside “en0″ or “en1″ to get your sytem IP. For Windows type “ipconfig”.

Before running the application change the “IP” in the Utils file.

I am not going to the Android source code because Complete source is already provided.

How to test?

1. Change the API Key and Sender ID in the application.

2. Make sure server side is set up. copy php code to your local server as described above.
Make sure you have sql tables set up.

3. Make sure your servers are running.

4. Your testing devices and Your server should be on the same network, otherwise you have to host an online server. You can use the Emulator also as one device, but it should be an emulator with “Google Play Services”. Android 5.0 is good to go.

5. Change the IP address in “Utils.java” to your system IP address.

Please leave your comments if you have problems understanding the above article.

How to connect Localhost in your MAC or Windows to your Android Device OR Android Emulator ?

The name “localhost” is just a loopback to your own computer.

1. ACCESSING LOCALHOST ON ANDROID DEVICE.

To access it on your Android Device, you need to find the computer’s IP address.

  • The most general way of finding this info, which works on both Mac and Linux, is to go into the Terminal and type “ifconfig” AND for Windows type “ipconfig” in the command prompt.
  • Look for either “en0″ or “en1″, and under that entry look for the “inet” listing. It will be something along the lines of “192.168.1.100”.
  • When you find that address, that’s what you’ll want to put in your browser’s address bar or the URL in the code you want to call your MAC’s/Windows’ localhost.
  • On a Mac specifically,

    Go to System preferences/sharing OR just search on right top – remote management

    Make sure remote management is checked

Note : MAKE SURE THAT YOUR ANDROID DEVICE AND YOUR MAC/WINDOWS ARE ON THE SAME NETWORK OTHERWISE IT WILL NOT WORK. [EG : SAME WIFI NETWORK].

For Example in the Android code you can use like below and call a webservice that is residing in your local server, i.e your localhost.


 new HttpPost("http://192.168.0.101/your_localhost_folder/your_localhost_file.php");

2. ACCESSING LOCALHOST ON ANDROID EMULATOR.

You can have the same thing as described above for Android Emulator also as long as they are in same network.

But there are other options too…

You can check it in the post here.

IN App Purchase – Android – Simplified source code

Hi all,

I have already showed you how to implement in app purchase in Android.
Please go through this post before reading this article.

Android IN App Purchase

This is how the MainActivity source code will look like.

package com.coderzheaven.inappdemo;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

import com.coderzheaven.android.util.IabHelper;
import com.coderzheaven.inapp.InAppPurchase;
import com.coderzheaven.inapp.InAppStateListener;

public class MainActivity extends Activity implements OnClickListener,
		InAppStateListener {

	static final String TAG = "INAPPTESTING";

	// INAPP
	IabHelper mHelper;
	InAppPurchase inapp;
	static String SKU_INAPPITEM_ID = "android.test.purchased";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

	}

	@Override
	public void onClick(View v) {

		if (v.getId() == R.id.button_query) {

			showToast("Querying Items");
			inapp = new InAppPurchase(this, this, SKU_INAPPITEM_ID);
			mHelper = inapp.QueryInventry();

		} else {

			if (inapp != null)
				inapp.initiatePurchase();
			else
				showToast("Please click query items before purchasing");

		}

	}

	public void showToast(String msg) {
		Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
		;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + ","
				+ data);

		// Pass on the activity result to the helper for handling
		if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
			// not handled, so handle it ourselves (here's where you'd
			// perform any handling of activity results not related to in-app
			// billing...
			super.onActivityResult(requestCode, resultCode, data);
		} else {
			Log.d(TAG, "onActivityResult handled by IABUtil.");
		}
	}

	// IN APP PURCHASE LISTENERS

	@Override
	public void onInAppInitialiseError() {
		System.out.println("onInAppInitialiseError");
		showToast("In App initialise Error.");
	}

	@Override
	public void onInAppInitialiseSuccess() {
		System.out.println("onInAppInitialiseSuccess");
		showToast("In App initialise Success.");
	}

	@Override
	public void onQueryInventryCompleted() {
		System.out.println("onQueryInventryCompleted");
		//showToast("Querying Items Completed.");
	}

	@Override
	public void onQueryInventryError(String message) {
		System.out.println("onQueryInventryError : ");
		showToast("Querying Items Error.");
	}

	@Override
	public void onAlreadyPurchased(String inappItemID) {
		System.out.println("onAlreadyPurchased");
		showToast("Item already Purchased.");
	}

	@Override
	public void onItemNotPurchased(String inappItemID) {
		System.out.println("onItemNotPurchased : " + inappItemID);
		showToast("Item not purchased");
	}

	@Override
	public void onPurchaseSuccessfull(String inappItemID) {
		System.out.println("onPurchaseSuccessfull : " + inappItemID);
		showToast("Purchase Successful");
	}

	@Override
	public void onPurchaseError(String inappItemID, String message) {
		System.out.println("onPurchaseError : " + inappItemID);
		showToast("Purchase Error");
	}

}

You can download the complete source code from here itself.

What are static variables? Why it is used? What is it’s use? – A Common Interview Question.

The static keyword is used in java mainly for memory management. We may apply static keyword with variables, methods, blocks and nested class. The static keyword belongs to the class than instance of the class.

The static can be:

  • variable (also known as class variable)
  • method (also known as class method)
  • block
  • nested class
  • Static variable

  • If you declare any variable as static, it is known static variable.
  • The static variable can be used to refer the common property of all objects (that is not unique for each object)
  • The static variable gets memory only once in class area at the time of class loading.
  • For eg:

    public class Test {
    	public static String st_var = "I'm a static variable";
    }
    

    We can use this in another java class like below

    public class Application {
    	
    	public static void main(String[] args) {
    		System.out.println(Test.st_var); // call using Class name itself.
    	}
    
    }
    

    One common use of static is to create a constant value that’s attached to a class. The only change we need to make to the above example is to add the keyword final in there, to make ‘st_var’ a constant

    Another classic use of static is to keep count of how many objects are created from a given class. Since Memory is allocated only once for a static variable, If you create any number of objects ,then all objects will have only one common static variable. In this way we can count the number of objects created by incrementing the static variable inside that class

    If you make it Final, then it is unchangable after initial value.

    static method

  • If you apply static keyword with any method, it is known as static method
  • A static method belongs to the class rather than object of a class.
  • A static method can be invoked without the need for creating an instance of a class.
  • static method can access static data member and can change the value of it.
  • For Example

    Class Test{
     static void change(){  
         st_var = "CHANGED";  
     }  
     }
     and call Like this 
     
     Test.change(); // no need of object creation
     
    

    Restrictions for static method

    There are two main restrictions for the static method. They are:

  • The static method can not use non static data member or call non-static method directly.
  • this and super cannot be used in static context.
  • For Example

    class A{  
     int num=50;//non static  
       
     public static void main(String args[]){  
      System.out.println(num);  
     }  
    }  
    

    The output of above program will be a Compile Time Error.

    Simple way to Animating Layout Changes in Android.

    A layout animation is a pre-loaded animation that the system runs each time you make a change to the layout configuration. All you need to do is set an attribute in the layout to tell the Android system to animate these layout changes, and system-default animations are carried out for you.

      Create the Layout

    In your activity’s layout XML file, set the android:animateLayoutChanges attribute to true for the layout that you want to enable animations for. For instance:

    <LinearLayout android:id="@+id/container"
        android:animateLayoutChanges="true"
        ...
    />
    
      Add, Update, or Remove Items from the Layout

    Now, all you need to do is add, remove, or update items in the layout and the items are animated automatically:

    private ViewGroup mContainerView;
    ...
    private void addItem() {
        View newView;
        ...
        mContainerView.addView(newView, 0);
    }
    
    

    Here is the complete sample layout file.

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:id="@+id/container"
        android:orientation="vertical"
        android:layout_height="match_parent"
        tools:context=".MainActivity" 
        android:animateLayoutChanges="true">
    
        <Button
            android:id="@+id/buttonAdd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Add Views" />
    
         <Button
            android:id="@+id/buttonRemove"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Remove Views" />
         
    </LinearLayout>
    

    The MainActivity file.

    package com.coderzheaven.demo1;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.LinearLayout;
    
    public class MainActivity extends Activity {
    
    	LinearLayout mContainerView;
    	int id = 0;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    
    		mContainerView = (LinearLayout) findViewById(R.id.container);
    		Button click = (Button) findViewById(R.id.buttonAdd);
    		click.setOnClickListener(new OnClickListener() {
    
    			@Override
    			public void onClick(View arg0) {
    				addView();
    			}
    		});
    		Button remove = (Button) findViewById(R.id.buttonRemove);
    		remove.setOnClickListener(new OnClickListener() {
    
    			@Override
    			public void onClick(View arg0) {
    				removeView();
    			}
    		});
    	}
    
    	void addView() {
    		Button b = new Button(this);
    		b.setId(id++);
    		b.setText("Button " + id);
    		mContainerView.addView(b, 0);
    	}
    
    	void removeView() {
    
    		View v = (View) findViewById(id - 1);
    		if (v != null) {
    			id--;
    			v.setVisibility(View.GONE);
    		}
    	}
    }
    
    

    Just try with a sample layout and see the magic.

    Check if Connected to Internet & if isConnected to Wifi in Android.

    This sample code checks whether the android device is connected to Internet and
    if it is connected to internet, it is connected to Wifi or Not?

    package com.coderzheaven.demo1;
    
    import android.app.Activity;
    import android.content.Context;
    import android.net.ConnectivityManager;
    import android.net.NetworkInfo;
    import android.os.Bundle;
    
    public class MainActivity extends Activity {
    
    	NetworkInfo activeNetwork;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    
    		if (connectedToInternet())
    			System.out.println("Connected to Internet.");
    		else
    			System.out.println("Not Connected to internet");
    
    		if (isWifi())
    			System.out.println("Connected to Wifi.");
    		else
    			System.out.println("Not Connected to Wifi");
    	}
    
    	Boolean connectedToInternet() {
    		ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    
    		activeNetwork = cm.getActiveNetworkInfo();
    		return (activeNetwork != null && activeNetwork
    				.isConnectedOrConnecting());
    
    	}
    
    	Boolean isWifi() {
    		return (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI);
    	}
    }
    

    MAKE SURE YOU ADD BELOW PERMISSION TO THE ANDROID MANIFEST

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

    Localhost for Android Emulator and iPhone Simulator.

    If you are trying to access a file (PHP or java) residing in your server in your own machine, then
    you have to use a specific IP to access it. If it is public, then use the other System’s IP

    1. If it is localhost, In Android you use it as

    10.0.2.2

    The localhost refers to the device on which the code is running, in this case the emulator.

    If you want to refer to the computer which is running the Android simulator, use the IP address 10.0.2.2 instead. You can read more from here.

    2. If you are trying to access from iOS Simulator use can use

    http://localhost:8000/your_path

    The iOS Simulator uses the host machine network so you should be able to just use localhost or your machines IP address, whichever IP your web service is listening on.

    Building Custom Components in Android.

    Hi everyone,

    In this tutorial we will be building a Custom TextView.
    ie. this TextView will be extending the inBuil TextView and have its own custom attributes
    along with the default attributes in a TextView in Android.

    So we will start.

    We will be making a custom textview and presenting to the UI using

    1. XML
    2. Java Code

    1. Using Java Code

    Create a class named CustomTV and extend TextView.

    CustomTV.java

    package com.coderzheaven.customcomponent;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Color;
    import android.util.AttributeSet;
    import android.widget.TextView;
    import com.coderzheaven.customcomponent.R;
    
    public class CustomTV extends TextView {
    
    	public CustomTV(Context context) {
    		super(context);
    	}
    
    	public CustomTV(Context context, AttributeSet attrs) {
    	    super(context, attrs);
    	}
    
    	public CustomTV(Context context, AttributeSet attrs, int defStyle) {
    	    super(context, attrs, defStyle);
    	    
    	}
    	   
    }
    

    Now we go to the MainActivity and place the Custom textview using java code.

    package com.coderzheaven.customcomponent;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.widget.LinearLayout;
    
    public class MainActivity extends Activity {
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    
    		LinearLayout lin = (LinearLayout) findViewById(R.id.lin);
    
    		CustomTV tv = new CustomTV(this);
    		tv.setText("I am a custom TextView from java code With Custom Attributes");
    		tv.setPadding(20, 20, 20, 20);
    		lin.addView(tv);
    
    	}
    
    }
    

    activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"   
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/lin"
        android:orientation="vertical"
        tools:context=".MainActivity" >
      
    </LinearLayout>
    

    1. Using XML

    There is no change in the java code above. Instead we will be adding one more TextView in the
    activity_main.xml which is our custom one.

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/lin"
        android:orientation="vertical"
        tools:context=".MainActivity" >
    
        <com.coderzheaven.customcomponent.CustomTV
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="20dp"
            android:text="I am Custom TextView in the XML with Custom Attributes" />
    
    </LinearLayout>
    

    NOW WE WILL SEE HOW CAN APPLY OUR OWN ATTRIBUTES TO OUR CUSTOM TEXTVIEW.

    Let’s say my custom textview should have an attribute “my_color” to which I can apply my own color as string.
    [We know there is already a method for setting color in a TextView, but this is only for illustration purpose]

    Create an xml named “attrs.xml” inside res/values and copy this code into it.

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <declare-styleable name="CustomTV">
            <attr name="my_color" format="string" />
        </declare-styleable>
    
    </resources>
    

    Now go to activity_main.xml and change xml code like this.
    Make sure to add your custom namespace [xmlns:custom=”http://schemas.android.com/apk/res/com.coderzheaven.customcomponent”]

    activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:custom="http://schemas.android.com/apk/res/com.coderzheaven.customcomponent"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/lin"
        android:orientation="vertical"
        tools:context=".MainActivity" >
    
        <com.coderzheaven.customcomponent.CustomTV
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="20dp"
            custom:my_color="#FF0000"  
            android:text="I am Custom TextView in the XML with Custom Attributes" />
    
    </LinearLayout>
    

    Now if you run, you can see your custom color to your custom TextView.

    Our CustomTV.java will change like this inorder to get the custom attributes and apply
    our own modifications.

    package com.coderzheaven.customcomponent;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Color;
    import android.util.AttributeSet;
    import android.widget.TextView;
    import com.coderzheaven.customcomponent.R;
    
    public class CustomTV extends TextView {
    
    	public CustomTV(Context context) {
    		super(context);
    	}
    
    	public CustomTV(Context context, AttributeSet attrs) {
    		super(context, attrs);
    
    		TypedArray a = context.obtainStyledAttributes(attrs,
    				R.styleable.CustomTV);
    
    		final int N = a.getIndexCount();
    		for (int i = 0; i < N; ++i) {
    			int attr = a.getIndex(i);
    			switch (attr) {
    			case R.styleable.CustomTV_my_color:
    				String my_color = a.getString(attr);
    				setCustomColor(my_color);
    				break;
    			}
    		}
    		a.recycle();
    
    	}
    
    	public void setCustomColor(String color) {
    		this.setTextColor(Color.parseColor(color));
    	}
    
    	public CustomTV(Context context, AttributeSet attrs, int defStyle) {
    		super(context, attrs, defStyle);
    
    	}
    
    }
    
    

    Apply your custom attribute in Java code also.

       tv.setCustomColor("#00FF00");
    

    Nexus 6 Came…

    Nexus 6

    Google Nexus 6

    Specifications

    GENERAL 2G Network GSM 850 / 900 / 1800 / 1900 – all models
      CDMA 800 / 1900 – XT1103 US model
    3G Network HSDPA 800 / 850 / 1700 / 1900 / 2100 / 900 – XT1100 Global model
      HSDPA 850 / 900 / 1700 / 1900 / 2100 – XT1103 US model
    4G Network LTE 700 / 800 / 900 / 1800 / 2100 / 2600 / 850 / 2500 – XT1100 Global model
      LTE 700 / 850 / 900 / 1800 / 1900 / 2100 / 2600 / 2500 – XT1103 US model
    SIM Nano-SIM
    Announced 2014, October
    Status Coming soon. Exp. release 2014, October
    BODY Dimensions 159.3 x 83 x 10.1 mm (6.27 x 3.27 x 0.40 in)
    Weight 184 g (6.49 oz)
    DISPLAY Type AMOLED capacitive touchscreen, 16M colors
    Size 1440 x 2560 pixels, 5.96 inches (~493 ppi pixel density)
    Multitouch Yes
    Protection Corning Gorilla Glass 3
    SOUND Alert types Vibration; MP3, WAV ringtones
    Loudspeaker Yes, with stereo speakers
    3.5mm jack Yes
    MEMORY Card slot No
    Internal 32/64 GB, 3 GB RAM
    DATA GPRS Yes
    EDGE Yes
    Speed DC-HSDPA, 42 Mbps; HSDPA, 21 Mbps; HSUPA, 5.76 Mbps; LTE, Cat6, 50 Mbps UL, 300 Mbps DL
    WLAN Wi-Fi 802.11 a/b/g/n/ac, dual-band, Wi-Fi Direct, DLNA, Wi-Fi hotspot
    Bluetooth v4.0, A2DP
    NFC Yes
    USB microUSB v2.0 (SlimPort), USB Host, USB On-the-go
    CAMERA Primary 13 MP, 4128 x 3096 pixels, autofocus, optical image stabilization, dual-LED flash
    Features Geo-tagging, touch focus, face detection, photo sphere, HDR, dual recording
    Video 2160p@30fps, optical stabilization
    Secondary 2 MP
    FEATURES OS Android OS, v5.0 (Lollipop)
    Chipset Qualcomm Snapdragon 805
    CPU Quad-core 2.7 GHz Krait 450
    GPU Adreno 420
    Sensors Accelerometer, gyro, proximity, compass, barometer
    Messaging SMS(threaded view), MMS, Email, Push Mail, IM
    Browser HTML5
    Radio No
    GPS Yes, with A-GPS, GLONASS
    Java Yes, via Java MIDP emulator
    Colors Midnight Blue, Cloud White
      – Wireless charging
    – Active noise cancellation with dedicated mic
    – MP4/H.264/H.263 player
    – MP3/WAV/eAAC+ player
    – Organizer
    – Photo/video editor
    – Document editor
    – Voice memo/dial/commands
    – Predictive text input
    BATTERY   Non-removable Li-Po 3220 mAh battery
    Stand-by Up to 330 h
    Talk time Up to 24 h

    How to change title and Subtitle text color and size of ActionBar in Android?

    Here is a simple example that shows how you can change title and subtitle textcolor and its size in Android

    Method 1
    ——–

    Changing the styles [For support Library]

    Go to Values/styles.xml copy this code to change the textcolor and actionbar background color.

    
    <style name="CustomActivityTheme" parent="@style/Theme.AppCompat.Light">
            <item name="android:actionBarStyle">@style/MyActionBar</item>
            <item name="actionBarStyle">@style/MyActionBar</item>
             <item name="android:windowActionBarOverlay">true</item>
            <!-- other activity and action bar styles here -->
    </style>
          <!-- style for the action bar backgrounds -->
    <style name="MyActionBar" parent="@style/Widget.AppCompat.Light.ActionBar">
            <item name="android:background">@drawable/actionbar_background</item>
            <item name="background">@drawable/actionbar_background</item>
            <item name="android:titleTextStyle">@style/MyTheme.ActionBar.TitleTextStyle</item>
            <item name="android:subtitleTextStyle">@style/MyTheme.ActionBar.TitleTextStyle</item>
            <item name="titleTextStyle">@style/MyTheme.ActionBar.TitleTextStyle</item>
            <item name="subtitleTextStyle">@style/MyTheme.ActionBar.TitleTextStyle</item>
         </style>
    <style name="MyTheme.ActionBar.TitleTextStyle" parent="@android:style/TextAppearance">
            <item name="android:textColor">@color/color_title</item>
            <item name="android:textSize">12sp</item>
    </style>
    	  
    	  
    

    Note : For applying theme if you are not using the Support Library then change the AppCompat to Holo.

    i.e make the Below changes in the parent

    parent="@android:style/Theme.Holo.Light"
    

    AND

    parent="@android:style/Widget.Holo.Light.ActionBar"
    

    AND for title

    parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title"
    

    Now Apply this theme in the AndroidManifest.xml, either for the entire application or a particular activity.

    For example

    
     <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/CustomActivityTheme" >
            <activity
                android:name="com.example.actionbarcustomize.MainActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
     </application>
    	
    

    Make Sure you add the colors in the strings.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <string name="app_name">ActionBarCustomize</string>
        <string name="hello_world">Hello world!</string>
        <string name="menu_settings">Settings</string>
    
        <drawable name="actionbar_background">#FF0000</drawable>
        <color name="color_title">#00FF00</color>
    	
    </resources>
    

    Method 2
    ———

    You can use a simple java code to so this.

    getActionBar().setTitle(Html.fromHtml("<font color='#ff0000'>ActionBartitle </font>"));
    

    Note : Change getActionBar() to getSupportActionBar() if you are using the support library for ActionBar.

    That’s all.. Now Run the application and see the changes.

    Android In App Purchased Demo V3.

    Hi all,

    This demo shows how to do in app purchase for managed products in Android using Version 3 in-app Billing API.

    Please Go through this before trying out this Demo

    http://developer.android.com/google/play/billing/index.html

    Android In App Purchase

    These are the important steps in to remember for doing in app purchase.

    1. You have to download the Google In App Billing Library from Google.

    For that you have to open the Android SDK Manager and Look for “Google Play Billing Library”.

    2. You have to make changes in the Android Manifest first.

    Add this permission.

         <!-- Permission for In App Purchase -->
        <uses-permission android:name="com.android.vending.BILLING" />
         

    The above permission will detect that your app contains “In App Purchases” in Google Play Store.

    3. Now add the .aidl file that you get while downloading the library from Google.

    [You can find this library in the Sample Project at the end of this post].

    4. Now let’s assume that we have done the coding part by giving a demo in_app item.

    5. You can test the application in two ways either using STATIC RESPONSES from Google Play

    OR real purchases with users but without using any money.

    STATIC TESTING :

    READ THIS LINK : http://developer.android.com/google/play/billing/billing_testing.html#billing-testing-static

    REAL TESTING – AFTER UPLOADING TO GOOGLE PLAY (IN ALPHA OR BETA MODE)

    READ THIS LINK : http://developer.android.com/google/play/billing/billing_testing.html#testing-purchases.

    NOTE : If you publish your application through Alpha or Beta mode, the users who are downloading from Google Play will not see it or get it. In that way Google ensures that it is not published before testing.

    For REAL TESTING AFTER UPLOADING TO GOOGLE PLAY you must be adding some users as Test Users who can test this app that you have
    You can add test users while you upload the apk with in app Billing in Alpha or Beta Mode.

    For adding test users you can see a link in the APK page of the particular app in Alpha or Beta Mode.[This is usually a Google community or Groups]

    For a user to be a Test account you have to go to Settings > Gmail accounts with testing access > add the Gmail account to test.

    This means that these users can buy this in app Item without loosing any money in alpha or Beta Mode.

    Important Note :

    In Google In App Billing V3, all purchases are managed that means you can even consume managed products.

    PRODUCTS ONCE CONSUMED WILL BE A AVAILABLE FOR PURCHASE AGAIN.

    THAT MEANS IF YOU PURCHASE A MANAGED PRODUCT AND IF THE USER CONSUMES IT, THEN IT WILL BE AGAIN AVAILABLE FOR PURCHASE.

    IF THE USER CONSUMES IT GOOGLE WILL REMOVE THAT PURCHASED ITEM FROM IT’S SEVER AND MARK IT AS ‘UN-OWNED’.

    SO WHEN YOU QUERY THE PURCHASED ITEMS YOU WILL NOT BE GETTING THE PURCHASED ITEM.

    SO IF YOU WANT THE USER TO PURCHASE THE ITEM ONLY ONCE AND AVAILABLE ALL THE TIME DON’T CONSUME IT

    THAT MEANS YOU HAVE TO COMMENT OUT THIS CODE FROM THE SAMPLE CODE PROVIDED.

       	mHelper.consumeAsync(purchase, mConsumeFinishedListener);
       

    That is you can directly write your code inside this if the purchase is sucessful

       if (purchase.getSku().equals(SKU_INAPPITEM)) {
       }
       

    OK Done.

    You can download the sample application from this link

    Download In App Billing Source Code

    You can also check this post for more simplified example.

    Yota Phone – The Android Smartphone From Russia With Two Screens

    Yota Phone

    Let’s start with the underlying hardware. Compared to some of the flagship and high-end Android devices launched in 2013, the Yota Phone is decidedly mid-range. The Dual-Core 1.7 GHz Krait CPU has the speed and capability to run Android comfortably, but the handset doesn’t stretch the specs in the current market. It’s nice to see it comes with 2 GB of RAM, and when it was announced at CES 2013 these were cutting-edge specs, but the Android world has moved on since then.

    The handset comes in just one storage memory configuration (32 GB) and unfortunately there is no SD card expansion port. Given 16 GB feels a bit tight on Android handsets today, the 32 GB option should be good for the life of the handset, and with smart use of cloud based services for storage and streaming it should suffice for the majority of use cases.

    Read More from here.
    http://www.forbes.com/sites/ewanspence/2014/01/04/yota-phone-review-the-android-smartphone-from-russia-with-two-screens/

    App Translation Service Now Available to All Developers

    To help developers reach users in other languages, Google launched the App Translation Service, which allows developers to purchase professional app translations through the Google Play Developer Console. This is part of a toolbox of localization features you can (and should!) take advantage of as you distribute your app around the world through Google Play.

    You’ll find the App Translation Service in the Developer Console at the bottom of the APK section — you can start a new translation or manage an existing translation here. You’ll be able to upload your app’s file of string resources, select the languages you want to translate into, select a professional translation vendor, and place your order. Pro tip: you can put your store listing text into the file you upload to the App Translation Service. You’ll be able to communicate with your translator to be sure you get a great result, and download your translated string files. After you do some localization testing, you’ll be ready to publish your newly translated app update on Google Play — with localized store listing text and graphics. Be sure to check back to see the results on your user base, and track the results of marketing campaigns in your new languages using Google Analytics integration.

    You can read more from here

    Intel ready to turn Android into Once Windows were…

    Yes

    The chip maker is now ready for making android scale to even bigger screen that is dominated by the Windows platform..
    Intel is reportedly thinking beyond Microsoft when it comes to a full-fledged ‘client’ operating system, and the best bet today for it is Google’s Android.

    The chipmaker’s general manager, Kirk Skaugen said that for the last decade they have been essentially 100 percent Microsoft but now with the emerging markets demand for Android is seen.

    More about this news from here.
    http://www.dnaindia.com/scitech/report-intel-ready-to-turn-android-into-windows-like-os-1924236

    How to work in ActionBar support Library.

    Hi all

    Today’s post is all about working with ActionBar support libraries from Google.
    These libraries support from Android 2.1 (API 7).

    ActionBar Support Custom

    For working with these libraries we have to follow some instructins.

    Please follow these steps exactly for setting up a Actionbar support library.

    1. Start the Android SDK Manager.
    In the SDK Manager window, scroll to the end of the Packages list, find the Extras folder and, if necessary, expand to show its contents.
    2. Select the Android Support Library item.
    Note: If you’re developing with Android Studio, select and install the Android Support Repository item instead.
    3. Click the Install packages… button.

    ActionBar Support Installation

    After downloading, the tool installs the Support Library files to your existing Android SDK directory. The library files are located in the following subdirectory of your SDK: /extras/android/support/ directory.

    Now Open Eclipse and do the following.

    Create a library project based on the support library code:

    Make sure you have downloaded the Android Support Library using the SDK Manager.
    Create a library project and ensure the required JAR files are included in the project’s build path:
    Select File > Import.
    Select Existing Android Code Into Workspace and click Next.

    Browse to the SDK installation directory and then to the Support Library folder. For example, if you are adding the appcompat project, browse to /extras/android/support/v7/appcompat/.

    Click Finish to import the project. For the v7 appcompat project, you should now see a new project titled android-support-v7-appcompat.

    In the new library project, expand the libs/ folder, right-click each .jar file and select Build Path > Add to Build Path. For example, when creating the the v7 appcompat project, add both the android-support-v4.jar and android-support-v7-appcompat.jar files to the build path.

    Right-click the project and select Build Path > Configure Build Path.
    In the Order and Export tab, check the .jar files you just added to the build path, so they are available to projects that depend on this library project. For example, the appcompat project requires you to export both the android-support-v4.jar and android-support-v7-appcompat.jar files.
    Uncheck Android Dependencies.

    Click OK to complete the changes.

    AndroidManifest.xml changes

    Important
    1. To work with support libraries of actionbar you should also have to change the theme to “Theme.AppCompat”.
    2. Also your activity should extend ActionBarActivity.

    This is all that needed.
    After that you can add this actionbar compat library for any number of projects.

    Usage.

    Instead of using getActionBar(), use should use getSupportActionBar() to point to suppport actionbar libraries.

    A sample looks like this.

    package com.coderzheaven.actionbartest;
    
    import android.os.Bundle;
    import android.support.v7.app.ActionBarActivity;
    import android.view.Menu;
    
    import com.example.actionbartest.R;
    
    public class MainActivity extends ActionBarActivity {
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		
    		getSupportActionBar().setTitle("ActionBar Support Demo");
    	}
    
    	@Override
    	public boolean onCreateOptionsMenu(Menu menu) {
    		// Inflate the menu; this adds items to the action bar if it is present.
    		getMenuInflater().inflate(R.menu.activity_main, menu);
    		return true;
    	}
    
    }
    

    For that you have to make changes in the styles.xml.

    This is my styles.xml in which I have made my ActionBar Custom.

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- the theme applied to the application or activity -->
        <style name="CustomActionBarTheme"
               parent="@style/Theme.AppCompat.Light.DarkActionBar">
            <item name="android:actionBarStyle">@style/MyActionBar</item>
    
            <!-- Support library compatibility -->
            <item name="actionBarStyle">@style/MyActionBar</item>
        </style>
    
        <!-- ActionBar styles -->
        <style name="MyActionBar"
               parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">
            <item name="android:background">@drawable/blue</item>
    
            <!-- Support library compatibility -->
            <item name="background">@drawable/blue</item>
        </style>
    </resources>
    

    My strings.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <string name="app_name">ActionBarTest</string>
        <string name="hello_world">Hello world!</string>
        <string name="menu_settings">Settings</string>
        
        <drawable name="blue">#0000FF</drawable>
    
    </resources>
    

    So you are done.
    Go on and run the project.

    You can download a sample of Project which contains the ActionBarCompat Library and a sample project which links this library from here.
    So when you import it to your eclipse make sure you import two projects included.

    How to Create a new theme for ActionBar in Android.

    In this post I will be telling you about how to change the default theme of ActionBar with our own custom One.
    Here I will be changing the background color, textColor and alpha of default ActionBar.
    Let’s see how it is done.

    By Checking out the styles.xml you will find that by default it looks like this.

    ActionBar Theme

    <resources>
     <style name="AppTheme" parent="android:Theme.Light" />
    </resources>
    

    Right now, we are using a theme “AppTheme” which is inheriting all the attributes from Theme.Light.
    Lets define a new style named “myActionBarTheme”.

    Now my styles.xml looks like this.
    Note that this time i Just changed “Holo.Light” to just “Holo” for darker theme.
    However you can leave it as the old one.

    styles.xml

    <resources xmlns:android="http://schemas.android.com/apk/res/android">
    
        <style name="CustomActionBarTheme" parent="android:style/Theme.Holo">
            <item name="android:actionBarStyle">@style/myActionBarTheme</item>
            
        </style>
    
        <style name="myActionBarTheme" parent="android:style/Widget.Holo.ActionBar">
            <item name="android:background">#FF4444</item>
            <item name="android:titleTextStyle">@style/myActionBarTitleTextStyle</item>
            <item name="android:alpha">1.0</item>
        </style>
         <style name="myActionBarTitleTextStyle" parent="android:style/TextAppearance.Holo.Widget.ActionBar.Title">
            <item name="android:textColor">#FFFFFF</item>
        </style>
    
    </resources>
    

    Now we have to use it right. If we want to apply it to the complete application we can do it like this in the Android Manifest file.

    AndroidManifest.xml

    <application android:theme="@style/CustomActionBarTheme" >
    

    Or You can apply different ones to different activities also.
    In this example I am just changing the ActionBar text color and alpha also.
    You can do any customization according to your wish.

    What ever we use as background will be strectched to fill the size of the ActionBar , so make sure you will be providing a nine-patch image or an XML.
    Here I am using an Xml named “top_bar_bg.xml”

    top_bar_bg.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item>
          <shape>
             <gradient android:angle="90" 
                  android:centerColor="#FF0066FF" 
                  android:endColor="#FF0066FF" 
                  android:startColor="#FF0066FF" />
            </shape>
        </item>
    </selector>
    

    More and more ActionBar customizations and tips will be coming in the next updates.
    Please visit again or subscribe to coderzheaven.com and also like us on facebook to get quick updates.

    PLease leave your valuable comments on this post.

    You can download the complete source code from here.

    How to handle configuration change in an activity using Fragments in android?

    Here is a simple example in which we will save or retain the state of the progress using fragments.

    Note : We have handle a configuration by another way – by ignoring the change i.e using this property in the activity tag
    android:configChanges=””
    By using this android ignores the configuration change and will never try to create a new instance of the activity.
    But Google discourages this practice.

    Handling configuration changes requires you to take many additional steps to ensure that each and every string, layout, drawable, dimension, etc. remains in sync with the device’s current configuration, and if you aren’t careful, you’re application can easily have a whole series of resource-specific bugs as a result.

    Another reason why Google discourages its use is because many developers incorrectly assume that setting android:configChanges=”orientation” (for example) will magically protect their application from unpredictable scenarios in which the underlying Activity will be destroyed and recreated. This is not the case. Configuration changes can occur for a number of reasons—not just screen orientation changes. Inserting your device into a display dock, changing the default language, and modifying the device’s default font scaling factor are just three examples of events that can trigger a device configuration change, all of which signal the system to destroy and recreate all currently running Activitys the next time they are resumed. As a result, setting the android:configChanges attribute is generally not good practice.

    retain state

    retain state

    Let’s go to the code and see how it is done.

    Now we will see how to do that.

    At first I will show you the layout which simply contains a textview that show the progress.

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity" >
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:layout_alignParentTop="true"
            android:text="Handling Runtime configuration changes by saving state using Fragments"
            android:textColor="@android:color/black"
            android:textSize="20sp" />
    
        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true" >
    
            <TextView
                android:id="@+id/tv_pro"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:textColor="@android:color/holo_blue_bright"
                android:textSize="40sp" />
        </FrameLayout>
    
    </RelativeLayout>
    

    Now we will see the code for the activity.

    package com.example.retaininstanceusingfragmentsexample;
    
    import android.app.Activity;
    import android.app.FragmentManager;
    import android.os.Bundle;
    import android.widget.TextView;
    
    public class MainActivity extends Activity implements
    		TaskFragment.TaskCallbacks {
    
    	private TaskFragment mTaskFragment;
    	TextView tvPro = null;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    
    		tvPro = (TextView) findViewById(R.id.tv_pro);
    
    		FragmentManager fm = getFragmentManager();
    		mTaskFragment = (TaskFragment) fm.findFragmentByTag("task");
    
    		// If the Fragment is not null, then it is currently being
    		// retained when a configuration change occurs.
    		if (mTaskFragment == null) {
    			mTaskFragment = new TaskFragment();
    			fm.beginTransaction().add(mTaskFragment, "task").commit();
    		}
    
    		// TODO: initialize views, restore saved state, etc.
    	}
    
    	@Override
    	public void onPreExecute() {
    	}
    
    	@Override
    	public void onProgressUpdate(int percent) {
    		tvPro.setText(percent + "%");
    	}
    
    	@Override
    	public void onCancelled() {
    	}
    
    	@Override
    	public void onPostExecute() {
    	}
    }
    

    Now the Fragments that handles the retained state.

    package com.example.retaininstanceusingfragmentsexample;
    
    import android.app.Activity;
    import android.app.Fragment;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.os.SystemClock;
    
    /**
     * This Fragment manages a single background task and retains itself across
     * configuration changes.
     */
    public class TaskFragment extends Fragment {
    
    	/**
    	 * Callback interface through which the fragment will report the task's
    	 * progress and results back to the Activity.
    	 */
    	static interface TaskCallbacks {
    		void onPreExecute();
    
    		void onProgressUpdate(int percent);
    
    		void onCancelled();
    
    		void onPostExecute();
    	}
    
    	private TaskCallbacks mCallbacks;
    	private DummyTask mTask;
    
    	/**
    	 * Hold a reference to the parent Activity so we can report the task's
    	 * current progress and results. The Android framework will pass us a
    	 * reference to the newly created Activity after each configuration change.
    	 */
    	@Override
    	public void onAttach(Activity activity) {
    		super.onAttach(activity);
    		mCallbacks = (TaskCallbacks) activity;
    	}
    
    	/**
    	 * This method will only be called once when the retained Fragment is first
    	 * created.
    	 */
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    
    		// Retain this fragment across configuration changes.
    		setRetainInstance(true);
    
    		// Create and execute the background task.
    		mTask = new DummyTask();
    		mTask.execute();
    	}
    
    	/**
    	 * Set the callback to null so we don't accidentally leak the Activity
    	 * instance.
    	 */
    	@Override
    	public void onDetach() {
    		super.onDetach();
    		mCallbacks = null;
    	}
    
    	/**
    	 * A dummy task that performs some (dumb) background work and update the UI
    	 */
    	private class DummyTask extends AsyncTask<Void, Integer, Void> {
    
    		@Override
    		protected void onPreExecute() {
    			if (mCallbacks != null) {
    				mCallbacks.onPreExecute();
    			}
    		}
    
    		/**
    		 * Note that we do NOT call the callback object's methods directly from
    		 * the background thread, as this could result in a race condition.
    		 */
    		@Override
    		protected Void doInBackground(Void... ignore) {
    			for (int i = 0; !isCancelled() && i < 100; i++) {
    				SystemClock.sleep(500);
    				// call to onProgressUpdate
    				publishProgress(i);
    			}
    			return null;
    		}
    
    		@Override
    		protected void onProgressUpdate(Integer... percent) {
    			if (mCallbacks != null) {
    				mCallbacks.onProgressUpdate(percent[0]);
    			}
    		}
    
    		@Override
    		protected void onCancelled() {
    			if (mCallbacks != null) {
    				mCallbacks.onCancelled();
    			}
    		}
    
    		@Override
    		protected void onPostExecute(Void ignore) {
    			if (mCallbacks != null) {
    				mCallbacks.onPostExecute();
    			}
    		}
    	}
    }
    

    After running this application, try to rotate the device and see how the fragment retains the state of the progress.

    You can download the complete source code of this post from here.

    Using Meta-data in Android Manifest and accessing it.

    Sometimes you have the need to set up some app-wide configuration information in an Android app or need to create a class that can be used in multiple projects with a generic way of setting configuration values. This is particularly useful for things like API keys that will probably be different across apps but should be accessible in the same way. There are several ways to do it, but the one I’ve come to prefer is adding a meta-data node to the AndroidManifest.xml file. If you are familiar with Android Adnetworks, most of them are using meta-data for this.

    This field can be used to store a boolean, float, int, or String and is later accessed by the Bundle method for your data type (e.g., getInt()). Here is an example of how to define a value in your AndroidManifest.xml:

    Let’s look at an example

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.metadataexample"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="17" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.example.metadataexample.MainActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            
             <meta-data android:name="myAPIKey" android:value="sample_value" />
        </application>
    
    </manifest>
    

    To get the value in the java code.

    String TAG = "Example Meta-Data";
    		try {
    			ApplicationInfo ai = getPackageManager().getApplicationInfo(
    					getPackageName(), PackageManager.GET_META_DATA);
    			Bundle bundle = ai.metaData;
    			String myAPIKey = bundle.getString("myAPIKey");
    			System.out.println("API KEY : " + myAPIKey);
    		} catch (NameNotFoundException e) {
    			Log.e(TAG,
    					"Failed to load meta-data, NameNotFound: " + e.getMessage());
    		} catch (NullPointerException e) {
    			Log.e(TAG,
    					"Failed to load meta-data, NullPointer: " + e.getMessage());
    		}
    

    You can download the sample code from here.

    How to write a custom content provider in android? with a sample application using our own custom content provider.

    Hello all

    we all know what are content providers right?
    Those who are unaware of content providers please visit this link http://developer.android.com/guide/topics/providers/content-providers.html

    Custom Content Provider

    Custom Content Provider

    In a breif content Providers are

    Content providers manage access to a structured set of data. They encapsulate the data, and provide mechanisms for defining data security. Content providers are the standard interface that connects data in one process with code running in another process.

    When you want to access data in a content provider, you use the ContentResolver object in your application’s Context to communicate with the provider as a client. The ContentResolver object communicates with the provider object, an instance of a class that implements ContentProvider. The provider object receives data requests from clients, performs the requested action, and returns the results.

    This sample Demo is creating custom content provider using SQLite Database.

    Now we will see how we can create our own custom content provider.

    Tn this example I have three classes.
    1. MainActivity.java
    2. NotesContentProvider.java
    3. NotesMetaData.java

    At first we will look at “NotesMetaData.java”.

    package com.coderzheaven.custom_contentproviderdemo;
    
    import android.net.Uri;
    import android.provider.BaseColumns;
    
    public class NotesMetaData {
    
    	public NotesMetaData() {
    
    	}
    
    	// A content URI is a URI that identifies data in a provider. Content URIs
    	// include the symbolic name of the entire provider (its authority)
    	public static final String AUTHORITY = "com.coderzheaven.custom_contentproviderdemo.Notes";
    	public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
    			+ "/notes");
    
    	public static final String DATABASE_NAME = "notes.db";
    	public static final int DATABASE_VERSION = 1;
    
    	public static final String CONTENT_TYPE_NOTES_ALL = "vnd.android.cursor.dir/vnd.coderz.notes";
    	public static final String CONTENT_TYPE_NOTES_ONE = "vnd.android.cursor.item/vnd.coderz.notes";
    
    	public class NotesTable implements BaseColumns {
    
    		private NotesTable() {
    
    		}
    
    		public static final String TABLE_NAME = "tbl_notes";
    
    		public static final String ID = "_id";
    		public static final String TITLE = "title";
    		public static final String CONTENT = "content";
    	}
    
    }
    
    

    NotesMetaData class defines some required constant values to use:

    + AUTHORITY: this is the name of your content provider

    + CONTENT_URI: is your content provider URI for other applications to access data from it.

    Let’s say if you want to get all notes, it would be like:

    content://”com.coderzheaven.custom_contentproviderdemo.Notes/notes”

    To retrieve a specific note:

    content://com.coderzheaven.custom_contentproviderdemo.Notes/notes/5″

    Now the “NotesContentProvider.java”

    package com.coderzheaven.custom_contentproviderdemo;
    
    import java.util.HashMap;
    
    import android.content.ContentProvider;
    import android.content.ContentUris;
    import android.content.ContentValues;
    import android.content.Context;
    import android.content.UriMatcher;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.database.sqlite.SQLiteQueryBuilder;
    import android.net.Uri;
    import android.text.TextUtils;
    
    public class NotesContentProvider extends ContentProvider {
    
    	private static final UriMatcher sUriMatcher;
    
    	private static final int NOTES_ALL = 1;
    	private static final int NOTES_ONE = 2;
    
    	static {
    		sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    		sUriMatcher.addURI(NotesMetaData.AUTHORITY, "notes", NOTES_ALL);
    		sUriMatcher.addURI(NotesMetaData.AUTHORITY, "notes/#", NOTES_ONE);
    	}
    
    	// Map table columns
    	private static final HashMap<String, String> sNotesColumnProjectionMap;
    	static {
    		sNotesColumnProjectionMap = new HashMap<String, String>();
    		sNotesColumnProjectionMap.put(NotesMetaData.NotesTable.ID,
    				NotesMetaData.NotesTable.ID);
    		sNotesColumnProjectionMap.put(NotesMetaData.NotesTable.TITLE,
    				NotesMetaData.NotesTable.TITLE);
    		sNotesColumnProjectionMap.put(NotesMetaData.NotesTable.CONTENT,
    				NotesMetaData.NotesTable.CONTENT);
    	}
    
    	private static class NotesDBHelper extends SQLiteOpenHelper {
    
    		public NotesDBHelper(Context c) {
    			super(c, NotesMetaData.DATABASE_NAME, null,
    					NotesMetaData.DATABASE_VERSION);
    		}
    
    		private static final String SQL_QUERY_CREATE = "CREATE TABLE "
    				+ NotesMetaData.NotesTable.TABLE_NAME + " ("
    				+ NotesMetaData.NotesTable.ID
    				+ " INTEGER PRIMARY KEY AUTOINCREMENT, "
    				+ NotesMetaData.NotesTable.TITLE + " TEXT NOT NULL, "
    				+ NotesMetaData.NotesTable.CONTENT + " TEXT NOT NULL" + ");";
    
    		@Override
    		public void onCreate(SQLiteDatabase db) {
    			db.execSQL(SQL_QUERY_CREATE);
    		}
    
    		private static final String SQL_QUERY_DROP = "DROP TABLE IF EXISTS "
    				+ NotesMetaData.NotesTable.TABLE_NAME + ";";
    
    		@Override
    		public void onUpgrade(SQLiteDatabase db, int oldVer, int newVer) {
    			db.execSQL(SQL_QUERY_DROP);
    			onCreate(db);
    		}
    	}
    
    	// create a db helper object
    	private NotesDBHelper mDbHelper;
    
    	@Override
    	public boolean onCreate() {
    		mDbHelper = new NotesDBHelper(getContext());
    		return false;
    	}
    
    	@Override
    	public int delete(Uri uri, String where, String[] whereArgs) {
    		SQLiteDatabase db = mDbHelper.getWritableDatabase();
    		int count = 0;
    		switch (sUriMatcher.match(uri)) {
    		case NOTES_ALL:
    			count = db.delete(NotesMetaData.NotesTable.TABLE_NAME, where,
    					whereArgs);
    			break;
    
    		case NOTES_ONE:
    			String rowId = uri.getPathSegments().get(1);
    			count = db.delete(
    					NotesMetaData.NotesTable.TABLE_NAME,
    					NotesMetaData.NotesTable.ID
    							+ " = "
    							+ rowId
    							+ (!TextUtils.isEmpty(where) ? " AND (" + where
    									+ ")" : ""), whereArgs);
    			break;
    
    		default:
    			throw new IllegalArgumentException("Unknown URI: " + uri);
    		}
    
    		getContext().getContentResolver().notifyChange(uri, null);
    		return count;
    	}
    
    	@Override
    	public String getType(Uri uri) {
    
    		switch (sUriMatcher.match(uri)) {
    		case NOTES_ALL:
    			return NotesMetaData.CONTENT_TYPE_NOTES_ALL;
    
    		case NOTES_ONE:
    			return NotesMetaData.CONTENT_TYPE_NOTES_ONE;
    
    		default:
    			throw new IllegalArgumentException("Unknown URI: " + uri);
    		}
    	}
    
    	@Override
    	public Uri insert(Uri uri, ContentValues values) {
    
    		// you cannot insert a bunch of values at once so throw exception
    		if (sUriMatcher.match(uri) != NOTES_ALL) {
    			throw new IllegalArgumentException(" Unknown URI: " + uri);
    		}
    
    		// Insert once row
    		SQLiteDatabase db = mDbHelper.getWritableDatabase();
    		long rowId = db.insert(NotesMetaData.NotesTable.TABLE_NAME, null,
    				values);
    		if (rowId > 0) {
    			Uri notesUri = ContentUris.withAppendedId(
    					NotesMetaData.CONTENT_URI, rowId);
    			getContext().getContentResolver().notifyChange(notesUri, null);
    			return notesUri;
    		}
    		throw new IllegalArgumentException("<Illegal>Unknown URI: " + uri);
    	}
    
    	// Get values from Content Provider
    	@Override
    	public Cursor query(Uri uri, String[] projection, String selection,
    			String[] selectionArgs, String sortOrder) {
    		SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
    		switch (sUriMatcher.match(uri)) {
    		case NOTES_ALL:
    			builder.setTables(NotesMetaData.NotesTable.TABLE_NAME);
    			builder.setProjectionMap(sNotesColumnProjectionMap);
    			break;
    
    		case NOTES_ONE:
    			builder.setTables(NotesMetaData.NotesTable.TABLE_NAME);
    			builder.setProjectionMap(sNotesColumnProjectionMap);
    			builder.appendWhere(NotesMetaData.NotesTable.ID + " = "
    					+ uri.getLastPathSegment());
    			break;
    
    		default:
    			throw new IllegalArgumentException("Unknown URI: " + uri);
    		}
    
    		SQLiteDatabase db = mDbHelper.getReadableDatabase();
    		Cursor queryCursor = builder.query(db, projection, selection,
    				selectionArgs, null, null, null);
    		queryCursor.setNotificationUri(getContext().getContentResolver(), uri);
    
    		return queryCursor;
    	}
    
    	@Override
    	public int update(Uri uri, ContentValues values, String where,
    			String[] whereArgs) {
    
    		SQLiteDatabase db = mDbHelper.getWritableDatabase();
    		int count = 0;
    		switch (sUriMatcher.match(uri)) {
    		case NOTES_ALL:
    			count = db.update(NotesMetaData.NotesTable.TABLE_NAME, values,
    					where, whereArgs);
    			break;
    
    		case NOTES_ONE:
    			String rowId = uri.getLastPathSegment();
    			count = db
    					.update(NotesMetaData.NotesTable.TABLE_NAME, values,
    							NotesMetaData.NotesTable.ID	+ " = "	+ rowId	+ (!TextUtils.isEmpty(where) ? " AND ("	+ ")" : ""), whereArgs);
    
    		default:
    			throw new IllegalArgumentException("Unknown URI: " + uri);
    		}
    
    		getContext().getContentResolver().notifyChange(uri, null);
    		return count;
    	}
    
    }
    

    When you insert/update/delete, always remember to call “notifyChange()” to the URI that has been used.

    When you query values, always remember to to call “setNotificationUri()” for Cursor.

    That’s done for creating your custom content provider. In order to use, you need to register it to AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.coderzheaven.custom_contentproviderdemo"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="17" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.coderzheaven.custom_contentproviderdemo.MainActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            
            
            
            <provider
                android:name="com.coderzheaven.custom_contentproviderdemo.NotesContentProvider"
                android:authorities="com.coderzheaven.custom_contentproviderdemo.Notes" >
            </provider>
            
        </application>
    
    </manifest>
    

    Now we look how we can use it in an activity

    MainActivity.java

    package com.coderzheaven.custom_contentproviderdemo;
    
    import android.app.Activity;
    import android.content.ContentValues;
    import android.database.Cursor;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.Toast;
    
    import com.coderzheaven.custom_contentproviderdemo.NotesMetaData.NotesTable;
    
    public class MainActivity extends Activity implements OnClickListener {
    
    	private final static String TAG = "CustomContentProvider";
    	EditText title, content, delete_id;
    	Button add, update, delete, showNotes;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    
    		title = (EditText) findViewById(R.id.title);
    		content = (EditText) findViewById(R.id.content);
    		delete_id = (EditText) findViewById(R.id.delete_id);
    
    		// add Click Listners
    		add = (Button) findViewById(R.id.button_add);
    		add.setOnClickListener(this);
    		update = (Button) findViewById(R.id.button_update);
    		update.setOnClickListener(this);
    		delete = (Button) findViewById(R.id.button_delete);
    		delete.setOnClickListener(this);
    		showNotes = (Button) findViewById(R.id.show_notes);
    		showNotes.setOnClickListener(this);
    
    		getNotes();
    
    	}
    
    	void addNote() {
    		if (title.getText().toString().length() > 0
    				&& content.getText().toString().length() > 0) {
    			ContentValues values = new ContentValues();
    			values.put(NotesTable.TITLE, title.getText().toString());
    			values.put(NotesTable.CONTENT, content.getText().toString());
    			getContentResolver().insert(NotesMetaData.CONTENT_URI, values);
    			Log.i(TAG, "Inserted");
    			makeToast("Note Added");
    		} else {
    			makeToast("Empty Field");
    		}
    	}
    
    	void deleteNote(String str_id) {
    		try {
    			int id = Integer.parseInt(str_id);
    			Log.i(TAG, "Deleting with id = " + id);
    			getContentResolver().delete(NotesMetaData.CONTENT_URI,
    					NotesMetaData.NotesTable.ID + " = " + id, null);
    			Log.i(TAG, "Deleted");
    			makeToast("Note Deleted");
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    	void updateNote(String str_id) {
    		try {
    			int id = Integer.parseInt(str_id);
    			Log.i(TAG, "Updating with id = " + id);
    			ContentValues values = new ContentValues();
    			values.put(NotesTable.TITLE, title.getText().toString());
    			values.put(NotesTable.CONTENT, content.getText().toString());
    			getContentResolver().update(NotesMetaData.CONTENT_URI, values,
    					NotesMetaData.NotesTable.ID + " = " + id, null);
    			makeToast("Note Updated");
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    	void getNotes() {
    
    		Cursor cur = getContentResolver().query(NotesMetaData.CONTENT_URI,
    				null, null, null, null);
    
    		if (cur.getCount() > 0) {
    			Log.i(TAG, "Showing values.....");
    			while (cur.moveToNext()) {
    				String Id = cur.getString(cur.getColumnIndex(NotesTable.ID));
    				String title = cur.getString(cur
    						.getColumnIndex(NotesTable.TITLE));
    				System.out.println("Id = " + Id + ", Note Title : " + title);
    			}
    			makeToast("Check the LogCat for Notes");
    		} else {
    			Log.i(TAG, "No Notes added");
    			makeToast("No Notes added");
    		}
    	}
    
    	@Override
    	public void onClick(View arg0) {
    		if (arg0 == add) {
    			addNote();
    		}
    		if (arg0 == update) {
    			// update note with Id
    			updateNote(delete_id.getText().toString());
    		}
    		if (arg0 == delete) {
    			// delete note with Id
    			deleteNote(delete_id.getText().toString());
    		}
    		if (arg0 == showNotes) {
    			// show all
    			getNotes();
    		}
    	}
    
    	private void makeToast(String text) {
    		Toast.makeText(this, text, Toast.LENGTH_LONG).show();
    	}
    
    }
    

    You can download the complete source code from this demo here.

    Samsung Galaxy Note 3 in India for Rs.49990

    Here are Galaxy note 3 specs.

    Samsung Galaxy Note 3

    General

    2G Network GSM 850 / 900 / 1800 / 1900
    3G Network HSDPA 850 / 900 / 1900 / 2100
    4G Network LTE
    SIM Micro-SIM
    Announced 2013, September
    Status Coming soon. Exp. release 2013, September
    Body

    Dimensions 151.2 x 79.2 x 8.3 mm (5.95 x 3.12 x 0.33 in)
    Weight 168 g (5.93 oz)
    – S Pen stylus
    Display

    Type Super AMOLED capacitive touchscreen, 16M colors
    Size 1080 x 1920 pixels, 5.7 inches (~386 ppi pixel density)
    Multitouch Yes
    Sound

    Alert types Vibration; MP3, WAV ringtones
    Loudspeaker Yes
    3.5mm jack Yes
    Memory

    Card slot microSD, up to 64 GB
    Internal 32/64 GB storage, 3 GB RAM
    Data

    GPRS Yes
    EDGE Yes
    Speed HSDPA, 42 Mbps; HSUPA; LTE, Cat4, 50 Mbps UL, 150 Mbps DL
    WLAN Wi-Fi 802.11 a/b/g/n/ac, dual-band, DLNA, Wi-Fi Direct, Wi-Fi hotspot
    Bluetooth Yes, v4.0 with A2DP, LE, EDR
    NFC Yes
    Infrared port Yes
    USB Yes, microUSB v3.0 (MHL 2), USB Host
    Camera

    Primary 13 MP, 4128 x 3096 pixels, autofocus, LED flash
    Features Dual Shot, Simultaneous HD video and image recording, geo-tagging, touch focus, face and smile detection, image stabilization, panorama, HDR
    Video Yes, 2160p@30fps, 1080p@60fps (N9005)/ 1080p (N9000)
    Secondary Yes, 2 MP, 1080p@30fps
    Features

    OS Android OS, v4.3 (Jelly Bean)
    Chipset Qualcomm Snapdragon 800 (N9005)/ Exynos 5 Octa 5420 (N9000)
    CPU Quad-core 2.3 GHz Krait 400 (N9005)/ Quad-core 1.9 GHz Cortex-A15 & quad-core 1.3 GHz Cortex-A7 (N9000)
    GPU Adreno 330 (N9005)/ Mali-T628 MP6 (N9000)
    Sensors Accelerometer, gyro, proximity, compass, barometer, temperature, humidity, gesture
    Messaging SMS(threaded view), MMS, Email, Push Mail, IM, RSS
    Browser HTML5
    Radio No
    GPS Yes, with A-GPS support and GLONASS
    Java Yes, via Java MIDP emulator
    Colors Black, White, Pink
    – ANT+ support
    – S-Voice natural language commands and dictation
    – Air gestures
    – SNS integration
    – Active noise cancellation with dedicated mic
    – Dropbox (50 GB storage)
    – TV-out (via MHL A/V link)
    – MP4/DivX/XviD/WMV/H.264/H.263 player
    – MP3/WAV/eAAC+/AC3/FLAC player
    – Organizer
    – Image/video editor
    – Document editor (Word, Excel, PowerPoint, PDF)
    – Google Search, Maps, Gmail,
    YouTube, Calendar, Google Talk, Picasa
    – Voice memo/dial/commands
    – Predictive text input (Swype)
    Battery

    Li-Ion 3200 mAh battery