Friday, 30 June 2017

Android: Sending headers with HttpURLConnection

This post includes the usage and implementation of HttpURLConnection to download a file from a URL along with sending the required headers with the http request. Through this post you will also learn to send custom headers along with the request to your http url.

The usage and implementation of HttpURLConnection is very simple as follows:

1. In your project, just add the following method where you want to download the file. Just pass the url from which you want to download the file, as the parameter to the below method.

private void downloadFileFromHttpURL(String your_url){
            
            URL url = new URL(your_url);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            // default headers for the request
            connection.addRequestProperty("Content-Type", "application/json");

            // custom headers for the request
            connection.addRequestProperty("customHeaderKey1", "HEADER_VALUE");
            connection.addRequestProperty("customHeaderKey2", "HEADER_VALUE");

            // check for the connection of url
            int response = connection.getResponseCode();
            if (response == 200) { // connected to the URL
LogWriter.write("LOG_TAG", "Is downloading..?");     

BufferedInputStream inStream = new BufferedInputStream(connection.getInputStream());
                // provide the path to save the downloaded file
                FileOutputStream fileStream = new FileOutputStream("YOUR_FILE_PATH");

                // BufferesOutputStream is used to write the downloaded file
                BufferedOutputStream outStream = new BufferedOutputStream(fileStream);

                byte[] buffer = new byte[16384];
                int len = 0;
                while ((len = inStream.read(buffer, 0, 16384)) != -1) {
                    LogWriter.write("LOG_TAG", "Yes downloading..");
                    outStream.write(buffer, 0, len);
                }
                outStream.flush();
                inStream.close();
                outStream.close();
            } else {
                // disconnect from URL if not connected  
                connection.disconnect();
                return null;
            }
            // disconnect from URL when the download is completed  
            connection.disconnect();
    }

That's all.
The above method will download the file from the url and save it to the path provided by you.
There are other option as well that you can use with HttpURLConnection which are follows:
   
      connection.setUseCaches(false);
      connection.setDoInput(true);
      connection.setDoOutput(true);
      connection.setRequestMethod("POST");

Note:
HttpURLConnection uses the GET method by default. It will use POST if setDoOutput(true) has been called.
Other HTTP methods (OPTIONS, HEAD, PUT, DELETE and TRACE) can be used with setRequestMethod(String).


Share and comment if any issues.

Monday, 26 June 2017

Android: Add and remove view dynamically

In this post I will show you how to add and remove a view dynamically at run-time.
This will be explained in a very simple activity in which when you will click the Add button, a new View will be added in the main layout(screen visible to you), and when you will click the Remove button, the newly added view will be removed from the main layout.


1. First of all make a layout class for the view which you want to inflate at run time. Here I'm naming it as row.xml and add the following code to it:

<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="wrap_content">
    <Button
        android:id="@+id/remove"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="Remove"/>
    <TextView
        android:id="@+id/textout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@+id/remove"/>
</RelativeLayout>


2. Now in the MainActivity.java class just add the below code snippet:

public class MainActivity extends Activity {

 EditText textIn;
 Button buttonAdd;
 LinearLayout container;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  textIn = (EditText)findViewById(R.id.textin);
  buttonAdd = (Button)findViewById(R.id.add);
  container = (LinearLayout)findViewById(R.id.container);
  
  buttonAdd.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View arg0) {
// code to inflate the view to be added at run time (row.xml)    
LayoutInflater layoutInflater = 
      (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    final View addView = layoutInflater.inflate(R.layout.row, null);
    TextView textOut = (TextView)addView.findViewById(R.id.textout);
    textOut.setText(textIn.getText().toString());
    Button buttonRemove = (Button)addView.findViewById(R.id.remove);
    buttonRemove.setOnClickListener(new OnClickListener(){

     @Override
     public void onClick(View v) {
      ((LinearLayout)addView.getParent()).removeView(addView);
     }});
    
    container.addView(addView);
   }});
  
 }
}

3. The layout file for MainActivity.java class named activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:text="Add"/>
        <EditText
            android:id="@+id/textin"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_toLeftOf="@+id/add"/>
    </RelativeLayout>
    <LinearLayout 
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
    </LinearLayout>

</LinearLayout>

That's all. Compile and run the app and after pressing the Add button you can see that a new view is added below to the Add button.


Share and comment if any issue.

Sunday, 18 June 2017

Android: ExpandableListView item click in Activity

In this post I will show the implementation of getting the item click event of ExpandableListview in your calling Activity or Fragment.
ExpandableListView is used to group list data by categories.It is a view that shows items in a vertically scrolling two-level list. It differs from a ListView by allowing two levels which are groups that can be easily expanded and collapsed by touching to view and their respective children items.
If you are not familiar with using ExpandableListView, first refer the tutorial here.

Now to get the item click in your activity or fragment follow below steps:

1. First make an Interface for the connectivity of your item click in your activity. For this create a class IExpandableListItemClick.java and add the following code:

public interface IExpandableListItemClick {

    void onExpandedItemClick(View view, int position);

}

2. In your adapter class make a variable for your Interface as follows:

 private IExpandableListItemClick expandedItemClickListener;

3. Now in the constructor of your adapter class assign your interface as follows:

public ExpandableListAdapter(Context context, List<String> expandableListTitle, HashMap<String, String>> expandableListDetail,
                          IExpandableListItemClick listener) {
        this.context = context;
               ................                                             
        this.expandedItemClickListener = listener;
    }


4. Now in the getChildView method of your adapter class add the following code:

 @Override
    public View getChildView(int listPosition, int expandedListPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        LayoutInflater inflater = LayoutInflater.from(context);
        convertView = inflater.inflate(R.layout.item_child_expandable_list, parent, false);
        
        // declare and initialize your view here

        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                expandedItemClickListener.onExpandedItemClick(view, expandedListPosition);
            }
        });
        return convertView;
    }

5. Now in your activity or your fragment implement your interface as follows: I am using a fragment
and implement its method.

public class MainFragment extends Fragment implements IExpandableListItemClick {

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
                                                     
          .......... ...............                 
                                                     
        return rootView;
    }                            
  ..... .........                 

@Override
    void onExpandedItemClick(View view, int position){   
                                                                                             
     }                                                                                      
 ...........                                                                                 
                                                                                             
}                

6. Now in the above method add a toast to see which item is clicked as follows:

@Override
    void onExpandedItemClick(View view, int position){                        
        Toast.makeText(getActivity, "Clicked item position: "+ position, Toast.LENGTH_SHORT).show();  
                                                         
     }


7. Now run your code and you can see the correct position of the item clicked in the toast.
You can change the parameters in interface method according to your requirements.

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

Sunday, 11 June 2017

Android: BigPictureStyle Notification

Now a days, you must have seen a notification from many android apps that contain a picture/image along with the message. This notification with a big image is known as BigPicturestyle Notifications. These notifications are generally used for the promotional purpose of some brand or some product or you can say about an offer.
With help of V4 appcompat library, we can implement this for all devices from Android 2.0 onward.
Building this type of notification in android is very simple and can be implemented as follows:

1. First create Notification object and set the title, content text, ticker text etc as follows:
        
        //Create notification object and set the content.
        NotificationCompat.Builder nb= new NotificationCompat.Builder(this);
        nb.setSmallIcon(R.drawable.small_icon);
        nb.setContentTitle("Notification title");
        nb.setContentText("Notification content/message");
        nb.setTicker("Notification ticker text");

2. Now create a bitmap of the image which needs to be shown as big picture & set it as shown in below code. Set the summaryText, this will appear on expanding the notification.
        
        //get the bitmap to show in notification bar
        Bitmap bm = BitmapFactory.decodeResource(this.getResources(),R.drawable.big_icon);
        NotificationCompat.BigPictureStyle s = new NotificationCompat.BigPictureStyle().bigPicture(bm);
        s.setSummaryText("Notification text that appears on expanding the notification");
        nb.setStyle(s);

3. Now set the intent that should be launched on clicking on the notification.
        Intent resultIntent = new Intent(this, MainActivity.class);
        TaskStackBuilder taskBuilder = TaskStackBuilder.create(this);
        taskBuilder.addParentStack(MainActivity.class);
       
        // Adds the Intent that starts the Activity to the top of the stack
        taskBuilder.addNextIntent(resultIntent);
        PendingIntent resultPendingIntent =
                taskBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
        nb.setContentIntent(resultPendingIntent);
        nb.setAutoCancel(true);
        NotificationManager mNotificationManager =
                (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        // mId allows you to update the notification later on.
        mNotificationManager.notify(11221, nb.build());

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


Sunday, 4 June 2017

Android: CoordinatorLayout

In this post I will let you know about the new layout introduced in Android Design Support Library.
The CoordinatorLayout is a super-powered FrameLayout. It is similar to Frame Layout yet its behavior attribute makes it different from other layouts. If you have used a FrameLayout before, you should be very comfortable using CoordinatorLayout. If you haven’t used a FrameLayout, do not worry, it is pretty straightforward.

CoordinatorLayout is intended for two primary use cases:
- As a top-level application decor or chrome layout
- As a container for a specific interaction with one or more child views

By specifying Behaviors for child views of a CoordinatorLayout you can provide many different interactions within a single parent and those views can also interact with one another. View classes can specify a default behavior when used as a child of a CoordinatorLayout using the DefaultBehavior annotation.

Behaviors may be used to implement a variety of interactions and additional layout modifications ranging from sliding drawers and panels to swipe-dismissable elements and buttons that stick to other elements as they move and animate.

Children of a CoordinatorLayout may have an anchor. This view id must correspond to an arbitrary descendant of the CoordinatorLayout, but it may not be the anchored child itself or a descendant of the anchored child. This can be used to place floating views relative to other arbitrary content panes.

Children can specify insetEdge to describe how the view insets the CoordinatorLayout. Any child views which are set to dodge the same inset edges by dodgeInsetEdges will be moved appropriately so that the views do not overlap.

-Dependency:
For using CoordinatorLayout in you app import Android Support Library into your project, by adding the following dependency to your app build.gradle file:

           dependencies {
               ......
                   compile 'com.android.support:design:23.0.0'
          }

Above Support Library also includes others views namely Snackbar, CollapsingToolbar, FloatingActionButton etc out of which some of them we will be using today.

1. To show the use of CoordinatorLayout, we will simply make layout containing a FAB button which will automatically slides out of the way when a Snackbar is displayed. The CoordinatorLayout is the root layout. Within it, we have a button, that is centered on screen, and a FAB, that’s positioned at the bottom right of the screen, with a little margin to ensure we abide by the material design guidelines.
The layout class is as follows:

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.sample.foo.usingcoordinatorlayout.FabAndSnackbarActivity">

    <Button
        android:id="@+id/showSnackbarButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="@string/show_snackbar"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|right"
        android:src="@android:drawable/ic_popup_disk_full"/>

</android.support.design.widget.CoordinatorLayout>

2. Now create a class FabAndSnackbarActivity.java and add the following code:

public class FabAndSnackbarActivity extends AppCompatActivity {

    private Button mShowSnackbarButton;
    private CoordinatorLayout mCoordinatorLayout;

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

        mCoordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorLayout);

        mShowSnackbarButton = (Button) findViewById(R.id.showSnackbarButton);
        mShowSnackbarButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(mCoordinatorLayout,
                        "This is a simple Snackbar", Snackbar.LENGTH_LONG)
                        .setAction("CLOSE", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                // Custom action
                            }
                        }).show();
            }
        });
    }
}

3. Now compile it and run your program. You will observe that the FAB button automatically slides up and out of the way for the Snackbar, when it is shown, and slides down and back to it’s position, when the snackbar is exiting from view. 

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