Monday, 21 February 2022

AsyncTask Alternative using Executor & Handler

Adding a sample to demonstrate how to create AsyncTask replacement with Executor & Handler.

AsyncTask is deprecated and it is suggested to use Kotlin coroutines instead.

https://developer.android.com/reference/android/os/AsyncTask


The other alternative is suggested to use Executor and Handler which is kind of same as using AsyncTask and should be avoided but in case somebody want to use it they can implement it like below.

Executor executor = Executors.newSingleThreadExecutor(); 
Handler handler = new Handler(Looper.getMainLooper());

//Run any main thread task like launching progress bar
...
executor.execute(() -> {
        //Do some background operation here(e.g fetching data from server etc)     
        ...
        handler.post(() -> {
         //Do some main thread operation like stopping progress bar or updating UI with fecthed data 
         ...
        });
    }); 

I have implemented little bit generic way to do the above operation and instead of writing Executors and Handler everytime we can use the below class and also we can specify the response type of doInBackground.

public class CustomAsyncTask<ResponseType> {
    private final AsyncTaskCallback<ResponseType> asyncTaskCallback;
    private final ExecutorService executor;
    private final Handler handler;

    interface AsyncTaskCallback<ResponseType> {
        //Call it before executing background task
        void onPreExecute();

        //Execute background thread and call the below method
        ResponseType doInBackground();

        //Once the background thread finishes call this method on main thread
        void onPostExecute(ResponseType result);
    }

    public CustomAsyncTask(AsyncTaskCallback<ResponseType> asyncTaskCallback) {
        this.asyncTaskCallback = asyncTaskCallback;

        executor = Executors.newSingleThreadExecutor();
        handler = new Handler(Looper.getMainLooper());
    }

    public void execute() {
        //Executing on caller thread(Assuming that user is calling CustomAsyncTask on main thread)
        asyncTaskCallback.onPreExecute();

        executor.execute(() -> {
            //Background work here
            ResponseType res = asyncTaskCallback.doInBackground();

            //Execute on main thread
            handler.post(() -> {
                //UI Thread work here
                asyncTaskCallback.onPostExecute(res);
            });
        });
    }
}

We can call the above class like below, We can specify the return type while initializing class and it will provide type safety for doInBackground result.

new CustomAsyncTask<String>(new CustomAsyncTask.AsyncTaskCallback<String>() {
                @Override
                public void onPreExecute() {
                    
                }

                @Override
                public String doInBackground() {
                    return null;
                }

                @Override
                public void onPostExecute(String result) {

                }
            }).execute();


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

https://github.com/dipenptl1/asynctask-replacement-java

Thursday, 17 February 2022

Android : Contact picker using registerForActivityResult

Adding sample to demonstrate registerForActivityResult use for accessing CONTACT from device contact list.

Previously we were able to pick contact from device contact list using startActivityForResult, but startActivityForResult is deprecated now, instead google suggest to use registerForActivityResult. 

https://developer.android.com/training/basics/intents/result


We can open contact list and retrieve the URI of selected contact using below code.

private val resultLauncher =
    registerForActivityResult(ActivityResultContracts.PickContact()) { uri ->
        uri?.let {
            Log.d(TAG, "Selected contact URI: $uri")
            binding.contactResultTv.text = retrievePhoneNumber(uri)
        }
    }
resultLauncher.launch(null)

We can retrieve actual contact from URI using below function.

@SuppressLint("Range")
private fun retrievePhoneNumber(uri: Uri): String {
    var phoneNumber = String.empty()

    val phone: Cursor? = this.contentResolver?.query(uri, null, null, null, null)
    phone?.let {
        if (it.moveToFirst()) {

            val id = it.getString(it.getColumnIndex(ContactsContract.Contacts._ID))
            val hasNumber =
                (it.getInt(it.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)))

            if (hasNumber > 0) {
                val phoneCursor: Cursor? = this.contentResolver?.query(
                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    null,
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", arrayOf(id),
                    null
                )
                phoneCursor?.let {
                    if (phoneCursor.moveToNext()) {
                        phoneNumber = phoneCursor.getString(
                            phoneCursor.getColumnIndex(
                                ContactsContract.CommonDataKinds.Phone.NUMBER
                            )
                        )
                    }
                    phoneCursor.close()
                }
            }
        }
        it.close()
    }
    return phoneNumber
}



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

https://github.com/dipenptl1/contact-picker-kotlin



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