Sunday, 7 January 2018

Saturday, 7 May 2016

Android : Service Example(Started Service, Bind Service, Bind Service Using AIDL, IntentService with Broadcast, IntentService with ResultReceiver)


Adding sample App to demonstrate different types of Services in Android.

Below example demonstrate following types of services in Android.


  • Started Service
  • Bound Service(In Same App)
  • Bound Service(Across The Application Using AIDL aka InterProcessCommunication)
  • IntentService(Return Data Using BroadcastReceiver)
  • IntentService(Return Data Using ResultReceiver) 

StartedService:
  • A service is started when any App component(Activity in our case) starts it by calling startService().
  • Started services cannot return results/values or interact with its starting component.
  • If we want to execute long running task in started service we need to create new Thread inside it otherwise app can face crashes or may hang UI as long as task is executing.
  • Started service can run indefinitely in background even if the component that started(Activity-In our case) it is destroyed.
USE : This type of service can be use to download/upload data in background which can be use later in our application like download images which can be displayed on ListView or any other UI component.


Bound Service(In Same App):
  • A service is "bound" when an application component binds to it by calling bindService().
  • This type of service can be used when Staring component(Activity-In our case) want to interact with service.
  • A Bound service provides client-server interface that allows components to interact with the service, send requests, get results and even do so across processes with Inter-Process-Communication (IPC).
  • A bound service runs only as long as another application component is bound to it. Multiple components can bind to the service at once, but when all of them unbind, the service is destroyed.
  • Bound service can be used in multi threaded environment it can handle multiple request simultaneously.  
USE : This type of service can be used when we want to communicate with service from application component(like Activity) for example we can upload data in background using service and we can call its public function to check uploading status and display it on UI.


Bound Service(AIDL):
  • This is also a bound service the main difference is in our implementation.... in above case we are calling same app service from same app component(Activity) and in case of AIDL service we can call one App's service from other App's component(Activity).
  • We can communicate across the application(InterProcessCommunication) using AIDL.
  • If we want to make our service private so that other application can not bind to our service we can put android:exported="false" in manifest in service node.

USE : AIDL service can be use to create Utility app where we can provide some common functionalities which can be access by different applications.


IntentService:
  • IntentService is subclass of Service class. IntentService runs on Worker-Thread so we dont have to create new Thread inside it to execute long running task like Service.
  • IntentService maintain queue of request if any request is executing and you send another request this request will wait till the first request is finish.
  • IntentService is not useful when you are working in multi-threaded environment.
  • There is no direct way to interact with UI component from IntentService but we can implement BroadcastReceiver and ResultReceiver for communicating with Activity.
USE : IntentService can be used to execute some task in background and at the same time we can get its result on Activity using BroadcastReceiver and ResultReceiver.

                           
                                                     Service Demo App Screenshot


AIDL Server App Screenshot


For more detail please download App source code from below URL:


You can download demo code from below URL:

Service Demonstration App URL:

AIDL Server App URL:



Saturday, 30 May 2015

Android : Extract BARCODE/QRCODE data from locally stored(SD Card) images.


Adding demo here to extract BARCODE/QRCODE data from images, images which are stored in local storage or SD card.


  • Barcode 
  • ZXing
  • Image Picker





First of all you need to download ZXing Core library from maven, below is the URL to download latest ZXing core library.


While creating this post core-3.2.0.jar was latest version. Add this jar in libs folder of your Android project.


We are picking images from gallery using intent and using "bitmap data of image"  to extract barcode/qrcode  result.


Actual code to extract data from bitmap image is given below. 


public Result[] decode(Bitmap imageBitmap) {

MultiFormatReader reader = null;
Map<DecodeHintType, Object> hints = new EnumMap<DecodeHintType, Object>(DecodeHintType.class);
/* There are different format to create barcode and qrcode, 
* while extracting we are adding all the possible format for better result. 
*/
hints.put(DecodeHintType.POSSIBLE_FORMATS, EnumSet.allOf(BarcodeFormat.class));
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);

reader = new MultiFormatReader();
reader.setHints(hints);

int width = imageBitmap.getWidth();
int height = imageBitmap.getHeight();
int[] pixels = new int[width * height];
imageBitmap.getPixels(pixels, 0, width, 0, 0, width, height);

RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

MultipleBarcodeReader multiReader = new GenericMultipleBarcodeReader(reader);
Result[] theResults = null;
try {
/* decode multiple is used so that if multiple barcode is present in single image we can get result for all of them. 
*/
theResults = multiReader.decodeMultiple(bitmap, hints);
} catch (NotFoundException e1) {
e1.printStackTrace();
}

return theResults;
}


You can download demo code from below url:




Saturday, 21 March 2015

Android: ListView with Filterable List and Animation



Adding demo here to create ListView with Filterable List.


  • ListView
  • Filterable Interface
  • Animation ListView






For adding filterable ListView we have to implement Filterable interface in our Adapter class.
And define getFilter() method of this interface.


For Example:


@Override
public Filter getFilter() {

return new Filter() {

@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
/*
*Notify listview to populate new list after filtering
*/
notifyDataSetChanged();
}

/* (non-Javadoc)
* constraint : String to filter result
* return  FilterResults to populate on listview
*/
@Override
protected FilterResults performFiltering(CharSequence constraint) {
/*
*Here we will get string to filter result from current list.
*We can create new result data to populate on listview. 
*/
                  return resultData;
}
};
}


For adding animation into ListView we have to create animation xml and put it into anim folder inside res directory 
Now we can add this animation into ListView using below code:

listView.setAnimation(AnimationUtils.loadAnimation(LauncherActivity.this, R.anim.alpha));


For detail download example and see inline comment.

You can download demo code from below url:



Sunday, 28 December 2014

Android: Custom theme in android application.


Adding demo here to create custom theme in Android application and applying it.


  • Custom Theme
This is a very simple demo app to create custom theme in android application.

First create two xml files in values folder...
attrs.xml
themes.xml

In attrs.xml file you will define all the attributes we are going to use as a theme style.
e.g:
<resources>
    <attr name="pageBackground" format="reference" />
</resources>



In themes.xml file we will differentiate this attribute according to our themes.
e.g:
<resources>

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

    <style name="Theme.Red">
        <item name="launcherBackground">@style/launcher_background_red</item>
    </style>

    <style name="Theme.Green">
        <item name="launcherBackground">@style/launcher_background_green</item>
    </style>

    <style name="Theme.Blue">
        <item name="launcherBackground">@style/launcher_background_blue</item>
    </style>
</resources>



In styles.xml file we will define actual implementation of different themes and set different property and its value accordingly.

<resources xmlns:android="http://schemas.android.com/apk/res/android">

<!-- Red Theme Start -->
<style name="launcher_background_red">
  <item name="android:background">@drawable/images_1</item>
  </style>
<!-- Red Theme End -->


<!-- Green Theme Start -->
<style name="launcher_background_green">
  <item name="android:background">@drawable/images_2</item>
  </style>
<!-- Green Theme End -->


<!-- Blue Theme Start -->
<style name="launcher_background_blue">
  <item name="android:background">@drawable/images_3</item>
  </style>
<!-- Blue Theme End -->

</resources>




Style:
After adding themes we can set style in our xml layout property like below:::
style="?launcherBackground" // We have added this as attribute in attrs.xml
e.g:

<RelativeLayout style="?launcherBackground">
</RelativeLayout>



Applying Theme:
Now for applying theme in our application we have to set theme in activities like below:::
setTheme(R.style.Theme_Red);

I have added one BaseActivity so that when we will change theme in BaseActivity it will reflect to all the child activities.


We have added theme setting in preference so that when user will relaunch application, application will show in previously selected theme.



You can download demo code from below url:
https://drive.google.com/file/d/0B0mH97AUwQqhclhSdkgtajhGVkU/view?usp=sharing




Saturday, 20 September 2014

Android: Sending broadcast message within Application and Across the application.


Adding demo here to send broadcast message within application and across the application.


  • BroadcastReceiver
  • Sending bundle to BroadcastReceiver
  • sendStickyBroadcast
  • Calling actvity method from BroadcastReceiver

We are going to add two project one for sending broadcast to its own and also to other app and other one will only receive broadcast.
  • SendBroadcast
  • ReceiveBroadcast


We can register broadcast in manifest and also in activty class. We are going to register broadcast in onResume method of activity. Because we are going to call public method of this activity from broadcast receiver. 


        @Override
protected void onResume() {
/**
* Registering only this two BroadcastReceiver so that we will get update for only this two                      broadcast. 
* */
IntentFilter toOwnAppFilter = new IntentFilter("com.send.broadcast.ToOwnApp");
toOwnAppReceiver = new BroadcastReceiverToOwnApp();
registerReceiver(toOwnAppReceiver, toOwnAppFilter);
IntentFilter toBothAppFilter = new IntentFilter("com.send.broadcast.ToBothApp");
toBothAppReceiver = new BroadcastReceiverToBothApp();
registerReceiver(toBothAppReceiver, toBothAppFilter);
super.onResume();
}

We have to unregister this broadcast in pause method.

@Override
protected void onPause() {
/**
* Unregister broadcast receiver when activity pause 
* */
unregisterReceiver(toOwnAppReceiver);
unregisterReceiver(toBothAppReceiver);
super.onPause();
}


Full Activity Code is Below:::::::::::::::::::::

package com.send.broadcast;

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

/**
 * @author dipenp
 *
 */
public class SendBroadcastActivity extends Activity {

BroadcastReceiverToOwnApp toOwnAppReceiver;
BroadcastReceiverToBothApp toBothAppReceiver;
public static String EXTRA = "extra";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_send_broadcast);
findViewById(R.id.sendBroadcastToOwnApp).setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("com.send.broadcast.ToOwnApp");
intent.putExtra(EXTRA, "To Own App");
// sendStickyBroadcast(intent);
sendBroadcast(intent);
}
});
findViewById(R.id.sendBroadcastToOtherApp).setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("com.example.ToOtherApp");
intent.putExtra(EXTRA, "To Other App");
sendStickyBroadcast(intent);//Sending sticky intent so that Receiver app can get this intent when it will register this BroadcastReceiver
// sendBroadcast(intent);
}
});
findViewById(R.id.sendBroadcastToBothApp).setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("com.send.broadcast.ToBothApp");
intent.putExtra(EXTRA, "To Both App");
sendStickyBroadcast(intent);//Sending sticky intent so that Receiver app can get this intent when it will register this BroadcastReceiver
// sendBroadcast(intent);
}
});
}

@Override
protected void onResume() {
/**
* Registering only this two BroadcastReceiver so that we will get update for only this two broadcast. 
* */
IntentFilter toOwnAppFilter = new IntentFilter("com.send.broadcast.ToOwnApp");
toOwnAppReceiver = new BroadcastReceiverToOwnApp();
registerReceiver(toOwnAppReceiver, toOwnAppFilter);
IntentFilter toBothAppFilter = new IntentFilter("com.send.broadcast.ToBothApp");
toBothAppReceiver = new BroadcastReceiverToBothApp();
registerReceiver(toBothAppReceiver, toBothAppFilter);
super.onResume();
}
@Override
protected void onPause() {
/**
* Unregister broadcast receiver when activity pause 
* */
unregisterReceiver(toOwnAppReceiver);
unregisterReceiver(toBothAppReceiver);
super.onPause();
}

/**
* Adding public method which we will call from broadcast receiver class.
* It is possible only when we will register broadcast from this activity. 
*/
public void makeToast() {
Toast.makeText(getApplicationContext(), "Calling activity from Broadcast.", Toast.LENGTH_LONG).show();
}
}

Broadcast Receiver Code is Below:::::::::::

package com.send.broadcast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

/**
 * @author dipenp
 *
 */
public class BroadcastReceiverToOwnApp extends BroadcastReceiver {
@Override
public void onReceive(Context arg0, Intent arg1) {
Toast.makeText(arg0, "BroadcastReceiverToOwnApp :: "+arg1.getExtras().getString(SendBroadcastActivity.EXTRA), Toast.LENGTH_LONG).show();
/**
* Calling activity method from broadcast receiver.
* Only possible if this broadcast is register from this activity.*/
try {
((SendBroadcastActivity)arg0).makeToast();
} catch (ClassCastException e) {
}
}
}

You can download demo code from below urls:
SendBroadcast: 

ReceiveBroadcast:

Friday, 29 August 2014

Android: Fragment demo to Add & Replace fragment, Different UI for different orientation.

Please visit my website for latest post about the difference between Add & Replace method and use of Back Stack.

http://dipenpatel.co.in/understanding-android-fragmentsadd-replace-method-and-back-stack/




Adding here Fragment demo which "Add" & "Replace" fragment in fragment holder.

Adding demo app for::

  • Fragment
  • Add & Replace fragment
  • Different UI for different orientation
  • Maintaining BackStack of Fragment






                           1. Portrait UI                                        2. Lanscape UI

We will add different layout xml in different layout folder "layout" & "layout-land" to render differently on different orientation.

There are two Fragment & two Button, first button will "Replace" first fragment container and second button will "Add" fragment in second fragment container.

When we "Replace" fragment it will detach existing fragment and "Add" new fragment.
When we "Add" fragment it will add new fragment and existing fragment remain same.

We can maintain back stack of fragment which can be accessible later.
  /**
   * We can add name to this back stack and we can access this fragment by name later.
     Otherwise we can pass null to parameter*/
    fragmentTwoTransaction.addToBackStack(null);  

Note:
I have added every fragment method name in StringBuilder when this method execute and Toast this StringBuilder onDetach of fragment. You can uncomment the Toast line in onDetach method and check fragment lifecycle.

About Code:::

LauncherActivity.java

/**
 * @author dipenp
 *
 */
public class LauncherActivity extends Activity {

private Button replaceFragmentButton, addFragmentButton;
private static int FRAGMENT_ONE_POSITION = 0, FRAGMENT_TWO_POSITION = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

/**************************************************
* Adding layout with two Button & two Fragment.
* One button to "Replace" fragment in first fragment & one button to "Add" fragment in second fragment.
* We have added same layout with different structure in different folder one in layout & one in layout-land(to display when device in landscape mode)
**************************************************/
setContentView(R.layout.activity_launcher);

replaceFragmentButton = (Button)findViewById(R.id.buttonOne);
addFragmentButton = (Button)findViewById(R.id.buttonTwo);

/**
* When we click on this button it will "Replace" existing fragment and add new one.
*/
replaceFragmentButton.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
FragmentTransaction fragmentOneTransaction = getFragmentManager().beginTransaction();

switch (FRAGMENT_ONE_POSITION) {
case 0:
FRAGMENT_ONE_POSITION++;
fragmentOneTransaction.replace(R.id.fragment_one_holder, new FragmentOne(LauncherActivity.this));
break;
case 1:
FRAGMENT_ONE_POSITION++;
fragmentOneTransaction.replace(R.id.fragment_one_holder, new FragmentTwo(LauncherActivity.this));
break;
case 2:
FRAGMENT_ONE_POSITION = 0;
fragmentOneTransaction.replace(R.id.fragment_one_holder, new FragmentThree(LauncherActivity.this));
break;
default:
break;
}

// fragmentOneTransaction.addToBackStack(null);
fragmentOneTransaction.commit();
}
});


/**
* When we click on this button it will "Add" new fragment.
*/
addFragmentButton.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
FragmentTransaction fragmentTwoTransaction = getFragmentManager().beginTransaction();

switch (FRAGMENT_TWO_POSITION) {
case 0:
FRAGMENT_TWO_POSITION++;
fragmentTwoTransaction.add(R.id.fragment_two_holder, new FragmentOne(LauncherActivity.this));
break;
case 1:
FRAGMENT_TWO_POSITION++;
fragmentTwoTransaction.add(R.id.fragment_two_holder, new FragmentTwo(LauncherActivity.this));
break;
case 2:
FRAGMENT_TWO_POSITION = 0;
fragmentTwoTransaction.add(R.id.fragment_two_holder, new FragmentThree(LauncherActivity.this));
break;
default:
break;
}

/**
* Adding current fragment to back stack which can be pop back when we need.
* We can add name to this back stack and we can access this fragment by name later.
*/
fragmentTwoTransaction.addToBackStack(null);
fragmentTwoTransaction.commit();
}
});
}

/**************************************
* Overriding onBackPressed button and pop backStack fragment.
*
**************************************/
@Override
public void onBackPressed() {
FragmentManager fm = getFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
} else {
super.onBackPressed();
}
}

}

You can download demo code from below url:
https://drive.google.com/file/d/0B0mH97AUwQqhMXVkc0N6VkY0cGM/edit?usp=sharing