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

inapp

in app

in app

in app

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.

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

A dazzling new generation

  • windows 8.1 laptops

The new generation of Windows 8.1 tablets, laptops, and 2-in-1 PCs are thin, light, long-lasting, and powerful, so you can take your PC with you wherever you go and stay powered up and connected all day long.

More ways to work and play

  • Catch up on email
  • Prepare a presentation
  • Make a Skype call
  • Surf a web
  • Download a new game
  • watch a new movie

    The latest PCs for Windows offer you stunning new forms, features, and functionality

How to add info button to right side or leftside of navigationbar in iPhone?


    UIButton* infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
    [infoButton addTarget:self action:@selector(showInfoView:) forControlEvents:UIControlEventTouchUpInside];
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:infoButton];

Adding button action function.

- (IBAction)showInfoView:(id)sender {
    
}

Random Integer array without repetition in Objective C Iphone

This sample code generates a random number and checks whether its already present in the array.
If yes then it will not add else it will add, thus generating a random array without duplicates.

-(NSMutableArray *) generateRandomArray : (int) max{
    NSMutableArray *randArray = [NSMutableArray new];
    for (int k = 0; k < max; k++) {
       int r = arc4random() % max;
        if([randArray containsObject:[NSString stringWithFormat:@"%d", r]]){
            k--;
        }else{
            [randArray addObject:[NSString stringWithFormat:@"%d", r]];
        }
    }
    NSLog(@"RAND %@",randArray);
    return randArray;
}

Please leave your valuable comments if you found this post useful.

How to download an image from a URL in Objective C iPhone?

Download image from URL in iPhone

This method downloads the image from the specified URL and stores in the documents directory and then shown in an ImageView.
Make sure you have an imageview linked with the outlet in the UserInterface.


-(void) downloadImageFromURL :( NSString *)imageUrl{
    
    NSURL  *url = [NSURL URLWithString:imageUrl];
    NSData *urlData = [NSData dataWithContentsOfURL:url];
    if ( urlData )
    {
        NSLog(@"Downloading started...");
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,@"dwnld_image.png"];
        NSLog(@"FILE : %@",filePath);
        [urlData writeToFile:filePath atomically:YES];
        UIImage *image1=[UIImage imageWithContentsOfFile:filePath];
        imageView.image=image1;
        NSLog(@"Completed...");
    }
    
}

Please leave your comments if you found this code useful.

How to create a radioGroup in Android inside a Scrollview?

Here is a sample code that creates a radiobutton group inside a scrollview.
Please make sure you have a scrollview in your UI and its linked.

// This function adds the radio buttons inside the scrollview.
Here I am using some of my variables to generate the count of radio buttons.
Please make sure to change it before using it in your code.

UIRadioButton implementation in iPhone
UIRadioButton implementation in iPhone


NSString *const CHECKED_IMAGE = @"radiochecked.png";
NSString *const UNCHECKED_IMAGE = @"radiounchecked.png";

int y=0;
    
    for(int optionCount = 0; optionCount < [pracObj.answers count]; optionCount++){
        
        UIButton *answerCheckBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [answerCheckBtn addTarget:self action:@selector(answerSelected:)
                                       forControlEvents:UIControlEventTouchDown];
        [answerCheckBtn setTitle:@"" forState:UIControlStateNormal];
        
        //set background image for button
        answerCheckBtn.backgroundColor = [UIColor clearColor];
        answerCheckBtn.frame = CGRectMake(1.0, y+2, 20,20);
        UIImage *buttonImageNormal = [UIImage imageNamed:UNCHECKED_IMAGE];
        UIImage *strechableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12 topCapHeight:0];
        [answerCheckBtn setBackgroundImage:strechableButtonImageNormal forState:UIControlStateNormal];
        
        answerCheckBtn.tag = optionCount + ANSWERTAG_STARTING;
        
        UILabel *answerLabel = [UILabel new];
        answerLabel.tag =  optionCount+100;
        answerLabel.text = [[pracObj.answers objectAtIndex:optionCount] stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]];
        answerLabel.lineBreakMode = NSLineBreakByWordWrapping;
        answerLabel.numberOfLines = 1;       
        answerLabel.frame = CGRectMake(30, y+2, 300.0, 20.0);
        
        [answerLabel sizeToFit];
        y+=answerLabel.frame.size.height;
        
        [answerLabel setFont:[UIFont systemFontOfSize:10]];
        [answersScrollView addSubview:answerCheckBtn];
        [answersScrollView addSubview:answerLabel];
    }

And click of each radio button you can cal this function to reset the image.


-(IBAction)answerSelected:(id)sender
{
    UIButton *curBtn = (UIButton*) sender;
    NSLog(@"DYN MEthod Clckd %d", curBtn.tag);
    
    UIImage *buttonImageNormal = [UIImage imageNamed:CHECKED_IMAGE];
    UIImage *strechableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12 topCapHeight:0];
    [curBtn setBackgroundImage:strechableButtonImageNormal forState:UIControlStateNormal];
    
    
    [self clearButtons:curBtn.tag];
}

-(void) clearButtons:(int) curTag
{
    int totalAnsCount = [curPracticeQuestionObj.answers count];
    
    for (int y = ANSWERTAG_STARTING; y < (ANSWERTAG_STARTING + totalAnsCount); y++) {
        if (y != curTag) {
            
            UIButton *otherButton = (UIButton *)[answersScrollView viewWithTag:y];
            UIImage *buttonImageNormal = [UIImage imageNamed:UNCHECKED_IMAGE];
            UIImage *strechableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12 topCapHeight:0];
            [otherButton setBackgroundImage:strechableButtonImageNormal forState:UIControlStateNormal];
            
        }
    }
    
}

How to split a string using a delimiter in iPhone and add it to a mutable array?

Here is a simple code that does this..

-(NSMutableArray *) getAnswers :( NSString *) yourstring{
    NSMutableArray *answers = [NSMutableArray new];
    NSArray *parts = [[yourstring componentsSeparatedByString:@","];
    for(NSString *str in parts){
        [answers addObject:str];
    }
    NSLog(@"RET answers %@", answers);
    return answers;
}

After splitting the string with “componentsSeparatedByString” the parts are added to a NSMutableArray using addObject.

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
android:minSdkVersion="7"
android:targetSdkVersion="17">

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.

A 4.8 inch iPhone may be on the way

Every iPhone user may be envious on seeing a bigger screen Android Phone.

iPhone 5S

But don’t worry Apple is said to be working on an iPhone with a 4.8-inch screen, a 20% increase in screen size from the iPhone 5S, iPhone 5C and iPhone 5.

Jeffries analyst Peter Misek has issued a research note to investors where he cited supply chain sources in China claiming that Apple will unveil an iPhone with 4.8-inch screen. This model is scheduled to be launched in September next year and will be named iPhone 6, said Misek.

You can read more about the story 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

Android JellyBean new features

  • WI-Fi Direct
  • 1080p video recording for stock Android devices
  • Improved error correction on the keyboard
  • You can directly access the apps from the lock screen
  • Upgraded copy and paste functionality
  • Support for the WebP image format
  • Hardware acceleration of the universal Interface
  • Soft buttons from Android 3.x are now available for use on phones
  • Widgets in a new tab can be separated, listed in a similar manner to apps
  • Folders can easily be created with a drag-and-drop style
  • Launcher Customizer
  • Enhanced visual voicemail with the ability to speed up or slow down voicemail messages
  • Pinch-to-zoom functionality in the calendar
  • Integrated screenshot capture (accomplished by holding down the Power and Volume-Down buttons)
  • Improved voice integration and continuous, real-time speech to text dictation
  • Face Unlock, a feature that allows users to unlock handsets using facial recognition software
  • New tabbed web browser under Google’s Chrome brand, allowing up to 16 tabs
  • Automatic syncing of browser with users’ Chrome bookmarks
  • A new typeface family for the UI, Roboto
  • A data Usage section in settings that lets users set warnings when they approach a certain usage limit, and disable data use when the limit is exceeded
  • Shut down apps ability that are using data in the background
  • An improved camera app with zero shutter lag, time lapse settings, panorama mode, and the ability to zoom while recording
  • Built-in photo editor
  • You can organize New gallery layout by location and person
  • Refreshed “People” app with social network integration, status updates and hi-res images
  • A near-field communication feature (Android Beam) allowing the rapid short-range exchange of web bookmarks, contact info, directions, YouTube videos and other data
  • Android VPN Framework (AVF), and TUN (but not TAP) kernel module.
  • Creating a Clock Widget in Android with Custom Font.

    Hi all

    if you have been a regular visitor of this website you have seen that I have shown you how to create a simple widget, adding controls to it, adding event handlers in the views etc…
    Do check this website for more tutorials on widgets.

    You can find other tutorials by following this LINK.

    This tutorial is also an important one on widgets.
    People always find it difficult to customize their widgets with Custom Fonts. AS of now you cannot directly set the font in a TextView in a Widget. For that you have to go indirectly.

    In this example I will show you how to create a Clock widget with Custom Font.

    Custom Font in Android Widget

    Custom Font in Android Widget

    So we will start.

    At first we will create the XML files.

    acitvity_main.xml – This is our main layout which contains a button that creates the widget.

    <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"
        android:background="@android:color/white" >
    
        <Button
            android:id="@+id/create_widget"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:text="Create Widget" />
    
    </RelativeLayout>
    

    Now the layout for the Widget and the WidgetProvider.

    my_widget_provider.xml

    <?xml version="1.0" encoding="utf-8"?>
    <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
        android:minWidth="250dip"
        android:minHeight="70dip"
        android:updatePeriodMillis="300000"
        android:configure="com.coderzheaven.customfontinwidget.SettingsPage" 
        android:initialLayout="@layout/widget_main"
    /> 
    

    widget_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/widget_root"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:baselineAligned="false"
        android:orientation="vertical" >
    
        <ImageView
            android:id="@+id/imageView_bg"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:scaleType="fitXY"
            android:contentDescription="@drawable/ic_launcher" />
        
        <ImageView
            android:id="@+id/imageView_txt"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:scaleType="fitXY"
            android:contentDescription="@drawable/ic_launcher" />
    
    </FrameLayout>
    

    OK Now the AndroidManifest File.

    Do look at my old posts for more explanation about the Mainfest files when you are using the widgets.

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.coderzheaven.customfontinwidget"
        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.customfontinwidget.SettingsPage"
                android:configChanges="keyboardHidden|orientation"
                android:label="@string/app_name"
                android:theme="@android:style/Theme.Translucent" >
                <intent-filter>
                    <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
                </intent-filter>
            </activity>
    
            <receiver
                android:name=".RepeatingAlarm"
                android:process=":remote" />
    
            <!-- Broadcast Receiver that will process AppWidget Updates -->
            <receiver
                android:name="com.coderzheaven.customfontinwidget.MyAppWidgetProvider"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                </intent-filter>
    
                <meta-data
                    android:name="android.appwidget.provider"
                    android:resource="@layout/my_widget_provider" />
            </receiver>
        </application>
    
    </manifest>
    

    Now create an XML file inside the drawable folder and name it theme0.xml and copy this code into it.

    <?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="#7700FF00" android:endColor="#3300FF00" android:startColor="#3300FF00" />
    
                <stroke android:width="1dp" android:color="#FF00FF00" />
    
                <corners android:radius="10dp" />
    
                <padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" />
            </shape></item>
    
    </selector>
    

    Now our XML files are over.
    Now we look at the java code.

    we have 4 java classes
    1. MyAppWidgetProvider.java
    2. MyTimer.java
    3. RepeatingAlarm.java
    4. SettingsPage.java

    SettingsPage.java

    package com.coderzheaven.customfontinwidget;
    
    import android.app.Activity;
    import android.appwidget.AppWidgetManager;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.RemoteViews;
    
    public class SettingsPage extends Activity implements OnClickListener {
    
    	int thisWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    
    		getIdOfCurrentWidget(savedInstanceState);
    
    		((Button) findViewById(R.id.create_widget)).setOnClickListener(this);
    
    	}
    
    	/**
    	 * Get the Id of Current Widget from the intent from the Widget or if it is
    	 * the first time
    	 **/
    	void getIdOfCurrentWidget(Bundle savedInstanceState) {
    		setResult(RESULT_CANCELED);
    		Bundle extras = getIntent().getExtras();
    		if (extras != null) {
    			thisWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
    					AppWidgetManager.INVALID_APPWIDGET_ID);
    		}
    	}
    
    	/**
    	 * Update the widget on first run
    	 * 
    	 * @param widgetId
    	 *            - the ID of current widget to be created
    	 */
    	public void updateWidget(int widgetId) {
    		RemoteViews remoteViews = new RemoteViews(getPackageName(),
    				R.layout.widget_main);
    
    		MyTimer myTimer = new MyTimer(this);
    		Bitmap bmp = myTimer.buildUpdate(myTimer.getTodaysTime());
    		remoteViews.setImageViewBitmap(R.id.imageView_txt, bmp);
    
    		// set a background
    		remoteViews.setImageViewResource(R.id.imageView_bg, R.drawable.theme0);
    
    		AppWidgetManager appWidgetManager = AppWidgetManager
    				.getInstance(SettingsPage.this);
    		// update the widget
    		appWidgetManager.updateAppWidget(widgetId, remoteViews);
    	}
    
    	public void setResultDataToWidget(int result, int widgetId) {
    		System.out.println("WID ID = " + widgetId);
    
    		// update the widget on creation
    		updateWidget(widgetId);
    
    		// set the result back to widget
    		Intent resultValue = new Intent();
    		// pass the widget ID along with the intent so that we will get it on
    		// the cofiguration activity
    		resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
    		setResult(result, resultValue);
    		finish();
    	}
    
    	@Override
    	public void onClick(View v) {
    		if (v.getId() == R.id.create_widget)
    			setResultDataToWidget(Activity.RESULT_OK, thisWidgetId);
    	}
    
    }
    

    MyAppWidgetProvider.java

    package com.coderzheaven.customfontinwidget;
    
    import android.app.AlarmManager;
    import android.app.PendingIntent;
    import android.appwidget.AppWidgetManager;
    import android.appwidget.AppWidgetProvider;
    import android.content.Context;
    import android.content.Intent;
    import android.os.SystemClock;
    
    public class MyAppWidgetProvider extends AppWidgetProvider {
    
    	@Override
    	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
    			int[] appWidgetIds) {
    
    		Intent intent = new Intent(context, RepeatingAlarm.class);
    		PendingIntent sender = PendingIntent
    				.getBroadcast(context, 0, intent, 0);
    
    		// We want the alarm to go off 1 seconds from now.
    		long firstTime = SystemClock.elapsedRealtime();
    		firstTime += 1000;
    
    		// Schedule the alarm!
    		AlarmManager am = (AlarmManager) context
    				.getSystemService(Context.ALARM_SERVICE);
    		am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, 1000,
    				sender);
    
    	}
    }
    

    MyTimer.java

    package com.coderzheaven.customfontinwidget;
    
    import java.util.Calendar;
    
    import android.appwidget.AppWidgetManager;
    import android.content.ComponentName;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Paint.Align;
    import android.graphics.Typeface;
    import android.widget.RemoteViews;
    
    public class MyTimer {
    	RemoteViews remoteViews;
    	Context context;
    	AppWidgetManager appWidgetManager;
    	ComponentName thisWidget;
    
    	public MyTimer(Context context) {
    
    		appWidgetManager = AppWidgetManager.getInstance(context);
    
    		this.context = context;
    
    		remoteViews = new RemoteViews(context.getPackageName(),
    				R.layout.widget_main);
    
    		thisWidget = new ComponentName(context, MyAppWidgetProvider.class);
    
    	}
    
    	public synchronized void runAndUpdateTheWidget() {
    
    		int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
    
    		for (final int appWidgetId : allWidgetIds) {
    
    			System.out.println("UPDATING......" + getTodaysTime() + " ID = "
    					+ appWidgetId);
    
    			remoteViews.setImageViewBitmap(R.id.imageView_txt,
    					buildUpdate(getTodaysTime()));
    			appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
    
    		}
    
    	}
    
    	public Bitmap buildUpdate(String time) {
    		int bmpWidth = 250;
    		int bmpHeight = 100;
    		Bitmap myBitmap = Bitmap.createBitmap(bmpWidth, bmpHeight,
    				Bitmap.Config.ARGB_8888);
    		Canvas myCanvas = new Canvas(myBitmap);
    		Paint paint = new Paint();
    		Typeface clock = Typeface.createFromAsset(context.getAssets(),
    				"digital-7.ttf");
    		paint.setAntiAlias(true);
    		paint.setSubpixelText(true);
    		paint.setTypeface(clock);
    		paint.setStyle(Paint.Style.FILL);
    		paint.setColor(Color.RED);
    		paint.setTextSize(70); 
    		paint.setTextAlign(Align.CENTER);
    		myCanvas.drawText(time, bmpWidth / 2, bmpHeight / 2 + (bmpHeight / 4),
    				paint);
    		return myBitmap;
    	}
    
    	public String getTodaysTime() {
    		final Calendar c = Calendar.getInstance();
    		int hour = Integer
    				.parseInt(convertToNormal(c.get(Calendar.HOUR_OF_DAY)));
    		int minute = c.get(Calendar.MINUTE);
    		int seconds = c.get(Calendar.SECOND);
    		return new StringBuilder().append(pad(hour)).append(":")
    				.append(pad(minute)).append(":").append(pad(seconds))
    				.toString();
    	}
    
    	private static String pad(int c) {
    		if (c >= 10)
    			return String.valueOf(c);
    		else
    			return "0" + String.valueOf(c);
    	}
    
    	public String convertToNormal(int hour) {
    		if (hour > 12)
    			hour = hour - 12;
    
    		return pad(hour);
    	}
    }
    

    And the Broadcast receiver
    RepeatingAlarm.java

    package com.coderzheaven.customfontinwidget;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    
    public class RepeatingAlarm extends BroadcastReceiver {
    	@Override
    	public void onReceive(Context context, Intent intent) {
    		MyTimer myTimer = new MyTimer(context);
    		myTimer.runAndUpdateTheWidget();
    	}
    }
    

    Your Clock widget with custom Font is complete, Go on and run it and Check in the widgets area.

    You can download the complete source code from this link.

    Please leave your valuable comments on this post. We have put a lot of effort on creating this post for you.

    Creating Dynamic table rows and colums in JQuery and removing it one by one.

    Hi all…

    Apart from Android, I am now going to post something in jquery.
    In this post I will be showing how to create a dynamic table in jquery and adding data to it using objects and also deleting each row with a remove button in the corresponding row.

    This is how it is done.

    At first you have to dowload the jquery files. I will be sharing a download link at the end of this tutorial which will have my sample code with the jquery files.

    So we will start

    This is the HTML code that does the work.
    After running this file we will get a screen like this.

    Before adding the table rows.
    Jquery Dynamic table creation

    After adding 5 rows in the table
    Jquery Dynamic table creation

    After removing 2 rows from the table.
    Jquery Dynamic table creation

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Auto Complete Input box</title>
    <link rel="stylesheet" type="text/css" href="jquery/jquery.autocomplete.css" />
    <script type="text/javascript" src="jquery/lib/jquery.js"></script>
    <script type="text/javascript" src="jquery/jquery.autocomplete.js"></script>
    <script>
    
      var itemCount = 0;
     
     $(document).ready(function(){
     
    	var objs=[];
    	var temp_objs=[];
    	
    	$( "#add_button" ).click(function() {	
    		
    		var html = "";
    		
    		var obj={
    			"ROW_ID" : itemCount,
    			"ITEM_NAME" :  $("#item_name").val(),
    			"ITEM_PRICE" : $("#item_price").val(),
    			"ITEM_QUANTITY" : $("#item_quantity").val()
    		}   
    	
    		// add object
    		objs.push(obj);
    					
    		itemCount++;
    		// dynamically create rows in the table
    		html = "<tr id='tr"+ itemCount + "'><td>"+ obj['ITEM_NAME'] + "</td> <td>" +  obj['ITEM_PRICE'] + " </td> <td>" +  obj['ITEM_QUANTITY'] + " </td><td><input type='button'  id='" + itemCount + "' value='remove'></td> </tr>";			
    		
    		//add to the table
    		$("#bill_table").append(html)
    		
    		// The remove button click
    		$("#"+itemCount).click(function() {
    			var buttonId = $(this).attr("id");
    			//write the logic for removing from the array
    			$("#tr"+ buttonId).remove();			
    		});
    		
    	});
    	
     });
     
    	
    </script>
    </head>
    <body>
    <table border='0' width='50%' align='center'  style="border-collapse:collapse " cellspacing='3' cellpadding='5'>
    <th colspan="7" bgcolor="#0099FF">Billing</th>
    <tr>
    
      	<td> Item Name : </td>
    	<td><input name="item_name" type="text" id="item_name" size="20"/></td>
    	
    	<td> Price : </td>
    	<td><input name="item_price" type="text" id="item_price" size="20"/></td>
    	
    	<td> Quantity : </td>
    	<td><input name="item_quantity" type="text" id="item_quantity" size="20"/></td>
    	
    	<td><input name="add_button" type="button" id="add_button" size="20" value="Add" /></td>
    
    
    </table>
    
    
    <div id="billing_items_div"> 
    
    <table border='1' id='bill_table'  width='50%' align='center'  style='border-collapse:collapse' cellspacing='3' cellpadding='5'>
    
    </table>
    </div>
    
    </body>
    </html>
    

    You can download the complete source code from here.

    Faster Loading images in GridViews or ListViews in Android using Menory Caching, Complete implemenation with sample code.

    Hi all

    This example shows you how to load large images in the gridview without any lag or without outofmemory error.

    Fast Grid

    This sample application uses the LruCache to hold the images.

    A cache that holds strong references to a limited number of values. Each time a value is accessed, it is moved to the head of a queue. When a value is added to a full cache, the value at the end of that queue is evicted and may become eligible for garbage collection.

    Read more from here.

    http://developer.android.com/reference/android/util/LruCache.html

    Now we will go to the implementation.

    This is the MainActivity that holds the GridView.
    We are adding here 100 images in the Grid to load.
    This time I am loading images from the resources.

    Everything is explained with in the code itself, So I am not adding more description here

    MainActivity.java

    package com.coderzheaven.testlistview;
    
    import java.util.ArrayList;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.widget.GridView;
    
    public class MainActivity extends Activity {
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    
    		super.onCreate(savedInstanceState);
    
    		ArrayList<String> items = new ArrayList<String>();
    
    		// adding 100 images
    		for (int p = 0; p < 100; p++) {
    			items.add("photo");
    		}
    
    		ListAdapter list = new ListAdapter(this, items);
    
    		GridView grid = new GridView(this);
    
    		grid.setAdapter(list);
    
    		grid.setNumColumns(GridView.AUTO_FIT);
    
    		setContentView(grid);
    
    	}
    
    }
    
    

    OK Now that our Activity is complete we will see the ListAdapter class that is processing each image and helps loading fast.

    ListAdapter.java

    package com.coderzheaven.testlistview;
    
    import java.lang.ref.WeakReference;
    import java.util.ArrayList;
    
    import android.content.Context;
    import android.content.res.Resources;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.drawable.BitmapDrawable;
    import android.graphics.drawable.Drawable;
    import android.os.AsyncTask;
    import android.util.LruCache;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.GridLayout.LayoutParams;
    import android.widget.GridView;
    import android.widget.ImageView;
    
    public class ListAdapter extends BaseAdapter {
    
    	Context context;
    	ArrayList<String> items;
    	private LruCache<String, Bitmap> mMemoryCache;
    
    	public ListAdapter(Context context, ArrayList<String> items) {
    		this.context = context;
    		this.items = items;
    
    		// Get memory class of this device, exceeding this amount will throw an
    		// OutOfMemory exception.
    		final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
    
    		// Use 1/8th of the available memory for this memory cache.
    		final int cacheSize = maxMemory / 8;
    
    		mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
    
    			protected int sizeOf(String key, Bitmap bitmap) {
    				// The cache size will be measured in bytes rather than number
    				// of items.
    				return bitmap.getByteCount();
    			}
    
    		};
    	}
    
    	@Override
    	public int getCount() {
    		return items.size();
    	}
    
    	@Override
    	public Object getItem(int arg0) {
    		return items.get(arg0);
    	}
    
    	@Override
    	public long getItemId(int arg0) {
    		return arg0;
    	}
    
    	@Override
    	public View getView(int arg0, View convertView, ViewGroup arg2) {
    		ImageView img = null;
    
    		if (convertView == null) {
    			img = new ImageView(context);
    			img.setScaleType(ImageView.ScaleType.CENTER_CROP);
    			img.setLayoutParams(new GridView.LayoutParams(
    					LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    		} else {
    			img = (ImageView) convertView;
    		}
    
    		int resId = context.getResources().getIdentifier(items.get(arg0),
    				"drawable", context.getPackageName());
    
    		loadBitmap(resId, img);
    
    		return img;
    	}
    
    	public void loadBitmap(int resId, ImageView imageView) {
    		if (cancelPotentialWork(resId, imageView)) {
    			final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
    			imageView.setBackgroundResource(R.drawable.empty_photo);
    			task.execute(resId);
    		}
    	}
    
    	static class AsyncDrawable extends BitmapDrawable {
    		private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
    
    		public AsyncDrawable(Resources res, Bitmap bitmap,
    				BitmapWorkerTask bitmapWorkerTask) {
    			super(res, bitmap);
    			bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(
    					bitmapWorkerTask);
    		}
    
    		public BitmapWorkerTask getBitmapWorkerTask() {
    			return bitmapWorkerTaskReference.get();
    		}
    	}
    
    	public static boolean cancelPotentialWork(int data, ImageView imageView) {
    		final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
    
    		if (bitmapWorkerTask != null) {
    			final int bitmapData = bitmapWorkerTask.data;
    			if (bitmapData != data) {
    				// Cancel previous task
    				bitmapWorkerTask.cancel(true);
    			} else {
    				// The same work is already in progress
    				return false;
    			}
    		}
    		// No task associated with the ImageView, or an existing task was
    		// cancelled
    		return true;
    	}
    
    	private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
    		if (imageView != null) {
    			final Drawable drawable = imageView.getDrawable();
    			if (drawable instanceof AsyncDrawable) {
    				final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
    				return asyncDrawable.getBitmapWorkerTask();
    			}
    		}
    		return null;
    	}
    
    	public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
    		if (getBitmapFromMemCache(key) == null) {
    			mMemoryCache.put(key, bitmap);
    		}
    	}
    
    	public Bitmap getBitmapFromMemCache(String key) {
    		return (Bitmap) mMemoryCache.get(key);
    	}
    
    	class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
    		public int data = 0;
    		private final WeakReference<ImageView> imageViewReference;
    
    		public BitmapWorkerTask(ImageView imageView) {
    			// Use a WeakReference to ensure the ImageView can be garbage
    			// collected
    			imageViewReference = new WeakReference<ImageView>(imageView);
    		}
    
    		// Decode image in background.
    		@Override
    		protected Bitmap doInBackground(Integer... params) {
    			data = params[0];
    			final Bitmap bitmap = decodeSampledBitmapFromResource(
    					context.getResources(), data, 100, 100);
    			addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
    			return bitmap;
    		}
    
    		// Once complete, see if ImageView is still around and set bitmap.
    		@Override
    		protected void onPostExecute(Bitmap bitmap) {
    			if (imageViewReference != null && bitmap != null) {
    				final ImageView imageView = imageViewReference.get();
    				if (imageView != null) {
    					imageView.setImageBitmap(bitmap);
    				}
    			}
    		}
    	}
    
    	public static Bitmap decodeSampledBitmapFromResource(Resources res,
    			int resId, int reqWidth, int reqHeight) {
    
    		// First decode with inJustDecodeBounds=true to check dimensions
    		final BitmapFactory.Options options = new BitmapFactory.Options();
    		options.inJustDecodeBounds = true;
    		BitmapFactory.decodeResource(res, resId, options);
    
    		// Calculate inSampleSize
    		options.inSampleSize = calculateInSampleSize(options, reqWidth,
    				reqHeight);
    
    		// Decode bitmap with inSampleSize set
    		options.inJustDecodeBounds = false;
    		return BitmapFactory.decodeResource(res, resId, options);
    	}
    
    	public static int calculateInSampleSize(BitmapFactory.Options options,
    			int reqWidth, int reqHeight) {
    		// Raw height and width of image
    		final int height = options.outHeight;
    		final int width = options.outWidth;
    		int inSampleSize = 1;
    
    		if (height > reqHeight || width > reqWidth) {
    
    			// Calculate ratios of height and width to requested height and
    			// width
    			final int heightRatio = Math.round((float) height
    					/ (float) reqHeight);
    			final int widthRatio = Math.round((float) width / (float) reqWidth);
    
    			// Choose the smallest ratio as inSampleSize value, this will
    			// guarantee
    			// a final image with both dimensions larger than or equal to the
    			// requested height and width.
    			inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    		}
    
    		return inSampleSize;
    	}
    
    }
    

    You can download the sample android source code from here.

    Please leave your comments. I will be adding a modified version of this sample for using it to download from a URL and caching it in the disk and Memory in the coming posts.

    What is a Memory Heap Size in android? and how can use Bitmap Efficiently?

    Memory Heap Size

    Android is a full multitasking system so it’s possible to run multiple programs at the same time and obviously each one can’t use all of your device memory.
    For this reason there is a hard limit on your Android application’s heap size: if your application needs to allocate more memory and you have gone up to that heap size already, you are basically going to get a “out of memory error”.
    Heap size limit is device dependent and it has changed a lot over the years, the first Android phone (the G1) has 16MB heap size limit, now we have tablets like Motorola Xoom that have 48MB heap size limit.
    The basic reason is that new tablets and new phones have an high monitor resolution so they need more memory in order to draw more pixels.
    However this limit is also too tight for a new kind of application that you can image for a tablet. For example, think about a photo editor that is really memory intensive, probably 48MB of heap space isn’t enough for that.
    For that kind of application Honeycomb introduced an option in the Android Manifest: “android:largeHeap=true” that give you a big heap space limit.”
    This doesn’t mean that if you get an “out of memory error” you can fix it simply setting this option!
    You have to use this option only if you are going to build an application that is really memory intensive and you really need it.
    When you develop an application you have to think that your application will run on a very large set of different devices with different capability and different heap size limit, so you need to worry about that and a simple thing you can do it’s provide your bitmap resources in all the different resolution ldpi, mdpi, hdpi, xhdpi.

    Handle bitmap efficiently

    If you’re not careful, bitmaps can quickly consume your available memory budget leading to an application crash due to the dreaded exception: “java.lang.OutofMemoryError: bitmap size exceeds VM budget”.

    Images come in all shapes and sizes. In many cases they are larger than required for a typical application user interface (UI).
    Given that you are working with limited memory, the best thing that you can do is to load a lower resolution version into the memory. The lower resolution version should match the size of the UI component that displays it. An image with an higher resolution does not provide any visible benefit, but still takes up precious memory and incurs additional performance overhead due to additional on the fly scaling.
    The BitmapFactory class provides several decoding methods (decodeByteArray(), decodeFile(),decodeResource(), etc.) for creating a Bitmap from various sources.
    Each type of decode method has additional signatures that let you specify the decoding options via BitmapFactory.Options class.
    Setting the inJustDecodeBounds property to true while decoding avoids memory allocation, returning null for the bitmap object but setting outWidth, outHeight and outMimeType. This technique allows you to read the dimensions and type of the image data before the construction (and memory allocation) of the bitmap.
    Now that the image dimensions are known, they can be used to decide if we should load the full image or a subsampled version, into the memory. To tell the decoder to subsample the image, loading a smaller version into memory, set inSampleSize to the scale factor in your BitmapFactory.Options object.
    The code below shows how to load an Image of arbitrarily large size to a bitmap of the reqWidth and reqHeight.
    The calcualteInSampleSize just determinates the scale factor from the original size and the requested size.

    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
            int reqWidth, int reqHeight) {
        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
     
        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
     
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }
    

    References:

    http://android-developers.blogspot.it/2011/03/memory-analysis-for-android.html

    http://android-developers.blogspot.it/2009/01/avoiding-memory-leaks.html

    http://developer.android.com/training/displaying-bitmaps/index.html

    FlipCard animation using Fragments in Android.

    Hello all

    I am back with fragments again. I know you have seen a lot of posts on fragments and fragment animation.

    This one will be another useful post for you.

    This post helps you to show a FlipCard animation using Fragments.

    Let us see how can we do this.

    At first I will show the activity that I am using to create Animation which contain two fragments for Front and Back Page.

    CardFlipActivity.java

    
    package com.example.cardflipanimation;
    
    import android.app.Activity;
    import android.app.Fragment;
    import android.app.FragmentManager;
    import android.content.Intent;
    import android.os.Bundle;
    import android.os.Handler;
    import android.support.v4.app.NavUtils;
    import android.view.LayoutInflater;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    
    public class CardFlipActivity extends Activity implements
    		FragmentManager.OnBackStackChangedListener {
    	/**
    	 * A handler object, used for deferring UI operations.
    	 */
    	private Handler mHandler = new Handler();
    
    	/**
    	 * Whether or not we're showing the back of the card (otherwise showing the
    	 * front).
    	 */
    	private boolean mShowingBack = false;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_card_flip);
    
    		if (savedInstanceState == null) {
    			// If there is no saved instance state, add a fragment representing
    			// the
    			// front of the card to this activity. If there is saved instance
    			// state,
    			// this fragment will have already been added to the activity.
    			getFragmentManager().beginTransaction()
    					.add(R.id.container, new CardFrontFragment()).commit();
    		} else {
    			mShowingBack = (getFragmentManager().getBackStackEntryCount() > 0);
    		}
    
    		// Monitor back stack changes to ensure the action bar shows the
    		// appropriate
    		// button (either "photo" or "info").
    		getFragmentManager().addOnBackStackChangedListener(this);
    	}
    
    	@Override
    	public boolean onCreateOptionsMenu(Menu menu) {
    		super.onCreateOptionsMenu(menu);
    
    		// Add either a "photo" or "finish" button to the action bar, depending
    		// on which page
    		// is currently selected.
    		MenuItem item = menu.add(Menu.NONE, R.id.action_flip, Menu.NONE,
    				mShowingBack ? R.string.action_photo : R.string.action_info);
    		item.setIcon(mShowingBack ? R.drawable.ic_action_photo
    				: R.drawable.ic_action_info);
    		item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
    		return true;
    	}
    
    	@Override
    	public boolean onOptionsItemSelected(MenuItem item) {
    		switch (item.getItemId()) {
    		case android.R.id.home:
    			// Navigate "up" the demo structure to the launchpad activity.
    			// See http://developer.android.com/design/patterns/navigation.html
    			// for more.
    			NavUtils.navigateUpTo(this,
    					new Intent(this, CardFlipActivity.class));
    			return true;
    
    		case R.id.action_flip:
    			flipCard();
    			return true;
    		}
    
    		return super.onOptionsItemSelected(item);
    	}
    
    	private void flipCard() {
    		if (mShowingBack) {
    			getFragmentManager().popBackStack();
    			return;
    		}
    
    		// Flip to the back.
    
    		mShowingBack = true;
    
    		// Create and commit a new fragment transaction that adds the fragment
    		// for the back of
    		// the card, uses custom animations, and is part of the fragment
    		// manager's back stack.
    
    		getFragmentManager().beginTransaction()
    
    		// Replace the default fragment animations with animator resources
    		// representing
    		// rotations when switching to the back of the card, as well as animator
    		// resources representing rotations when flipping back to the front
    		// (e.g. when
    		// the system Back button is pressed).
    				.setCustomAnimations(R.animator.card_flip_right_in,
    						R.animator.card_flip_right_out,
    						R.animator.card_flip_left_in,
    						R.animator.card_flip_left_out)
    
    				// Replace any fragments currently in the container view with a
    				// fragment
    				// representing the next page (indicated by the just-incremented
    				// currentPage
    				// variable).
    				.replace(R.id.container, new CardBackFragment())
    
    				// Add this transaction to the back stack, allowing users to
    				// press Back
    				// to get to the front of the card.
    				.addToBackStack(null)
    
    				// Commit the transaction.
    				.commit();
    
    		// Defer an invalidation of the options menu (on modern devices, the
    		// action bar). This
    		// can't be done immediately because the transaction may not yet be
    		// committed. Commits
    		// are asynchronous in that they are posted to the main thread's message
    		// loop.
    		mHandler.post(new Runnable() {
    			@Override
    			public void run() {
    				invalidateOptionsMenu();
    			}
    		});
    	}
    
    	@Override
    	public void onBackStackChanged() {
    		mShowingBack = (getFragmentManager().getBackStackEntryCount() > 0);
    
    		// When the back stack changes, invalidate the options menu (action
    		// bar).
    		invalidateOptionsMenu();
    	}
    
    	/**
    	 * A fragment representing the front of the card.
    	 */
    	public static class CardFrontFragment extends Fragment {
    		public CardFrontFragment() {
    		}
    
    		@Override
    		public View onCreateView(LayoutInflater inflater, ViewGroup container,
    				Bundle savedInstanceState) {
    			return inflater.inflate(R.layout.fragment_card_front, container,
    					false);
    		}
    	}
    
    	/**
    	 * A fragment representing the back of the card.
    	 */
    	public static class CardBackFragment extends Fragment {
    		public CardBackFragment() {
    		}
    
    		@Override
    		public View onCreateView(LayoutInflater inflater, ViewGroup container,
    				Bundle savedInstanceState) {
    			return inflater.inflate(R.layout.fragment_card_back, container,
    					false);
    		}
    	}
    }
    

    Now the animations.
    For that you have to create 4 xml animation files in the res/animator folder.

    card_flip_left_in.xml
    card_flip_left_out.xml
    card_flip_right_in.xml
    card_flip_right_out.xml

    I will be listing these files in this order.

    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- Before rotating, immediately set the alpha to 0. -->
        <objectAnimator
            android:valueFrom="1.0"
            android:valueTo="0.0"
            android:propertyName="alpha"
            android:duration="0" />
    
        <!-- Rotate. -->
        <objectAnimator
            android:valueFrom="-180"
            android:valueTo="0"
            android:propertyName="rotationY"
            android:interpolator="@android:interpolator/accelerate_decelerate"
            android:duration="@integer/card_flip_time_full" />
    
        <!-- Half-way through the rotation (see startOffset), set the alpha to 1. -->
        <objectAnimator
            android:valueFrom="0.0"
            android:valueTo="1.0"
            android:propertyName="alpha"
            android:startOffset="@integer/card_flip_time_half"
            android:duration="1" />
    </set>
    
    
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- Rotate. -->
        <objectAnimator android:valueFrom="0"
            android:valueTo="180"
            android:propertyName="rotationY"
            android:interpolator="@android:interpolator/accelerate_decelerate"
            android:duration="@integer/card_flip_time_full"></objectAnimator>
    
        <!-- Half-way through the rotation (see startOffset), set the alpha to 0. -->
        <objectAnimator android:valueFrom="1.0"
            android:valueTo="0.0"
            android:propertyName="alpha"
            android:startOffset="@integer/card_flip_time_half"
            android:duration="1"></objectAnimator>
    </set>
    
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- Before rotating, immediately set the alpha to 0. -->
        <objectAnimator
            android:valueFrom="1.0"
            android:valueTo="0.0"
            android:propertyName="alpha"
            android:duration="0" />
    
        <!-- Rotate. -->
        <objectAnimator
            android:valueFrom="180"
            android:valueTo="0"
            android:propertyName="rotationY"
            android:interpolator="@android:interpolator/accelerate_decelerate"
            android:duration="@integer/card_flip_time_full" />
    
        <!-- Half-way through the rotation (see startOffset), set the alpha to 1. -->
        <objectAnimator
            android:valueFrom="0.0"
            android:valueTo="1.0"
            android:propertyName="alpha"
            android:startOffset="@integer/card_flip_time_half"
            android:duration="1" />
    </set>
    
    
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- Rotate. -->
        <objectAnimator
            android:valueFrom="0"
            android:valueTo="-180"
            android:propertyName="rotationY"
            android:interpolator="@android:interpolator/accelerate_decelerate"
            android:duration="@integer/card_flip_time_full" />
    
        <!-- Half-way through the rotation (see startOffset), set the alpha to 0. -->
        <objectAnimator
            android:valueFrom="1.0"
            android:valueTo="0.0"
            android:propertyName="alpha"
            android:startOffset="@integer/card_flip_time_half"
            android:duration="1" />
    </set>
    
    

    Inside the drawable folder put these images.

    ic_action_info.png
    ic_action_photo.png
    image1.png

    Put these inside the ids.xml folder inside the res/values folder.

        <item type="id" name="action_next" />
        <item type="id" name="action_flip" />
    

    strings.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <string name="app_name">CardFlipAnimation</string>
        <string name="hello_world">Hello world!</string>
        <string name="menu_settings">Settings</string>
        <string name="action_info">Photo info</string>
        <string name="action_photo">View photo</string>
    
    </resources>
    

    And also integers.xml

    <resources>
        <integer name="card_flip_time_full">300</integer>
        <integer name="card_flip_time_half">150</integer>
    </resources>
    

    Download the complete android source code from here.

    Process lifecycle in Android and Different types of processes.

    The Android system tries to maintain an application process for as long as possible, but eventually needs to remove old processes to reclaim memory for new or more important processes. To determine which processes to keep and which to kill, the system places each process into an “importance hierarchy” based on the components running in the process and the state of those components. Processes with the lowest importance are eliminated first, then those with the next lowest importance, and so on, as necessary to recover system resources.

    There are five levels in the importance hierarchy. The following list presents the different types of processes in order of importance (the first process is most important and is killed last ):

    Foreground process A process that is required for what the user is currently doing. A process is considered to be in the foreground if any of the following conditions are true:

    It hosts an Activity that the user is interacting with (the Activity ‘s onResume() method has been called).

    It hosts a Service that’s bound to the activity that the user is interacting with.

    It hosts a Service that’s running “in the foreground”—the service has called startForeground() .

    It hosts a Service that’s executing one of its lifecycle callbacks ( onCreate() , onStart() , or onDestroy() ).

    It hosts a BroadcastReceiver that’s executing its onReceive() method.

    Generally, only a few foreground processes exist at any given time. They are killed only as a last resort—if memory is so low that they cannot all continue to run. Generally, at that point, the device has reached a memory paging state, so killing some foreground processes is required to keep the user interface responsive.

    Visible process A process that doesn’t have any foreground components, but still can affect what the user sees on screen. A process is considered to be visible if either of the following conditions are true:

    It hosts an Activity that is not in the foreground, but is still visible to the user (its onPause() method has been called). This might occur, for example, if the foreground activity started a dialog, which allows the previous activity to be seen behind it.

    It hosts a Service that’s bound to a visible (or foreground) activity.

    A visible process is considered extremely important and will not be killed unless doing so is required to keep all foreground processes running.

    Service process A process that is running a service that has been started with the startService() method and does not fall into either of the two higher categories. Although service processes are not directly tied to anything the user sees, they are generally doing things that the user cares about (such as playing music in the background or downloading data on the network), so the system keeps them running unless there’s not enough memory to retain them along with all foreground and visible processes.

    Background process A process holding an activity that’s not currently visible to the user (the activity’s onStop() method has been called). These processes have no direct impact on the user experience, and the system can kill them at any time to reclaim memory for a foreground, visible, or service process. Usually there are many background processes running, so they are kept in an LRU (least recently used) list to ensure that the process with the activity that was most recently seen by the user is the last to be killed. If an activity implements its lifecycle methods correctly, and saves its current state, killing its process will not have a visible effect on the user experience, because when the user navigates back to the activity, the activity restores all of its visible state.

    Empty process A process that doesn’t hold any active application components. The only reason to keep this kind of process alive is for caching purposes, to improve startup time the next time a component needs to run in it. The system often kills these processes in order to balance overall system resources between process caches and the underlying kernel caches.

    Android ranks a process at the highest level it can, based upon the importance of the components currently active in the process. For example, if a process hosts a service and a visible activity, the process is ranked as a visible process, not a service process.

    In addition, a process’s ranking might be increased because other processes are dependent on it—a process that is serving another process can never be ranked lower than the process it is serving. For example, if a content provider in process A is serving a client in process B, or if a service in process A is bound to a component in process B, process A is always considered at least as important as process B.

    Because a process running a service is ranked higher than a process with background activities, an activity that initiates a long-running operation might do well to start a service for that operation, rather than simply create a worker thread—particularly if the operation will likely outlast the activity. For example, an activity that’s uploading a picture to a web site should start a service to perform the upload so that the upload can continue in the background even if the user leaves the activity. Using a service guarantees that the operation will have at least “service process” priority, regardless of what happens to the activity. This is the same reason that broadcast receivers should employ services rather than simply put time-consuming operations in a thread.

    How to write multilingual Android apps?

    To build multilingual Android apps you need to collect the texts into resource files and translate them.

    Once you provide the translation, Android OS will choose the resources that match user’s locale. If your application is available in several languages, Android will select the language that the device uses.

    In this tutorial, we’ll cover:

    • Application localization process
    • Translating strings
    • Localizing images
    • Running and testing the localized application

    In order to have a multilingual Android app you need to provide Android with the localized resource files.

    If the locale is ‘en-US’, Android will look for a value of “R.string.title” by searching the files in the following order:

  • ‘res/values-en-rUS/strings.xml’
  • ‘res/values-en/strings.xml’
  • ‘res/values/strings.xml’

  • Translating Strings

    For example if an application requires four strings.xml files, one for each in English, Italian, French, and Russian.

    The procedure for creating strings.xml files is as follows:

    • Translate the strings.xml file to each language
    • Create three new folders under res – values-it, values-fr and values-ru (The original values folder already exists).
    • Place the translated strings.xml files in the respective folders.

    Localizing Images

    If our application also needs six more drawable folders, each containing a variant of the background image.

    Place background image that has to appear for a respective language in corresponding folders under the project workspace of the application as specified in below Table.

    If your images contain texts, we recommend creating copies of the texts in your strings.xml file. This way, translators can translate just the texts, and you can rebuild the localized images.

    Background image Destination folder in project workspace
    Italian drawable-it-rIT/background.png
    French drawable-fr-rFR/background.png
    French (Canada) drawable-fr-rCA/background.png
    English (Canada) drawable-en-rCA/background.png
    Russian drawable-ru-rRU/background.png
    US English drawable-en-rUS/background.png
    Default (Earth image) drawable/background.png

    Running and Testing the Localized Application

    Once the localized string and image resources are added to the project workspace, the application is ready for testing. To test it, we can set different locales via Home > Menu > Settings > Locale & text > Select locale.

    Depending on configuration of the device, some devices may offer only a few locales or may not offer any alternate locales via the settings application. However, the Android emulator will offer a selection of all the locales that are available in Android OS. To set the emulator to a locale that is not available in the system image, you can use Custom Locale, available in the Application tab.

    Hope you enjoyed this post, Please leave a comment at the end.