Sunday, 21 May 2017

Android: Layout as background of view

In this post I will show you how to set your custom layout as the background of your item of your listview or gridview or any other view that contains long list of data, through your adapter.
This is very simple and can be done as follows:

1. Make a file custom_placeholder.xml of your custom layout as follows:

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

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="6dp"
        android:background="@drawable/shape_bg">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="Downloading..."
            android:textAlignment="center"
            android:textSize="14sp" />

    </RelativeLayout>

</LinearLayout>


2. Now in the getView method of your adapter just replace your code with below code:

public View getView(final int position, View convertView, ViewGroup parent) {
        CustomViewHolder mViewHolder;
        if (convertView == null) {
            LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.item_gridview_assets, parent, false);
            mViewHolder = new CustomViewHolder(convertView);  // set your layout (convertView) as your viewHolder
            convertView.setTag(mViewHolder);
        } else {
            mViewHolder = (CustomViewHolder) convertView.getTag();
        }
          //Now check the condition whether your image is available or not  
        String value = imageList.get(position);
        if (!value.equalsIgnoreCase("")) {
             // case when image is available  
           mViewHolder.imgAssets.setBackgroundResource(R.drawable.sample_img);
        } else {
             // case when image is not available  
           // This will inflate your custom view that you created above
            LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.custom_placeholder, parent, false);
        }
        return convertView;
    }

That's all.
Share and comment if any issues.



Sunday, 30 April 2017

Android: Capture screen as snapshot

This blog post is regarding how to capture your android screen as snapshot. This may be one of your requirements during the course of your application development. It is very simple to implement this functionality as follows:

1. On the click of your button or at the event at which you want to capture your screen just use the below method:

void onYourButtonClick() {
        try {
            LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
            // pass your main layout id
            File screenshot = storeScreenShot(layout, "Screen_shot_" + new Date().getTime() + ".jpg");
            // you need to first save the captured image
        } catch (Exception ex) {
            ex.getMessage();
        }
    }

2. Method to save your file:

public static Bitmap getScreenShot(View view) {
        View screenView = view;
        screenView.setDrawingCacheEnabled(true);
        Bitmap bitmap = Bitmap.createBitmap(screenView.getDrawingCache());
        screenView.setDrawingCacheEnabled(false);
        return bitmap;
    }

    public static File storeScreenShot(View v, String fileName) {
        Bitmap bm = getScreenShot(v);
        final String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/SC";
        File dir = new File(dirPath);
        if (!dir.exists()) {
            if (!dir.mkdirs()) {
                Log.d("TAG", "Oops! Failed to create directory");
            }
        }
        File file = new File(dirPath, fileName);
        try {
            FileOutputStream fOut = new FileOutputStream(file);
            bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);
            fOut.flush();
            fOut.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return file;
    }

3. So the file (screenshot) created in step one is your captured screen image file.
You can use this file as per your needs.


That's all.
Share and comment if any issues.

Sunday, 9 April 2017

Android: Snackbar example

Snackbar is one of the most interesting component introduced in Material Design. Snackbars are just like Toast messages except they provide action to interact with. Snackbar will be displayed at the bottom of the screen and can be swiped off in order to dismiss them.
Snackbars provide lightweight feedback about an operation. They show a brief message at the bottom of the screen on mobile and lower left on larger devices. Snackbars appear above all other elements on screen and only one can be displayed at a time.
They automatically disappear after a timeout or after user interaction elsewhere on the screen, particularly after interactions that summon a new surface or activity.
Snackbars can contain an action which is set via setAction(CharSequence, View.OnClickListener).

Also to be notified when a snackbar has been shown or dismissed, you can provide a Snackbar.Callback via addCallback(BaseCallback).


Implementing Snackbar is very simple which can be done as follows:

Snackbar snackbar = Snackbar
        .make(coordinatorLayout, "Snackbar is visible.", Snackbar.LENGTH_LONG)
        .setAction("DONE", new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar snackbar1 = Snackbar.make(coordinatorLayout, "Snackbar dismissed.", Snackbar.LENGTH_SHORT);
                snackbar1.show();
            }
        });

snackbar.show();


One point to be noted here is that, while making a Snackbar I have used the CoordinatorLayout as the parent layout for Snackbar. Due to this CoordinatorLayout our Snackbar has the ability to be dismissed when swiped.


Tha's all.
Share and comment if any issues.


Thursday, 30 March 2017

Android: FileUriExposedException in Android N

If your android application shares files with/from other applications using Uri, and your application's targetSdkVersion is 24+ i.e Android N, then you may have encountered with an error/exception saying something like android.os.FileUriExposedException:

android.os.FileUriExposedException: file:///storage/emulated/0/DCIM/Camera/img_21032017190911.jpg exposed beyond app through ClipData.Item.getUri()

The error or exception is thrown when an application exposes a file:// Uri to another app.
Thus using file:// Uri is discouraged in this scenario because the receiving app may not have access to the path or the file:// Uri shared with it.
Like for example, the receiving app may not have requested the READ_EXTERNAL_STORAGE run time permission, or the platform may be sharing the file:// Uri across user profile boundaries, then this may result in an unexpected behaviour at best or at worst, it may result in a crash.

So the first thing to deal with this exception is that,

1. Your application should use content:// Uri instead of  file:// Uri so that the platform can extend temporary permission for the receiving app to access the resource.

2. Or you need to use FileProvider.

3. The work around from code can be done as follows:
    Just add the below code in your Application file's onCreate method as follows:

   public class ApplicationMain extends Application{

@Override
            public void onCreate() {
            super.onCreate();
....
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
....
}
   }


Note: This exception is only thrown for applications targeting N or higher. Applications targeting earlier SDK versions are allowed to share file:// Uri, but it's strongly discouraged.

That's all.
Share and comment if any issues.


Sunday, 26 March 2017

Android: Upload images using MultipartPost request

An HTTP MultipartPost request is a request that HTTP clients construct to send files and data over to a HTTP Server. It is commonly used by browsers and HTTP clients to upload files to the server.

To implement this request in your android applications to send images to your server follow these simple steps.

1. Add the following dependency in your build.gradle file:

                     compile 'com.squareup.okhttp3:okhttp:3.2.0'    

2. Now just add the code snippet with following parameters described as follows:


void uploadImageThroughMultipartPostRequest(File yourFileToBeUploaded) {

// yourFileToBeUploaded is your image file
        String contentType = null;
        RequestBody fileBody = null;
        if (yourFileToBeUploaded != null) {
            try {
                contentType = yourFileToBeUploaded.toURL().openConnection().getContentType();
            } catch (Exception e) {
                e.printStackTrace();
            }
            fileBody = RequestBody.create(MediaType.parse(contentType), yourFileToBeUploaded);
        }
       
       String requestURL = "YOUR_POST_REQUEST_URL" ;
       
       RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM) // Type to set Form request
                .addFormDataPart("uploaded_file", yourFileToBeUploaded.getPath())
                .addFormDataPart("uploaded_file_tag", "File_Name.jpeg", fileBody)
                .build();

        Request request = new Builder()
                .url(requestURL)
                .put(requestBody)
                .addHeader("Accept", "application/json")
                .addHeader("Content-Type", "application/json")
                .build();

        OkHttpClient okHttpClient = new OkHttpClient();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, final IOException e) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getActivity(), "Upload failure " + e.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                });
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                            Toast.makeText(getActivity(), "Message: "+response , Toast.LENGTH_SHORT).show();

                    }
                });
            }
        });
    }

3. Now just call the above method as follows:

            try {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            uploadImageThroughMultipartPostRequest(fileToUpload);
                        }
                    }).start();
                } catch (Exception ex) {
                    ex.getMessage();
                }

That's all.
Share and comment if any issues.


Thursday, 16 March 2017

Customizing Toast in Android

This post is regarding the customization of a Toast in your application.
You may have seen many a times some toast messages in android application notifying you that something has been completed or some action has been performed or executed.
These toast messages that you see are of the default representation from android but you can also customize your toast as you want.
This is quite simple which can be implemented as follows:

1. Create your xml layout file (custom_toast.xml) to show how your toast will look like.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="16dp"
            android:src="@drawable/sample_image" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="16dp"
            android:lines="2"
            android:text="This is your custom toast..!!!"
            android:textAlignment="center"
            android:textSize="12dp" />

    </LinearLayout>
</LinearLayout>

2. In your activity where you want to show the toast, just add the following snippet.

LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View layout = inflater.inflate(R.layout.custom_toast, null);
        Toast toast = new Toast(this);
        toast.setView(layout);
        toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
        toast.show();

That's all. Here you go.
Share and comment if any issues.



Sunday, 5 March 2017

Android: Decoding a Base64 encoded string

Sometimes in your application you contain some data which is very useful to you or its so sensitive that you don't want anyone else to have it. In that you need to encode or encrypt your data while transferring it through your application.
So for encoding your data and use it in your android application, we have android.util.Base64 class which is used to encode/decode your data.
First of all encoding is not the same thing as encryption. If you’re storing or using useful and sensitive information, you should be encrypting, not simply Base64 encoding. But android.util.Base64 class is also a very useful tool for this purpose.
The use of this class is very simple as depicted in the below example:

1. First import the required class:

                         import android.util.Base64;

2. Now just use the below code: 

String str = "Hello, world!";
       
byte[] encodedStr = Base64.encode(str.getBytes(), Base64.DEFAULT);    
byte[] decodedStr = Base64.decode(encodedStr, Base64.DEFAULT);
       
Log.d("Android Castle", "Android Castle Default Value =  " + str);
Log.d("Android Castle", "Android Castle Encoded Value =  " + new String(encodedStr));
Log.d("Android Castle", "Android Castle Decoded Value =  " + new String(decodedStr));


3. The following will be out put of the above snippet:

Android Castle Default Value = Hello, world!
Android Castle Encoded Value  = SGVsbG8sIHdvcmxkIQ==
Android Castle Decoded Value = Hello, world!

But in many case we have some highly secure data where the data is encoded and then compressed and then its being transferred to your application. In that case being a developer you have to decode the data and decompress it as well to make it useful for your application. The solution for this problem is as follows:

1. Import as follows:

                    import  org.java_websocket.util.Base64;

2. Use the following code snippet:

            String st = "YOUR ENCODE STRING";

            byte[] decodedByte = new byte[0];
            byte[] result = new byte[0];
            int resultLength = 0;
            try {
                decodedByte = Base64.decode(st, Base64.GZIP);
                Inflater decompresser = new Inflater();
                decompresser.setInput(decodedByte, 0, decodedByte.length);
                result = new byte[decodedByte.length];
                resultLength = decompresser.inflate(result);
                decompresser.end();
                String outputString = new String(result, 0, resultLength, "UTF-8");
               
                System.out.println("Your decode string: " + outputString);

            } catch (Exception e) {
                e.printStackTrace();
            }

That's all.

Share and comment if any issues.