Floating Search View with Auto Hide for Android

Floating Search View with auto hide is part of material design. All major app now include floating searchview. For instance here is a simple implementation of floating searchview, with out using any dependencies or library files. It’s a simple and effective way for creating floating searchview for beginners.



Search View

SearchView is a widget that provides a user interface for the user to enter a search query and submit a request to a search provider. Shows a list of query suggestions or results, if available, and allows the user to pick a suggestion or result to launch into.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:id="@+id/cordinatorLayoutActivityA"
    tools:context="com.logicchip.blog_14_floatingsearchview.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:visibility="gone"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

        <android.support.v7.widget.CardView
            app:layout_scrollFlags="scroll|enterAlways"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:cardUseCompatPadding="true"
            android:id="@+id/cardS"
            app:cardBackgroundColor="@color/colorIcons"
            app:cardElevation="5dp">
            <android.support.v7.widget.SearchView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginEnd="20dp"
                android:id="@+id/searchViewQuery"
                app:popupTheme="@style/AppTheme.PopupOverlay"
                app:queryHint="Search event"
                android:textColor="@color/colorPrimaryText"
                app:iconifiedByDefault="false"
                app:closeIcon="@drawable/ic_close"
                android:layout_marginRight="20dp" />
            <ImageButton
                android:layout_marginRight="5dp"
                android:onClick="PopupShowMenu"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_gravity="end|center_vertical"
                android:id="@+id/imageViewSearchMenu"
                style="@style/Widget.AppCompat.Button.Borderless"
                android:src="@drawable/ic_more"/>

        </android.support.v7.widget.CardView>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="fill_vertical"
        android:id="@+id/nestedScrollView"
        android:focusableInTouchMode="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <android.support.v7.widget.RecyclerView
            android:focusableInTouchMode="true"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:clipToPadding="false"
            android:paddingBottom="5dp"
            android:id="@+id/recycleView">
        </android.support.v7.widget.RecyclerView>

    </android.support.v4.widget.NestedScrollView>

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



However searchview come’s with default icon below method shows how to remove it, Else you can replace it custom icons. Furthermore you can always modify it in your own way here.

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        searchViewQuery = (SearchView)findViewById(R.id.searchViewQuery);
        imageViewSearchMenu = (ImageButton) findViewById(R.id.imageViewSearchMenu);
        cordinatorLayoutActivityA = (CoordinatorLayout) findViewById(R.id.cordinatorLayoutActivityA);
        nestedScrollView=(NestedScrollView)findViewById(R.id.nestedScrollView);


        EditText searchEditText = (EditText) searchViewQuery.findViewById(android.support.v7.appcompat.R.id.search_src_text);
        searchEditText.setTextColor(ResourcesCompat.getColor(getResources(),R.color.colorPrimaryText,null));
        searchEditText.setHintTextColor(ResourcesCompat.getColor(getResources(),R.color.colorSecondaryText,null));

        ImageView searchImage = (ImageView) searchViewQuery.findViewById(android.support.v7.appcompat.R.id.search_mag_icon);
        searchImage.setVisibility(View.GONE);
        ViewGroup linearLayoutSearchView =(ViewGroup) searchImage.getParent();
        linearLayoutSearchView.removeView(searchImage);
        linearLayoutSearchView.addView(searchImage);
        searchImage.setAdjustViewBounds(true);
        searchImage.setMaxWidth(0);
        searchImage.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
           LinearLayout.LayoutParams.WRAP_CONTENT));
        searchImage.setImageDrawable(null);

        recycleViewNews = (RecyclerView)findViewById(R.id.recycleView);
        recycleViewNews.setHasFixedSize(true);
        recycleViewNews.setLayoutManager(new LinearLayoutManager(this));
        mAdapter = new AdapterForRecycle(this);
        recycleViewNews.setAdapter(mAdapter);
        recycleViewNews.setNestedScrollingEnabled(false);


    }
Even so “Floating searchview” is explained above you can still download it from here, You can modify the code us u like. In like manner feel free to comment your doubt’s below. Does our tutorials help you then help as spread the word, like and share.

Share An Image Without Saving it in Android

As a matter of fact sometimes we want to share images without saving it. Images from internet or locally generated images.For example  whatsapp profile pictures. You can share it, but it’s only visible in gallery when we saved it. However we are using bitmap generated from linear-layout to share.

In fact  sharing an image without saving it is by using cache memory. Consequently we can share it like an uri. On the other hand we can simply store the image in cache and use the uri for sharing.

Furthermore we are saving bitmap to cache and use it for sharing. In fact a previous post explain how to convert view to bitmap.Binary data is shared using the ACTION_SEND action combined with setting the appropriate MIME type and placing the URI to the data in an extra named EXTRA_STREAM. This is commonly used to share an image but can be used to share any type of binary content.

You can use a MIME type of "*/*", but this will only match activities that are able to handle generic data streams.

In conclusion the receiving application needs permission to access the data the Uri points to.

Similarly we don’t need any special permission to store data in cache memory.

Adding Permission

Add these permissions in the manifest file.

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

 

OnClickShare

However below is the onclick method for share button. Create a method with view as argument then specify it in the xml file.

public void OnClickShare(View view){

        Bitmap bitmap =getBitmapFromView(idForSaveView);
        try {
           File file = new File(this.getExternalCacheDir(),"logicchip.png");
            FileOutputStream fOut = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
            fOut.flush();
            fOut.close();
            file.setReadable(true, false);
            final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
            intent.setType("image/png");
            startActivity(Intent.createChooser(intent, "Share image via"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Creating bitmap from view

For instance method creates bitmap from view or any layout extending view.If the background is empty it set’s white color as background.

private Bitmap getBitmapFromView(View view) {
        Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(returnedBitmap);
        Drawable bgDrawable =view.getBackground();
        if (bgDrawable!=null) {
            //has background drawable, then draw it on the canvas
            bgDrawable.draw(canvas);
        }   else{
            //does not have background drawable, then draw white background on the canvas
            canvas.drawColor(Color.WHITE);
        }
        view.draw(canvas);
        return returnedBitmap;
    }

MainActivity.java

This class file contain both methods, we don’t use onclick listener or implement onclick listener in order to reduce code. Because the click is coded directly to the xml file using onclick.

public class MainActivity extends AppCompatActivity {
    LinearLayout idForSaveView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        idForSaveView=(LinearLayout)findViewById(R.id.idForSaveView);
    }

    public void OnClickShare(View view){

        Bitmap bitmap =getBitmapFromView(idForSaveView);
        try {
            File file = new File(this.getExternalCacheDir(),"logicchip.png");
            FileOutputStream fOut = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
            fOut.flush();
            fOut.close();
            file.setReadable(true, false);
            final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
            intent.setType("image/png");
            startActivity(Intent.createChooser(intent, "Share image via"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Bitmap getBitmapFromView(View view) {
        Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(returnedBitmap);
        Drawable bgDrawable =view.getBackground();
        if (bgDrawable!=null) {
            //has background drawable, then draw it on the canvas
            bgDrawable.draw(canvas);
        }   else{
            //does not have background drawable, then draw white background on the canvas
            canvas.drawColor(Color.WHITE);
        }
        view.draw(canvas);
        return returnedBitmap;
    }
}

activity_main.xml

Still the  project require an user interface. Even though below xml file is just for showing how this work.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.logicchip.blog_13_shareimage.MainActivity">

            <LinearLayout
                android:id="@+id/idForSaveView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
                <ImageView
                    android:layout_gravity="center"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/ic_launcher"/>
                <TextView
                    android:layout_gravity="center"
                    android:textColor="@color/colorAccent"
                    android:textSize="20sp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="logicchip.com"/>
            </LinearLayout>
        <Button
            android:onClick="OnClickShare"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Share"/>

</LinearLayout>
Even so “Share An Image Without Saving it in Android” is explained above you can still download it from here, You can modify the code us u like. In like manner feel free to comment your doubt’s below. Does our tutorials help you then help as spread the word, like and share.

Send SMS Using SMS Gateway from Android

In Android, you can use SmsManager API or devices Built-in application to send SMS’s. Therefore in this tutorial, we shows how to send SMS message using SMS Gateway from android. However Some times it’s important to inform user about changes made to there account by email or sms. Such as verification codes,conformations etc, please let me present some interesting facts in this topic.

At this point about 5.1 billion out of the 6.8 billion people on Earth own a mobile phone – that’s a huge.

There are twice as many active SMS users in the world than active users of email.

On average, it takes 9 minutes for someone to respond to an SMS (by comparison, the response time in case of e-mail is 90 minutes).

Around 98 per cent of all messages are opened, but only 20 per cent of emails are looked at.

 

Android

Of course first is the android part, it transmit address of the recipient and message to be send. In order to transmit network data we are  using volley. And also the response is received by volley network library. As a matter of fact internet permission is required for this project.

Server

In fact way2sms don’t provide an official api for users. Still there are several api’s available unofficially. As a result of googling found a suitable api. Then modified it to work with android. However you can use wamp or any other free hosting providers as server. In the same way api working and it’s integration is explained below.

Introduction

Accordingly there is a lot of free Sms sending web portals available on the internet. Therefore people use them to send bulk and nonbulk Short messages without any charge. Still Way2Sms is one of the No.1 SMS Portal on the World Wide Web almost 1 million users were registered with them and send millions of message per day. Hence you are going to learn about the Way2Sms Php API Script Integration in an android app in this article.

How Way2Sms API  Script Works:

Consequently by integrating the Way2Sms Php API Script in your app, Your can send  SMS Directly through your app. You are never redirected to Way2Sms official site for login or another purpose. Because every action will take place through your server itself. You can also modify the script design like yours . Because the code was developed using PHP and it was too simple.

How to Integrate Way2Sms PHP API Script:

In fact it’s very easy to integrate the PHP API script on your app or website. In order to do this, you must have a Php Enabled Server (Cpanel). If you don’t have a PHP Supported Server, then create a free A/c on any of the site that listed on the linked page: Link Here

 

After creating an A/c or log in to your Existing Cpanel A/c, Do the following steps and procedure to integrate the  API script on your website. Or you can use wamp instead.

Above all first Download the script from here: Download,

Then Go to File-Browser of your Cpanel A/c & Create a “New Folder” name “androidsms”.

Afterward Upload the “12sms.rar” Downloaded the file to the “androidsms”.

Next Extract the “12sms.rar” File.

Run like: “http://example.com/androidsms/sms.php”.

You are Done.

SMS-Gateway

Accordingly a SMS-Gateway allows a computer to send or receive Short Message Service transmissions to or from a telecommunications network. Most messages are eventually routed into the mobile phone networks. In fact it’s able to send the messages coming from your Android application through HTTP to the SMSC (Short Message Service Center) of the Mobile Service Provider via SMPP IP SMS connection or a GSM modem. However the SMSC is a network element in the mobile telephone network that stores, forwards, converts and delivers SMS messages. Still to be able to send messages using HTTP, you will need an SMS Gateway that has a built-in webserver. In conclusion it allows you to send text messages from your application by calling an URL (HTTP Get) or using the HTTP Post method.

 

Sms.php

In addition below is the modified php script for sending message. It also require other script’s from the rar file.

<?php

include('func.php');
error_reporting(0);
set_time_limit(0);
$ser="http://site24.way2sms.com/";
$ckfile = tempnam ("/tmp", "CURLCOOKIE");
$login=$ser."Login1.action";
// * Reciving Username of Way2sms A/c from Html form //
$uid="youruserid";
// * Reciving Password of Way2sms A/c from Html form //
$pwd="yourpassword";//input($_REQUEST['pwd']);
// * To whome the message send to 
$to=$_POST['to'];
// * Message to be sended //
$msg=$_POST['message'];

$jsonData      = array();
$jsonTempData  = array();

if(!$to)
{ $to=$uid; }
if(!$msg)
{ $msg=rword(5).rword(5).rword(5).rword(5).rword(5); }
$captcha=input($_REQUEST['captcha']);
flush();
if($uid && $pwd)
{
$ibal="0";
$sbal="0";
$lhtml="0";
$shtml="0";
$khtml="0";
$qhtml="0";
$fhtml="0";
$te="0";
flush();

$loginpost="gval=&username=".$uid."&password=".$pwd."&Login=Login";

$ch = curl_init();
$lhtml=post($login,$loginpost,$ch,$ckfile);

if(stristr($lhtml,'Location: '.$ser.'vem.action') || stristr($lhtml,'Location: '.$ser.'MainView.action') || stristr($lhtml,'Location: '.$ser.'ebrdg.action'))
{
preg_match("/~(.*?);/i",$lhtml,$id);
$id=$id['1'];
if(!$id)
{
    goto end;
}
goto bal;
}
elseif(stristr($lhtml,'Location: http://site2.way2sms.com/entry'))
{
    goto end;
}
else
{goto end;
}
bal:
$msg=urlencode($msg);
$main=$ser."smstoss.action";
$ref=$ser."sendSMS?Token=".$id;
$conf=$ser."smscofirm.action?SentMessage=".$msg."&Token=".$id."&status=0";

$post="ssaction=ss&Token=".$id."&mobile=".$to."&message=".$msg."&Send=Send Sms&msgLen=".strlen($msg);
$mhtml=post($main,$post,$ch,$ckfile,$proxy,$ref);
if(stristr($mhtml,'smscofirm.action?SentMessage='))
// * Message Sended Sucessfull Message//
{
    $jsonTempData['sms']    ="Message send";
}   else
// * Login Faild or SMS Send Error Message 1//
{
    $jsonTempData['sms']   ="Error message 1";
}
    curl_close($ch);
end:
flush();
}
$jsonData[]=$jsonTempData;

$outputArr['check'] = $jsonData;
// Encode Array To JSON Data
print_r( json_encode($outputArr));

?>

 

MainActivity.java

Class file contain the sending of information  number and message.

public class MainActivity extends AppCompatActivity {
private EditText editTextTo,editTextMessage;
    RelativeLayout activity_main;

    private RequestQueue requestQueue;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        activity_main=(RelativeLayout)findViewById(R.id.activity_main);
        editTextTo=(EditText)findViewById(R.id.editTextTo);
        editTextMessage=(EditText)findViewById(R.id.editTextMessage);
        requestQueue = Volley.newRequestQueue(this);
    }

    public void OnClickButton(View view){
        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);

        if(editTextTo.getText().toString().isEmpty()){
            Snack("Number is empty");
        }else if(editTextTo.getText().length()!=10){
            Snack("Check the number");
        }else if(editTextMessage.getText().toString().isEmpty()){
            Snack("Message is empty");
        }else{
            SendSms(editTextTo.getText().toString(),editTextMessage.getText().toString());
        }
    }


    public void Snack(String message){
        Snackbar.make(activity_main, message, Snackbar.LENGTH_LONG).setAction("Action", null).show();
    }

    public void SendSms(final String to, final String message) {

        StringRequest menuRequest = new StringRequest(Request.Method.POST,"http://example.com/androidsms/sms.php",
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        try {
                            JSONArray jsonResponse = new JSONObject(response).getJSONArray("check");

                            int i = jsonResponse.length();
                            for(int j=0;j<i;j++){
                                JSONObject jsonChildNode = jsonResponse.getJSONObject(j);
                                Snack(jsonChildNode.optString("sms").toString());

                            }

                        } catch (JSONException e) {
                            e.printStackTrace();
                            Log.e("Json",e.getMessage());
                            Snack("Json " + e.getMessage());
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        error.printStackTrace();
                        Snack("Volley " + error.getMessage());
                    }
                }
        ) {
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<>();
                params.put("to",to);
                params.put("message",message);
                return params;
            }
        };
        requestQueue.add(menuRequest);
    }

}

 

Incidentally here is the full code for android: Download.

Creating Image From Current View in Android

Sometimes we are require to create images in our application,This project is all about creating image from view.In addition a view can be Relative-layout, Linear-layout etc. However for creating image from view in android first convert the view to bitmap format. Then the converted bitmap file is saved as a readable image format. Finally scan the gallery for making the newly created images visible.

Before everything add permission’s for reading from and writing to the external storage in manifest file.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />



 

Download full source code here.

Creating bitmap from view

In order to create a bitmap first define a bitmap with the same size as the view with bitmap configuration ARGB_8888. In fact a bitmap configuration describes how pixels are stored. This affects the quality (color depth) as well as the ability to display transparent/translucent colors. Accordingly for bitmap configuration “ARGB_8888” each pixel is stored on 4 bytes. Another part is creating a canvas and bind to the bitmap, Canvas is where the images are drawn.

private Bitmap getBitmapFromView(View view) {
        //Define a bitmap with the same size as the view
        Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
        //Bind a canvas to it
        Canvas canvas = new Canvas(returnedBitmap);
        //Get the view's background
        Drawable bgDrawable =view.getBackground();
        if (bgDrawable!=null) {
            //has background drawable, then draw it on the canvas
            bgDrawable.draw(canvas);
        }   else{
            //does not have background drawable, then draw white background on the canvas
            canvas.drawColor(Color.WHITE);
        }
        // draw the view on the canvas
        view.draw(canvas);
        //return the bitmap
        return returnedBitmap;
    }

Saving the bitmap

In the first place create a folder to save the images inside the picture directory or any other place. In any case check if it’s there else create it. Next is the image name it can’t be same because it overwrite the previous image, For this reason we are using system time in milliseconds for the name. As a result not two names are same. Then an image file is created with system time as the name. Also a bitmap object is created and it have the bitmap result of the view to bitmap conversion. Although image file is created it’s blank and FileOutputStreamis used for writing bitmap data  to the image file.

  private File saveBitMap(Context context, View drawView){
        File pictureFileDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"Logicchip");
        if (!pictureFileDir.exists()) {
            boolean isDirectoryCreated = pictureFileDir.mkdirs();
            if(!isDirectoryCreated)
                Log.i("TAG", "Can't create directory to save the image");
            return null;
        }
        String filename = pictureFileDir.getPath() +File.separator+ System.currentTimeMillis()+".jpg";
        File pictureFile = new File(filename);
        Bitmap bitmap =getBitmapFromView(drawView);
        try {
            pictureFile.createNewFile();
            FileOutputStream oStream = new FileOutputStream(pictureFile);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, oStream);
            oStream.flush();
            oStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            Log.i("TAG", "There was an issue saving the image.");
        }
        scanGallery( context,pictureFile.getAbsolutePath());
        return pictureFile;
    }



Scanning the gallery

As a matter of fact creating an image does’t mean it’s visible in gallery. Therefore we need to refresh the media scanner and update it with new images path.

 private void scanGallery(Context cntx, String path) {
        try {
            MediaScannerConnection.scanFile(cntx, new String[]{path}, null, new MediaScannerConnection.OnScanCompletedListener() {
                public void onScanCompleted(String path, Uri uri) {
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("TAG", "There was an issue scanning gallery.");
        }
    }

 

Full code MainActivity

public class MainActivity extends AppCompatActivity {
    ProgressDialog pd;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pd = new ProgressDialog(MainActivity.this);
    }
public void SaveClick(View view){
        pd.setMessage("saving your image");
        pd.show();
RelativeLayout savingLayout =(RelativeLayout)findViewById(R.id.idForSaving);
                File file = saveBitMap(MainActivity.this, savingLayout);
                if (file != null) {
                    pd.cancel();
                    Log.i("TAG", "Drawing saved to the gallery!");
                } else {
                    pd.cancel();
                    Log.i("TAG", "Oops! Image could not be saved.");
                }
}

  private File saveBitMap(Context context, View drawView){
        File pictureFileDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"Logicchip");
        if (!pictureFileDir.exists()) {
            boolean isDirectoryCreated = pictureFileDir.mkdirs();
            if(!isDirectoryCreated)
                Log.i("TAG", "Can't create directory to save the image");
            return null;
        }
        String filename = pictureFileDir.getPath() +File.separator+ System.currentTimeMillis()+".jpg";
        File pictureFile = new File(filename);
        Bitmap bitmap =getBitmapFromView(drawView);
        try {
            pictureFile.createNewFile();
            FileOutputStream oStream = new FileOutputStream(pictureFile);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, oStream);
            oStream.flush();
            oStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            Log.i("TAG", "There was an issue saving the image.");
        }
        scanGallery( context,pictureFile.getAbsolutePath());
        return pictureFile;
    }

 //create bitmap from view and returns it
    private Bitmap getBitmapFromView(View view) {
        //Define a bitmap with the same size as the view
        Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
        //Bind a canvas to it
        Canvas canvas = new Canvas(returnedBitmap);
        //Get the view's background
        Drawable bgDrawable =view.getBackground();
        if (bgDrawable!=null) {
            //has background drawable, then draw it on the canvas
            bgDrawable.draw(canvas);
        }   else{
            //does not have background drawable, then draw white background on the canvas
            canvas.drawColor(Color.WHITE);
        }
        // draw the view on the canvas
        view.draw(canvas);
        //return the bitmap
        return returnedBitmap;
    }


    // used for scanning gallery
    private void scanGallery(Context cntx, String path) {
        try {
            MediaScannerConnection.scanFile(cntx, new String[]{path}, null, new MediaScannerConnection.OnScanCompletedListener() {
                public void onScanCompleted(String path, Uri uri) {
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("TAG", "There was an issue scanning gallery.");
        }
    }
}

Xml file for main activity

<?xml version="1.0" encoding="utf-8"?>
<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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.logicchip.blog_11_saving_layout_as_image_in_android.MainActivity"
    android:orientation="vertical">
        <RelativeLayout
            android:background="@drawable/for_backgroud"
            android:id="@+id/idForSaving"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

                <ImageView
                    android:alpha=".3"
                    android:layout_centerInParent="true"
                    android:layout_width="150dp"
                    android:layout_height="150dp"
                    android:src="@drawable/logo"/>
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">
                        <TextView
                            android:drawableLeft="@drawable/logo_browser"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="logicchip.com"/>
                        <TextView
                            android:drawableLeft="@drawable/logo_facebook"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="/logicchip"/>
                        <TextView
                            android:drawableLeft="@drawable/logo_twitter"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="\@logic_chip"/>
                        <TextView
                            android:drawableLeft="@drawable/logo_google_plus"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="/+Logicchip"/>
                        <TextView
                            android:drawableLeft="@drawable/logo_youtube"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="/logicchip"/>
                        <TextView
                            android:drawableLeft="@drawable/logo_email"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="info@logicchip.com"/>
                </LinearLayout>
        </RelativeLayout>
        <Button
            android:onClick="SaveClick"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="save"/>
</LinearLayout>

 

 

Turing Your WordPress site into an android App

Turn your WordPress site into a native android app. Certainly not talking about creating a webview and loading an URL with it. In conclusion almost all android apps for website’s are URL loaded inside a webview. Although the webview is present here but it’s different.Let me explain.Don’t have to,let me show it.



Download full code here

In fact this video is sufficient explanation. However for this project we are using an actual website, yes this website. Hence turning this site into an android app. So let’s begin, Mainly this project is divided in to three.

  1. WordPress part.
  2. Web-service Part.
  3. Android part.

WordPress Part

In the first place start by installing a plugin for Accelerated Mobile Pages (AMP), i am using this one. Then after installing the plugin you can check your amp url. As a result normal url for a post is “www.yourwebsite.com/post/” and it’s amp url is “www.yourwebsite.com/post/amp/”. Keep it in mind we will be using it later.

Web-service Part

In addition to WordPress part this gets posts details from your database to android. Since it’s the sole purpose of this part. While only focus of this projects are posts. You can modify it as you like, either posts or pages even both. On with the code, Like my all other posts this web-service is also written in php. While WordPress is written using php as the scripting language. Therefore making it much more practical to use php. Create a folder in your public_html so we can access it like this “www.yourwebsite.com/yourfolder/webservice.php”.

However some of the things are gathered using WordPress functions. Especially relevant things like database name password thumbnail etc. So sensitive information’s are therefore hidden. Another interesting thing is that this code is universal just copy  and use. Also it work’s with any WordPress websites.

webservice.php

<?php
 /*
 * Post Template
   Used to call webservices
   Plugin Name: Android App logicchip
   Plugin URI: https://logicchip.com
   Description: A plugin for creating an android app of your site with realtime notifiaction and much more. 
   For more information please visit out site the link is below. #happy coding !
   Version: 1.0
   Author: Mr. Akhil Ashok
   Author URI: https://logicchip.com
   License: GPL2
   Email :akhilashok123@gmail.com,info@logicchip.com
   */
ini_set("memory_limit","128M");
 
// To load wordpress functions ,include file wp-load.php which is in root.
$base_dir = dirname(dirname(__FILE__));
require_once($base_dir."/wp-load.php");
mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
$conn = new mysqli(DB_HOST, DB_USER, DB_PASSWORD,DB_NAME);
if ($conn->connect_error) {
  //die("Connection failed: " . $conn->connect_error);
} else{
//echo "Connected successfully "."<br />\r\n";
}

$jsonDataBack  = array();

 $sql="SELECT wp_posts.ID,wp_posts.post_author,wp_posts.post_modified,wp_posts.guid,wp_users.display_name FROM wp_posts INNER JOIN wp_users 
 WHERE  wp_posts.post_status = 'publish' AND wp_posts.post_type = 'post' AND wp_users.ID = wp_posts.post_author ORDER BY wp_posts.post_date DESC ";

$result = $conn->query($sql);

    if ($result->num_rows > 0) {
        for ($x=0; $row = $result->fetch_assoc(); $x++) {
        $jTempData  = array();
        $jTempData['id']=$row["ID"];
        $jTempData['author']=$row["display_name"];
        $jTempData['name']=get_the_title($row["ID"]);       
        $jTempData['time']=$row["post_modified"];
        //$jTempData['link']=$row["guid"];
        $jTempData['link']=get_permalink($row["ID"]);
    
        if ( has_post_thumbnail($row["ID"])) {
        $jTempData['image']=$post_thumbnail_id = wp_get_attachment_url(get_post_thumbnail_id( $row["ID"] ));
            }else{
        $jTempData['image']="none";
            }
        setup_postdata($row["ID"]); 
        $categories = get_the_category($row["ID"]);
            if ( ! empty( $categories ) ) {  
        $jTempData['category']=esc_html( $categories[0]->name );
            }else{
        $jTempData['category']="none";      
            }
        $jTempData['content']=strip_tags(get_the_excerpt( $row["ID"]));
        $jsonDataBack[$x]=$jTempData;
            }
    }else{
        $jTempData  = array();
        $jTempData['id']="0";
        $jTempData['name']="none";
        $jTempData['link']="none";
        $jTempData['time']="none";
        $jTempData['content']="none";
        $jTempData['author']="none";
        $jTempData['image']="none";
        $jTempData['category']="none";
        $jsonDataBack[0]=$jTempData;
            }
$conn->close();
$outputArray['for_post'] = $jsonDataBack;
print_r( json_encode($outputArray));
?>



Android Part

Finally, Android part include fetching the information provided by the web-service. However the received information has a pattern and it’s repeating. Therefore we need to create a type for pattern and an adapter for repeating part. Also a list for displaying the adapter. Finally activity for reading the post.

Type

All the information received are of string type so it’s easy to work with. Class file for setting and getting information in this case string value’s. Another way is you can just sent it directly to the adapter, by using type complexity of the code is reduced.

WordPressType.java
public class WordPressType {

    String response_id,response_name,response_link,response_time,response_content,response_author,response_image,response_category;
    public WordPressType(){}

    public WordPressType(String response_id, String response_name, String response_link, String response_time, String response_content, String
    response_author, String response_image, String response_category){
        this.response_id=response_id;
        this.response_name=response_name;
        this.response_link=response_link;
        this.response_time=response_time;
        this.response_content=response_content;
        this.response_author=response_author;
        this.response_image=response_image;
        this.response_category=response_category;
    }
// in order to get string value
    public String getResponse_id(){return this.response_id;}
    public String getResponse_name(){return this.response_name;}
    public String getResponse_link(){return this.response_link;}
    public String getResponse_time(){return this.response_time;}
    public String getResponse_content(){return this.response_content;}
    public String getResponse_author(){return this.response_author;}
    public String getResponse_image(){return this.response_image;}
    public String getResponse_category(){return this.response_category;}
// in order to set string value
    public void setResponse_id(String response_id){this.response_id=response_id;}
    public void setResponse_name(String response_name){this.response_name=response_name;}
    public void setResponse_link(String response_link){this.response_link=response_link;}
    public void setResponse_time(String response_time){this.response_time=response_time;}
    public void setResponse_content(String response_content){this.response_content=response_content;}
    public void setResponse_author(String response_author){this.response_author=response_author;}
    public void setResponse_image(String response_image){this.response_image=response_image;}
  public void setResponse_category(String response_category){this.response_category=response_category;}
}

Before creating the adapter, See the images in the below image. Another class is created for caching those images to avoid using up the resources.

BitmapCache.java
public class BitmapCache extends LruCache<String, Bitmap> implements ImageCache {

    public static int getDefaultLruCacheSize() {
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;
        return cacheSize;
    }

    public BitmapCache(){
        this(getDefaultLruCacheSize());
    }

    public BitmapCache(int sizeInKiloBytes) {
        super(sizeInKiloBytes);
    }
    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight() / 1024;
    }

    @Override
    public Bitmap getBitmap(String url) {
        return get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        put(url, bitmap);
    }
}

 

Adapter

So the adapter extents RecyclerView.Adapter and it’s placed inside the RecyclerView that’s the list. Like any adapter both xml and java part is required. CardView looks cool so it’s created with card view.

wordpress_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:elevation="5dp"
    app:cardElevation="5dp">
// in order for getting the image 
    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/idForImage"
        android:layout_gravity="top"
        android:scaleType="centerCrop"
        android:layout_width="match_parent"
        android:layout_height="160dp"
        android:src="@mipmap/ic_launcher"/>
    <View

        android:layout_marginTop="82dp"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:alpha=".7"
        android:background="@color/colorPrimaryText">

    </View>

    <LinearLayout
        android:layout_marginTop="80dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">


        <TextView
            android:maxLines="1"
            android:id="@+id/idForName"
            android:layout_marginTop="10dp"
            android:layout_marginLeft="16dp"
            android:textColor="@color/colorIcons"
            android:gravity="left"
            android:textSize="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Event Management Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs This is my web site, so do not override; let my WebView load the page"/>
          
        <TextView
            android:id="@+id/idForContent"
            android:layout_marginLeft="16dp"
            android:textColor="@color/colorDivider"
            android:maxLines="3"
            android:textAlignment="inherit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Event Management Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs This is my web site, so do not override; let my WebView load the page"/>
        <LinearLayout
            android:layout_marginLeft="16dp"
            android:layout_marginBottom="5dp"
            android:layout_marginTop="5dp"
            android:layout_marginRight="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <LinearLayout
                android:layout_weight="1"
                android:layout_gravity="left"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">
                <TextView
                    android:layout_weight="1"
                    android:maxLines="1"
                    android:id="@+id/idForTime"
                    android:gravity="left"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Event Management Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs This is my web site, so do not override; let my WebView load the page"/>
                <TextView
                    android:layout_weight="1"
                    android:maxLines="1"
                    android:id="@+id/idForAuthor"
                    android:gravity="left"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Event Management Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs This is my web site, so do not override; let my WebView load the page"/>
            </LinearLayout>
            <LinearLayout
                android:layout_weight="1"
                android:layout_gravity="right"
                android:gravity="right"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <Button
                    android:id="@+id/idForCategory"
                    android:textStyle="bold"
                    style="@style/Widget.AppCompat.Button.Borderless"
                    android:textColor="@color/colorAccent"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Event Management Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs This is my web site, so do not override; let my WebView load the page"/>
            </LinearLayout>


        </LinearLayout>

    </LinearLayout>


</android.support.v7.widget.CardView>

Errors are common while coding, if  “com.android.volley.toolbox.NetworkImageView” showing an error include volley in your dependencies .

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.1.0'
    testCompile 'junit:junit:4.12'
    compile 'com.android.volley:volley:1.0.0'
    compile 'com.android.support:design:25.1.0'
    compile 'com.android.support:cardview-v7:25.1.0'
    compile 'com.android.support:palette-v7:25.1.0'
    compile 'com.android.support:recyclerview-v7:25.1.0'
}
AdapterForWordPress.java

So the adapter contain ((WordPress)context).LoadPostView (); , because adapter can’t directly call parent activity methods. However LoadPostView() is the method and WordPress is the parent activity.

public class AdapterForWordPress extends RecyclerView.Adapter<AdapterForWordPress.ViewHolder>{
        private Activity context;
        private ArrayList<WordPressType> typeForPosts;
        private RequestQueue mRequestQueue;
        private ImageLoader mImageLoader;

        public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
            // each data item is just a string in this case
            TextView idForName,idForContent,idForTime,idForAuthor;
            Button idForCategory;
            NetworkImageView idForImage;

            public ViewHolder(View v) {
                super(v);
                idForName=(TextView)v.findViewById(R.id.idForName);
                idForContent=(TextView)v.findViewById(R.id.idForContent);
                idForTime=(TextView)v.findViewById(R.id.idForTime);
                idForAuthor=(TextView)v.findViewById(R.id.idForAuthor);
                idForCategory=(Button) v.findViewById(R.id.idForCategory);
                idForImage=(NetworkImageView) v.findViewById(R.id.idForImage);
                v.setOnClickListener(this);
            }

            @Override
            public void onClick(View v) {
                ((WordPress)context).LoadPostView(typeForPosts.get(getAdapterPosition()).getResponse_link().toString());
            }
        }

        public  AdapterForWordPress(Activity context,ArrayList<WordPressType> typeForPosts){
            this.context=context;
            this.typeForPosts = typeForPosts;
        }

        @Override
        public AdapterForWordPress.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            // create a new view
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.wordpress_layout, parent, false);
            // set the view's size, margins, paddings and layout parameters
            ViewHolder vh = new ViewHolder(view);
            return vh;
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
//each data is inserted
             holder.idForName.setText(typeForPosts.get(position).getResponse_name().toString());
             holder.idForContent.setText(typeForPosts.get(position).getResponse_content().toString());
             holder.idForAuthor.setText(typeForPosts.get(position).getResponse_author().toString());
             holder.idForCategory.setText(typeForPosts.get(position).getResponse_category().toString());
             holder.idForImage.setImageUrl(typeForPosts.get(position).getResponse_image(), getImageLoader());

            try {
                DateFormat inputFirstTime = new SimpleDateFormat(Constants.TEMPLATE_FOR_TIME);
                DateFormat inputSecondTime = new SimpleDateFormat(Constants.TEMPLATE_FOR_TIME);
                Date dateOne = new Date();

                Date dateTwo = inputFirstTime.parse(inputSecondTime.format(dateOne)+" 00:00:00");
                Date dateThree = inputFirstTime.parse(typeForPosts.get(position).getResponse_time().toString());

                Calendar calenderOne = Calendar.getInstance();
                calenderOne.setTime(dateThree);

                int monthOne = calenderOne.get(Calendar.MONTH);
                String month = getMonthForInt(monthOne);
                int hour =calenderOne.get(Calendar.HOUR);
                int day  = calenderOne.get(Calendar.DAY_OF_MONTH);
                int year = calenderOne.get(Calendar.YEAR);

                if(dateTwo.compareTo(dateThree)>0){
                    holder.idForTime.setText(year+" "+month+" "+day);
                }else if(dateTwo.compareTo(dateThree)<0){
                    holder.idForTime.setText("Tomorrow "+year+" "+month+" "+day+" "+hour);
                }else if(dateTwo.compareTo(dateThree)==0) {
                    //It's today not possible
                    holder.idForTime.setText("Today "+year+" "+month+" "+day+" "+hour);
                }else {
                    //How to get here ?
                    holder.idForTime.setText("Error "+year+" "+month+" "+day+" "+hour);
                }

            }catch (Exception e){
                ((WordPress)context).SnackBarMessage("Exception with date");
            }

        }

        @Override
        public int getItemCount() {
            return typeForPosts.size();
        }



//month in string from number
    public String getMonthForInt(int num) {
        String month = "wrong";
        DateFormatSymbols dfs = new DateFormatSymbols();
        String[] months = dfs.getMonths();
        if (num >= 0 && num <= 11 ) {
            month = months[num];
        }
        return month;
    }

//for requesting image file for network imageview
    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(context);
        }
        return mRequestQueue;
    }

    public ImageLoader getImageLoader() {
        getRequestQueue();
        if (mImageLoader == null) {
            mImageLoader = new ImageLoader(this.mRequestQueue,new BitmapCache());
        }
        return this.mImageLoader;
    }

    }

Parent activity

So the Parent activity contains SwipeRefreshLayout + NestedScrollView + RecyclerView. As a result of combining this, user interface is more material design. However this includes swipe refresh option auto hiding of action bar, and CallingPage is the web-service method. Retrieved web-service information is changed to type and that is place inside an array-list is passed to adapter. Another method LoadPostView is for the launching activity to read the post along with the link of selected post.

public class WordPress extends AppCompatActivity {
    private RecyclerView recycleViewWordPress;
    private RecyclerView.Adapter mAdapter;
    private RequestQueue queue;
    private ArrayList<WordPressType> typeForPosts;
    private SwipeRefreshLayout swipeRefreshLayout;
    private CoordinatorLayout coordinatorLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_wordpress);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        coordinatorLayout=(CoordinatorLayout)findViewById(R.id.coordinatorLayout);
        swipeRefreshLayout=(SwipeRefreshLayout)findViewById(R.id.swipeRefreshLayout);
        recycleViewWordPress=(RecyclerView)findViewById(R.id.recycleViewWordPress);
        recycleViewWordPress.setHasFixedSize(true);
        recycleViewWordPress.setLayoutManager(new LinearLayoutManager(this));
        // specify an adapter (see also next example)
        recycleViewWordPress.setNestedScrollingEnabled(false);
        queue = Volley.newRequestQueue(this);
        swipeRefreshLayout.setRefreshing(true);
        CallingPage();
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                swipeRefreshLayout.setRefreshing(true);
                CallingPage();
            }
        });
    }

    public void SnackBarMessage(String message) {
        Snackbar.make(coordinatorLayout, message, Snackbar.LENGTH_LONG).setAction("Action", null).show();
    }

    public void CallingPage(){
        // Request a string response from the provided URL.
        StringRequest stringRequest = new StringRequest(Request.Method.POST, Constants.HOST_URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        // Display the first 500 characters of the response string.
                        typeForPosts =new ArrayList<WordPressType>();

                        mAdapter = new AdapterForWordPress(WordPress.this,typeForPosts);
                        recycleViewWordPress.setAdapter(mAdapter);
                        try {
                            JSONArray jsonResponse = new JSONObject(response).getJSONArray(Constants.RESPONSE);
                            int i = jsonResponse.length();

                            for (int j = 0; j < i; j++) {
                                WordPressType typeHints =new WordPressType();
                                JSONObject jsonChildNode = jsonResponse.getJSONObject(j);
                                typeHints.setResponse_id(jsonChildNode.optString(Constants.RESPONSE_1.trim()).toString());
                                typeHints.setResponse_name(jsonChildNode.optString(Constants.RESPONSE_2.trim()).toString());
                                typeHints.setResponse_link(jsonChildNode.optString(Constants.RESPONSE_3.trim()).toString());
                                typeHints.setResponse_time(jsonChildNode.optString(Constants.RESPONSE_4.trim()).toString());
                                typeHints.setResponse_content(jsonChildNode.optString(Constants.RESPONSE_5.trim()).toString());
                                typeHints.setResponse_author(jsonChildNode.optString(Constants.RESPONSE_6.trim()).toString());
                                typeHints.setResponse_image(jsonChildNode.optString(Constants.RESPONSE_7.trim()).toString());
                                typeHints.setResponse_category(jsonChildNode.optString(Constants.RESPONSE_8.trim()).toString());
                                typeForPosts.add(typeHints);
                                mAdapter.notifyDataSetChanged();
                            }
                            swipeRefreshLayout.setRefreshing(false);

                        } catch (JSONException e) {
                            e.printStackTrace();
                            //Toast.makeText(WordPress.this,"frag a"+ e.getMessage(), Toast.LENGTH_LONG).show();
                            SnackBarMessage("JSON Exception");
                        }
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                //Toast.makeText(WordPress.this, "error 2", Toast.LENGTH_LONG).show();
                SnackBarMessage("Volley Response Error");
            }
        });
        // Add the request to the RequestQueue.
        queue.add(stringRequest);

    }
// next activity with specific link 
    public void LoadPostView(String linkToOpen){
        Intent intent =new Intent(WordPress.this,PostView.class);
        intent.putExtra("link",linkToOpen);
        startActivity(intent);
    }
}

Also user interface for parent activity.

activity_wordpress.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:id="@+id/coordinatorLayout"
    tools:context="com.logicchip.wordpresstoandroid.WordPress">
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
    </android.support.design.widget.AppBarLayout>
        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipeRefreshLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="fill_vertical"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">
            <android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="fill_vertical"
                app:layout_behavior="@string/appbar_scrolling_view_behavior">
                 <android.support.v7.widget.RecyclerView
                     android:id="@+id/recycleViewWordPress"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content">
                 </android.support.v7.widget.RecyclerView>
            </android.support.v4.widget.NestedScrollView>
        </android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>

 

Reading post

So Remember the AMP mentioned above seems like we are using it now. First of all see the xml yes it contain’s a webview, then the class file PostView. In fact parameter passed from parent activity is changed like this, from “www.yourwebsite.com/post/” to “www.yourwebsite.com/post/amp/” . As a result of this operation webview loads the AMP version of your page. Because of class MyWebChromeClient inside PostView  we can play videos in webview. Similarly MyBrowser class is for handling the clicks inside the webview along with some other functions like 404, 403 error’s etc.

activity_post_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_post_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.logicchip.wordpresstoandroid.PostView">
            <WebView
                android:id="@+id/idForLink"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
            </WebView>
</RelativeLayout>
PostView.java
public class PostView extends AppCompatActivity {
    private WebView idForLink;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_post_view);
        idForLink = (WebView) findViewById(R.id.idForLink);
        idForLink.setWebViewClient(new MyBrowser());
        idForLink.setWebChromeClient(new MyWebChromeClient());
        idForLink.getSettings().setLoadsImagesAutomatically(true);
        idForLink.getSettings().setJavaScriptEnabled(true);
        idForLink.getSettings().setAppCacheEnabled(true);
        idForLink.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        String linkToOpen=getIntent().getStringExtra("link");
        idForLink.loadUrl(linkToOpen+"amp/");
    }
    public class MyWebChromeClient extends WebChromeClient {
        @Override
        public void onShowCustomView(View view, CustomViewCallback callback) {
            // TODO Auto-generated method stub
            super.onShowCustomView(view, callback);
            if (view instanceof FrameLayout) {
                FrameLayout frame = (FrameLayout) view;
                if (frame.getFocusedChild() instanceof VideoView) {
                    VideoView video = (VideoView) frame.getFocusedChild();
                    frame.removeView(video);
                    video.start();
                }
            }
        }
    }
    private class MyBrowser extends WebViewClient {   }
}

Constants.java

In order to keep constant values for easy access.

public class Constants {
    public static String HOST_URL="http://yourwebsite.com/yourfolder/webservice.php";
    public static String AMP="amp/";
    public static String TEMPLATE_FOR_TIME = "yyyy-MM-dd";
    public static String RESPONSE = "for_post";
    public static String RESPONSE_1 = "id";
    public static String RESPONSE_2 = "name";
    public static String RESPONSE_3 = "link";
    public static String RESPONSE_4 = "time";
    public static String RESPONSE_5 = "content";
    public static String RESPONSE_6 = "author";
    public static String RESPONSE_7 = "image";
    public static String RESPONSE_8 = "category";
}

 

 

Create QR Code with Logo in android

Creating Qr code with logo using zxing library. In the first place QR code (abbreviated from Quick Response Code) is the trademark for a type of matrix barcode (or two-dimensional barcode). Not to mention it’s first designed for the automotive industry in Japan. On the other hand a barcode is a machine-readable optical label that contains information about the item to which it is attached. In fact a QR code uses four standardized encoding modes (numeric, alphanumeric, byte/binary, and kanji) .To efficiently store data,extensions may also be used.

Here we are using zxing library to make the QR codes. But by default there are no company logos present there at center or any other part. Furthermore what you can do is create a QR code and on top of it draw the logo image of the company. In fact that’s exactly what we are going to do Creating qr code with logo and custom color. Above all include zxing core in your dependencies. Further information is available at previous post Qr Code Reader And Qr Code Generator for Android.

dependencies {
..............
.......
    compile 'com.google.zxing:core:3.3.0'
}

 

As a matter of fact a good amount of library’s are available for making Qr Code. Still it’s better to stick with native library’s or create your own library’s. Making Qr code with logo is good and bad at the same time. In fact it’s good for promoting and identifying and bad for some Qr readers, it wont read your code. As a result of trial and error generate combination of white, wherever white is that the background color just like the figure. Otherwise Qr readers will not acknowledge your code.

Download full source code here.

Furthermore consider the below figure. Accordingly first one is basic Qr code with low error correction level. Thus the second one is Qr code with custom logo, color and high error correction.

Setting parameters for Qr Code.

As a matter of fact Qr code require some parameters before creating. Accordingly data to encode, character set, error correction level, height and width. So data to encode is the string or message we pass. Then the character set  UTF-8 which is defined by Unicode. Finally error correction is an important aspect. Even so four types of error correction levels are present Level L(L), Level M(M), Level Q(Q) and Level H(H). Hence it can restore approximately  7% , 15% ,25% , 30% of code words respectively.

public void GenerateClick(View view){
        try {
            //setting size of qr code
            int width =300,height = 300;
            int smallestDimension = width < height ? width : height;

            EditText editText=(EditText)findViewById(R.id.editText) ;
            String qrCodeData = editText.getText().toString();
            //setting parameters for qr code
            String charset = "UTF-8"; 
            Map<EncodeHintType, ErrorCorrectionLevel> hintMap =new HashMap<EncodeHintType, ErrorCorrectionLevel>();
            hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            CreateQRCode(qrCodeData, charset, hintMap, smallestDimension, smallestDimension);

        } catch (Exception ex) {
            Log.e("QrGenerate",ex.getMessage());
        }
    }

Generating Qr Code.

Generated Qr code is in BitMatrix format so it’s convert to bitmap for our purpose. However custom color can be applied in the conversion process. At the same time where  BitMatrix to Bitmap take place. Furthermore that part is mentioned in the code with comments. Therefore read the comments to know what’s happening. Also the logo for merging is fetched here. To clarify actual process behind the conversion to bitmap is, Checking each bitmatrix pixel position by position. Thus the result is placed inside an integer array. Those results are checked before inserting .Data representing bit is placed with black and data nil bit is with white, but here its different because the black color is replaced with our custom color.

 public  void CreateQRCode(String qrCodeData, String charset, Map hintMap, int qrCodeheight, int qrCodewidth){
    

        try {
            //generating qr code.
            BitMatrix matrix = new MultiFormatWriter().encode(new String(qrCodeData.getBytes(charset), charset),
                    BarcodeFormat.QR_CODE, qrCodewidth, qrCodeheight, hintMap);
            //converting bitmatrix to bitmap

            int width = matrix.getWidth();
            int height = matrix.getHeight();
            int[] pixels = new int[width * height];
            // All are 0, or black, by default
            for (int y = 0; y < height; y++) {
                int offset = y * width;
                for (int x = 0; x < width; x++) {
                    //for black and white
                    //pixels[offset + x] = matrix.get(x, y) ? BLACK : WHITE;
                    //for custom color
                    pixels[offset + x] = matrix.get(x, y) ?
                            ResourcesCompat.getColor(getResources(),R.color.colorB,null) :WHITE;
                }
            }
            //creating bitmap
            Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
            
           //getting the logo 
            Bitmap overlay = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
            //setting bitmap to image view
            imageViewBitmap.setImageBitmap(mergeBitmaps(overlay,bitmap));

        }catch (Exception er){
            Log.e("QrGenerate",er.getMessage());
        }
    }

Combining Qr Code with logo.

Additionally two arguments are passed to this method both are Bitmap’s. In fact the bitmap object is for qr code and overlay is for logo. However don’t mix those. Or we get Qr code inside logo instead of Qr code with logo inside. However Matrix() class is from android.graphics.Matrix; . As a matter of fact it’s a simple process of combining qr code with logo by overlapping one above other.

public Bitmap mergeBitmaps(Bitmap overlay, Bitmap bitmap) {

        int height = bitmap.getHeight();
        int width = bitmap.getWidth();

        Bitmap combined = Bitmap.createBitmap(width, height, bitmap.getConfig());
        Canvas canvas = new Canvas(combined);
        int canvasWidth = canvas.getWidth();
        int canvasHeight = canvas.getHeight();

        canvas.drawBitmap(bitmap, new Matrix(), null);

        int centreX = (canvasWidth  - overlay.getWidth()) /2;
        int centreY = (canvasHeight - overlay.getHeight()) /2 ;
        canvas.drawBitmap(overlay, centreX, centreY, null);

        return combined;
    }

The entire code.

Instead of click listener button click is specified inside the xml file itself. As a result  length of code is reduced and it’s a good practice. Additionally object smallestDimension is for making square shaped qr code. While it holds the smallest value from width and height. Simultaneously all the methods can produce exceptions, In other word’s  each method need to be enclosed in try and catch.

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private ImageView imageViewBitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageViewBitmap=(ImageView)findViewById(R.id.imageViewBitmap);
    }
//handling button click
    public void GenerateClick(View view){
        try {
            //setting size of qr code
            int width =300;
            int height = 300;
            int smallestDimension = width < height ? width : height;

            EditText editText=(EditText)findViewById(R.id.editText) ;
            String qrCodeData = editText.getText().toString();
            //setting parameters for qr code
            String charset = "UTF-8"; 
            Map<EncodeHintType, ErrorCorrectionLevel> hintMap =new HashMap<EncodeHintType, ErrorCorrectionLevel>();
            hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            CreateQRCode(qrCodeData, charset, hintMap, smallestDimension, smallestDimension);

        } catch (Exception ex) {
            Log.e("QrGenerate",ex.getMessage());
        }
    }

    public  void CreateQRCode(String qrCodeData, String charset, Map hintMap, int qrCodeheight, int qrCodewidth){
       

        try {
            //generating qr code in bitmatrix type
            BitMatrix matrix = new MultiFormatWriter().encode(new String(qrCodeData.getBytes(charset), charset),
                    BarcodeFormat.QR_CODE, qrCodewidth, qrCodeheight, hintMap);
            //converting bitmatrix to bitmap

            int width = matrix.getWidth();
            int height = matrix.getHeight();
            int[] pixels = new int[width * height];
            // All are 0, or black, by default
            for (int y = 0; y < height; y++) {
                int offset = y * width;
                for (int x = 0; x < width; x++) {
                    //pixels[offset + x] = matrix.get(x, y) ? BLACK : WHITE;
                    pixels[offset + x] = matrix.get(x, y) ?
                            ResourcesCompat.getColor(getResources(),R.color.colorB,null) :WHITE;
                }
            }

            Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
            //setting bitmap to image view

            Bitmap overlay = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);

            imageViewBitmap.setImageBitmap(mergeBitmaps(overlay,bitmap));

        }catch (Exception er){
            Log.e("QrGenerate",er.getMessage());
        }
    }



    public Bitmap mergeBitmaps(Bitmap overlay, Bitmap bitmap) {

        int height = bitmap.getHeight();
        int width = bitmap.getWidth();

        Bitmap combined = Bitmap.createBitmap(width, height, bitmap.getConfig());
        Canvas canvas = new Canvas(combined);
        int canvasWidth = canvas.getWidth();
        int canvasHeight = canvas.getHeight();

        canvas.drawBitmap(bitmap, new Matrix(), null);

        int centreX = (canvasWidth  - overlay.getWidth()) /2;
        int centreY = (canvasHeight - overlay.getHeight()) /2 ;
        canvas.drawBitmap(overlay, centreX, centreY, null);

        return combined;
    }
}

activity_main.xml

After all the UI contain only basic views EditText, Button, ImageView all inside a LinearLayout with vertical orientation. Though you can see android:onClick="GenerateClick" which is for the method GenerateClick(View view).

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.logicchip.MainActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/editText"/>
        <Button
            android:onClick="GenerateClick"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Generate"/>
        <ImageView
            android:id="@+id/imageViewBitmap"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

</RelativeLayout>

 

Qr Code Reader And Qr Code Generator for Android

In the first place QR code (abbreviated from Quick Response Code) is the trademark for a type of matrix barcode (or two-dimensional barcode). Not to mention it’s first designed for the automotive industry in Japan. On the other hand a barcode is a machine-readable optical label that contains information about the item to which it is attached. In fact a QR code uses four standardized encoding modes (numeric, alphanumeric, byte/binary, and kanji) .To efficiently store data,extensions may also be used.

As a matter of fact the QR code system became popular outside the automotive industry. Due to its fast readability and greater storage capacity compared to standard UPC barcodes. Furthermore applications include product tracking, item identification, time tracking, document management, and general marketing.

However a QR code consists of black squares arranged in a square grid on a white background.

Which can be read by an imaging device such as a camera. And processed using Reed–Solomon error correction until the image can be appropriately interpreted. The required datum is then extracted from patterns that are present in both horizontal and vertical components of the image. Finally the source of this  information Wikipedia.

Explanation

However this tutorial is for reading and generating Qr code using zxing with simple step by step processes. ZXing (“zebra crossing”) is an open-source, multi-format 1D/2D barcode image processing library implemented in Java with ports to other languages. Its focus is on using the built-in camera on mobile phones to scan and decode barcodes on the device, without communicating with a server, though the library also supports use on a server. Similarly Qr code used in payment applications like paytm also in xender for connecting. Additionally BBM. This tutorial is divided in to three parts to explain.

  1. Activity for Navigation (MainActivity).
  2. Qr Code Generator Activity.
  3. Qr Code Reader Activity.

1- Activity for Navigation (MainActivity)

MainActiviy is only for navigation purpose. Then add the required library’s (dependencies ). com.google.zxing:core is for QR Code generating and me.dm7.barcodescanner:zxing is for QR Code scanner.

dependencies {
    compile 'com.google.zxing:core:3.3.0'
    compile 'me.dm7.barcodescanner:zxing:1.9'
    
}

In addition to dependencies permissions required are.

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Navigation activity contain only two methods readQr for reader and generateQr for generator activity. Similarly click is handled by onClick inside xml.

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

    public void readQr(View view){
        Intent intent=new Intent(MainActivity.this,QrRead.class);
        startActivity(intent);
    }
    public void generateQr(View view){
        Intent intent=new Intent(MainActivity.this,QrGenerate.class);
        startActivity(intent);
    }
}

Finally xml file for Navigation activity. However android:onClick="generateQr" and android:onClick="readQr" are for  methods generateQr(View view) and readQr(View view) accordingly.

activity_main.xml

?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.logicchip.blog_8_qrcode.MainActivity">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true">

        <Button
            android:text="Generate Qr Code"
            android:drawableRight="@drawable/ic_action_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="generateQr"
            android:id="@+id/button3" />

        <Button
            android:text="Read Qr Code"
            android:drawableRight="@drawable/ic_action_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:onClick="readQr"
            android:id="@+id/button4" />
    </LinearLayout>
</RelativeLayout>

2- Qr Code Generator Activity

First and foremost Generation of qr code using zxing take place here. However qrGenerator method contains basic properties for the qr code like height width character encoding etc. Another method createQRCode is where encoding take-place, and bitmetrix  is converted to bitmap. Then this bitmap is displayed inside the imageview.

QrGenerate.java

public class QrGenerate extends AppCompatActivity {

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



    public void qrGenerator(View v){
        try {
            //setting size of qr code
            WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE);
            Display display = manager.getDefaultDisplay();
            Point point = new Point();
            display.getSize(point);
            int width = point.x;
            int height = point.y;
            int smallestDimension = width < height ? width : height;

        EditText qrInput = (EditText) findViewById(R.id.qrInput);
        String qrCodeData = qrInput.getText().toString();
            //setting parameters for qr code
        String charset = "UTF-8"; // or "ISO-8859-1"
        Map<EncodeHintType, ErrorCorrectionLevel> hintMap =new HashMap<EncodeHintType, ErrorCorrectionLevel>();
        hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
        createQRCode(qrCodeData, charset, hintMap, smallestDimension, smallestDimension);

        } catch (Exception ex) {
            Log.e("QrGenerate",ex.getMessage());
        }
    }

    public  void createQRCode(String qrCodeData,String charset, Map hintMap, int qrCodeheight, int qrCodewidth){
        
        try {
            //generating qr code in bitmatrix type
            BitMatrix matrix = new MultiFormatWriter().encode(new String(qrCodeData.getBytes(charset), charset), BarcodeFormat.QR_CODE, qrCodewidth, qrCodeheight, hintMap);
            //converting bitmatrix to bitmap
            int width = matrix.getWidth();
            int height = matrix.getHeight();
            int[] pixels = new int[width * height];
            // All are 0, or black, by default
            for (int y = 0; y < height; y++) {
                int offset = y * width;
                for (int x = 0; x < width; x++) {
                    pixels[offset + x] = matrix.get(x, y) ? BLACK : WHITE;
                }
            }

            Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
            //setting bitmap to image view
            ImageView myImage = (ImageView) findViewById(R.id.imageView1);
            myImage.setImageBitmap(bitmap);
        }catch (Exception er){
            Log.e("QrGenerate",er.getMessage());
        }
    }

}

Also Ui for Qr Generator is given below.

activity_qr_generate.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_qr_generate"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.logicchip.blog_8_qrcode.QrGenerate">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <EditText
            android:hint="Text here...."
            android:id="@+id/qrInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10">
            <requestFocus />
        </EditText>
        <Button
            android:id="@+id/button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Generate QR Code"
            android:onClick="qrGenerator"/>
        <ImageView
            android:layout_gravity="center_horizontal"
            android:id="@+id/imageView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
</RelativeLayout>

3- Qr Code Reader Activity

Reader class extents Activity and implements ZXingScannerView.ResultHandler. In other words me.dm7.barcodescanner.zxing is used. In detail it’s an Android library projects that provides easy to use and extensible Barcode Scanner views based on ZXing and ZBar. QrReader.java is an activity but don’t have an xml. As a result ZXingScannerView act as the ui, providing the Camera preview. We have to include the activity file for reader class in the manifest file otherwise it will result in crashing.

QrReader.java

import android.app.Activity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import com.google.zxing.Result;
import me.dm7.barcodescanner.zxing.ZXingScannerView;

/**
 * Created by akhil on 28-12-16.
 */

public class QrReader extends Activity implements ZXingScannerView.ResultHandler {
    private ZXingScannerView mScannerView;
    String TAG="QRREADER";

    @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);
        mScannerView = new ZXingScannerView(this);   // Programmatically initialize the scanner view
        setContentView(mScannerView);                // Set the scanner view as the content view
    }

    @Override
    public void onResume() {
        super.onResume();
        mScannerView.setResultHandler(this); // Register ourselves as a handler for scan results.
        mScannerView.startCamera();          // Start camera on resume
    }

    @Override
    public void onPause() {
        super.onPause();
        mScannerView.stopCamera();           // Stop camera on pause
    }

    @Override
    public void handleResult(Result rawResult) {
        // Do something with the result here
        Log.v(TAG, rawResult.getText()); // Prints scan results
        Log.v(TAG, rawResult.getBarcodeFormat().toString()); // Prints the scan format (qrcode, pdf417 etc.)

        // call the alert dialog
        Alert(rawResult);

    }


    public void Alert(Result rawResult){
        AlertDialog.Builder builder = new AlertDialog.Builder(QrRead.this);
        builder.setTitle("Qr scan result");
        builder.setMessage("Result :"+rawResult.getText()+"\nType :"+rawResult.getBarcodeFormat().toString())
                .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        // back to previous activity
                        finish();

                    }
                })
                .setNegativeButton("Scan Again", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        // User cancelled the dialog
// If you would like to resume scanning, call this method below:
                        mScannerView.resumeCameraPreview(QrRead.this);
                    }
                });
        // Create the AlertDialog object and return it
        builder.create().show();
    }
}

Manifest for the application.

The application require permission for camera and storage. Some times the storage permission is not required because the file is never actually saved.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.logicchip.blog_8_qrcode">

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".QrRead"></activity>
        <activity android:name=".QrGenerate"
            android:label="@string/qr_generate"></activity>
    </application>

</manifest>

If you have any questions or queries drop it in the comments below.Download Source code here

Android Splash Screen With Progress Bar

A splash screen is a graphical control element consisting of window containing an image,  logo and the current version of the software. Splash screen usually appears while a game or program is launching. A Splash screened are typically used by particularly large applications to notify the user that the program is in the process of loading. They provide feedback that a lengthy process is underway. Occasionally, a progress bar within the splash screen indicates the loading progress. The splash disappears when the application’s main window appears. Source: Wikipedia. Else we can use it for making the app more attractive. You can find tutorials in splash screen for android all over the internet. Only few that works without the blank screen while launching. I found a perfect example for proper splash screen from bignerdranch.com.

Progress bar is used in this example and can be changed according to the work done. We are creating two activity’s. One for displaying flash and another is the landing activity. The page after splash screen. This can be explained in four steps.

  1. Creating the xml file for the splash screen.
  2.  Creating the theme for splash activity.
  3. Applying the theme for splash activity.
  4. Background tasks to be done while displaying progress bar and splash screen.

 

 

Fourth one is for class files to show progress and load next page after progress bar reach 100% .



 1 – Creating XML file for the splash screen and splash activity

For this first create a xml file in the drawable. Mine is "splash.xml",ic_launcher is the splash image.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="100dp"
    android:layout_height="100dp">
    <item
        android:drawable="@android:color/background_light"/>
    <item >
        <bitmap
            android:gravity="center"
            android:filter="true"
            android:src="@drawable/ic_launcher"/>
    </item>

</layer-list>

Below is the xml file for Splash activity.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_splash"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.logicchip.blog_7_proper_splash_screen.Splash">


    <ProgressBar
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="50dp"
        android:id="@+id/progressBar" />

    <TextView
        android:textSize="40sp"
        android:textColor="@android:color/holo_red_light"
        android:text="TextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/progressBar"
        android:layout_centerHorizontal="true"
        android:id="@+id/textView" />
</RelativeLayout>



2 – Creating the Theme for splash activity

Theme is an important element. Edit your styles.xml file and add the SplashTheme part.

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <!--splash theme start-->
    <style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowBackground">@drawable/splash</item>
    </style>
    <!--splash theme end-->

</resources>

3 – Applying the theme for splash activity

Setting theme for the specified splash activity. Just edit AndroidManifest.xml file and replace the laucher activity theme with SplashTheme.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.logicchip.blog_7_proper_splash_screen">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".Splash"
            android:theme="@style/SplashTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".MainActivity">
        </activity>
    </application>

</manifest>

4 – Tasks for progress bar and loading next activity

Two activity’s are created Splash.java and MainActivity.java. Splash.java is the splash activity,handling the splash and progress of progress bar. MainActivity.java is the landing page. Inside the code the part runOnUiThread  is used to modify the TextView component. Ui components modification is possible only on ui thread. Otherwise app crashes.

 runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            textView.setText(String.valueOf(i)+"%");
                        }
                    });

Time period is set to 100 ms. Run method inside the thread executes every 100 ms. It only stops when timer.cancel(); called . If you don’t call timer.cancel(); the process continues to execute leading to system hang or crash.

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.util.Timer;
import java.util.TimerTask;

public class Splash extends AppCompatActivity{
    private Timer timer;
    private ProgressBar progressBar;
    private int i=0;
    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);
        progressBar=(ProgressBar)findViewById(R.id.progressBar);
        progressBar.setProgress(0);
        textView=(TextView)findViewById(R.id.textView);
        textView.setText("");

        final long period = 100;
        timer=new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                //this repeats every 100 ms
                if (i<100){
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            textView.setText(String.valueOf(i)+"%");
                        }
                    });
                    progressBar.setProgress(i);
                    i++;
                }else{
                    //closing the timer
                    timer.cancel();
                    Intent intent =new Intent(Splash.this,MainActivity.class);
                    startActivity(intent);
                    // close this activity
                    finish();
                }
            }
        }, 0, period);
    }

}
You can download full code from here, You can modify the code us u like. In like manner feel free to comment your doubt’s below. Does our tutorials help you then help as spread the word, like and share.

Notification for android

A notification is a message you can display to the user outside of your application’s normal UI. When you tell the system to issue a notification, it first appears as an icon in the notification area.In order to see the details, the user opens the notification drawer. Both the notification area and the drawer are system-controlled areas that the user can view at any time more can be found here.

 

We can update the current notification shown or create a new one . These two things can be achieved very easily.




 

 

The NotificationManager require a key for starting, if we use the same key over and over it updates the current notification with the same key.

 

 

In the case of using another key for NotificationManager it creates new notification instance. Like the figure.

It also contains additional items. Sound (default or assigned tone),Vibration (control duration and pattern of vibration),Light(color and blinking delay are  controlled ) and Time (display given time) are among it

 

Creating the object

 

Notification mNotification = new NotificationCompat.Builder(this)

This code creates the object, Next part is the tittle ticker. Ticker is created using .setTicker("Ticker heading"). Ticker is the heading that displays along with the icon in notification area.




Below is an example method for notification.

public void singleNotification(){
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pi = PendingIntent.getActivity(this, 0,intent, PendingIntent.FLAG_UPDATE_CURRENT);
        //for vibration
        longs=new long[] { 1000, 1000};
        //for led color
        color=Color.BLUE;
        Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.InboxStyle inboxStyle =new NotificationCompat.InboxStyle();
        inboxStyle.setBigContentTitle("Logicchip");

        // Moves events into the expanded layout
        arraySingleList=new ArrayList();
        arraySingleList.add("logicchip a");
        arraySingleList.add("logicchip b");
        arraySingleList.add("logicchip c");
        for (int i=arraySingleList.size(); i >0; i--) {
            inboxStyle.addLine(arraySingleList.get(i-1).toString());
        }
        Bitmap largeIcon = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher);
        Notification mNotification = new NotificationCompat.Builder(this)
                .setTicker("Ticker logicchip")
                .setContentTitle(String.valueOf(keyForSingleNotification)+" Content Tittle Logicchip")
                .setLargeIcon(largeIcon)
                .setContentText("Content Text Logicchips")
                .setContentInfo(String.valueOf(arraySingleList.size()))
                .setSmallIcon(R.mipmap.ic_launcher)//icon
                .setContentIntent(pi)
                .setVibrate(longs)                                          //for vibration set pattern time
                .setNumber(arraySingleList.size()) //showing number
                .setSubText(String.valueOf(arraySingleList.size())+" New updates")//for single line text
                .setLights(color,2000, 2000)//led blinking
                .setSound(uri)//for notification tone
                .setStyle(inboxStyle)//for changing updates
                .setAutoCancel(true)
                .setWhen(System.currentTimeMillis())//showing time
                .build();
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        notificationManager.notify(keyForSingleNotification++, mNotification);
    }

The intent is for displaying the result, It can be explained. When we click the notification it opens the activity mentioned in PendingIntent. Each notification can only open one activity.

The next method shows the updating notification.

    public void showNotification() {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pi = PendingIntent.getActivity(this, 0,intent, PendingIntent.FLAG_UPDATE_CURRENT);
        //for vibration
        longs=new long[] { 1000, 1000};
        //for led color
        color=Color.BLUE;
        Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.InboxStyle inboxStyle =new NotificationCompat.InboxStyle();
        inboxStyle.setBigContentTitle("Logicchip");

        // Moves events into the expanded layout
        arrayList.add("logicchip "+arrayList.size());
        for (int i=arrayList.size(); i >0; i--) {
            inboxStyle.addLine(arrayList.get(i-1).toString());
        }
        Bitmap largeIcon = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher);
        Notification mNotification = new NotificationCompat.Builder(this)
                .setTicker("Ticker logicchip")
                .setContentTitle("Content Titile Logicchip")
                .setLargeIcon(largeIcon)
                .setContentText("Content Text Logicchips")
                .setContentInfo(String.valueOf(arrayList.size()))
                .setSmallIcon(R.mipmap.ic_launcher)//icon
                .setContentIntent(pi)
                .setVibrate(longs)                                          //for vibration set pattern time
                .setNumber(arrayList.size()) //showing number
                .setSubText(String.valueOf(arrayList.size())+" New updates")//for single line text
                .setLights(color,2000, 2000)//led blinking
                .setSound(uri)//for notification tone
                .setStyle(inboxStyle)//for changing updates
                .setAutoCancel(true)
                .setWhen(System.currentTimeMillis())//showing time
                .build();
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        notificationManager.notify(keyForNotification, mNotification);
    }

you can see by comparing the two methods keyForNotification and keyForSingleNotification++. Where keyForNotification is for updating notifications and keyForSingleNotification++ is for individual notifications.

The full code is displayed below with xml file.

 

MainActivity.java

 

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements View.OnClickListener,Runnable {
    private CoordinatorLayout coordinatorLayout;
    private ArrayList arrayList=new ArrayList(),arraySingleList;
    private int keyForNotification=0,keyForSingleNotification=0;
    private long[] longs;
    private int color;
    private Thread thread;
    private Button buttonThread,buttonSingle,buttonMulti;
    private boolean oN=false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        buttonThread=(Button)findViewById(R.id.buttonThread);
        buttonSingle=(Button)findViewById(R.id.buttonSingle);
        buttonMulti=(Button)findViewById(R.id.buttonMulti);
        buttonThread.setOnClickListener(this);
        buttonSingle.setOnClickListener(this);
        buttonMulti.setOnClickListener(this);
    }




    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.buttonThread:

                if(oN){
                    thread=null;
                    oN=false;
                    buttonThread.setText("start");
                }else {
                    thread = new Thread(this);
                    thread.start();
                    oN=true;
                    buttonThread.setText("stop");
                }
                break;
            case R.id.buttonSingle:
                singleNotification();
                break;
            case R.id.buttonMulti:
                showNotification();
                break;
        }

    }


    public void showNotification() {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pi = PendingIntent.getActivity(this, 0,intent, PendingIntent.FLAG_UPDATE_CURRENT);
        //for vibration
        longs=new long[] { 1000, 1000};
        //for led color
        color=Color.BLUE;
        Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.InboxStyle inboxStyle =new NotificationCompat.InboxStyle();
        inboxStyle.setBigContentTitle("Logicchip");

        // Moves events into the expanded layout
        arrayList.add("logicchip "+arrayList.size());
        for (int i=arrayList.size(); i >0; i--) {
            inboxStyle.addLine(arrayList.get(i-1).toString());
        }
        Bitmap largeIcon = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher);
        Notification mNotification = new NotificationCompat.Builder(this)
                .setTicker("Ticker logicchip")
                .setContentTitle("Content Titile Logicchip")
                .setLargeIcon(largeIcon)
                .setContentText("Content Text Logicchips")
                .setContentInfo(String.valueOf(arrayList.size()))
                .setSmallIcon(R.mipmap.ic_launcher)//icon
                .setContentIntent(pi)
                .setVibrate(longs)                                          //for vibration set pattern time
                .setNumber(arrayList.size()) //showing number
                .setSubText(String.valueOf(arrayList.size())+" New updates")//for single line text
                .setLights(color,2000, 2000)//led blinking
                .setSound(uri)//for notification tone
                .setStyle(inboxStyle)//for changing updates
                .setAutoCancel(true)
                .setWhen(System.currentTimeMillis())//showing time
                .build();
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        notificationManager.notify(keyForNotification, mNotification);
    }

    public void singleNotification(){
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pi = PendingIntent.getActivity(this, 0,intent, PendingIntent.FLAG_UPDATE_CURRENT);
        //for vibration
        longs=new long[] { 1000, 1000};
        //for led color
        color=Color.BLUE;
        Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.InboxStyle inboxStyle =new NotificationCompat.InboxStyle();
        inboxStyle.setBigContentTitle("Logicchip");

        // Moves events into the expanded layout
        arraySingleList=new ArrayList();
        arraySingleList.add("logicchip a");
        arraySingleList.add("logicchip b");
        arraySingleList.add("logicchip c");
        for (int i=arraySingleList.size(); i >0; i--) {
            inboxStyle.addLine(arraySingleList.get(i-1).toString());
        }
        Bitmap largeIcon = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher);
        Notification mNotification = new NotificationCompat.Builder(this)
                .setTicker("Ticker logicchip")
                .setContentTitle(String.valueOf(keyForSingleNotification)+" Content Tittle Logicchip")
                .setLargeIcon(largeIcon)
                .setContentText("Content Text Logicchips")
                .setContentInfo(String.valueOf(arraySingleList.size()))
                .setSmallIcon(R.mipmap.ic_launcher)//icon
                .setContentIntent(pi)
                .setVibrate(longs)                                          //for vibration set pattern time
                .setNumber(arraySingleList.size()) //showing number
                .setSubText(String.valueOf(arraySingleList.size())+" New updates")//for single line text
                .setLights(color,2000, 2000)//led blinking
                .setSound(uri)//for notification tone
                .setStyle(inboxStyle)//for changing updates
                .setAutoCancel(true)
                .setWhen(System.currentTimeMillis())//showing time
                .build();
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        notificationManager.notify(keyForSingleNotification++, mNotification);
    }


    @Override
    public void run() {
        Thread thisThread = Thread.currentThread();
        while (thread == thisThread) {
                try {
                    Thread.sleep(3000);
                    showNotification();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    }
}

 

activity_main.xml

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/content_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="logicchip.blog_6_notifiaction.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="center"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="start"
            android:id="@+id/buttonThread" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Single"
            android:id="@+id/buttonSingle" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Multi"
            android:id="@+id/buttonMulti" />
    </LinearLayout>
</RelativeLayout>

You must add permission for VIBRATION. Add this to the AndroidManifest.xml file.

<uses-permission android:name="android.permission.VIBRATE"></uses-permission>

Don’t hesitate to comment below if you have any questions or doubts.

Tab View Inside Navigation Drawer for android

To create a project that displays Tab View inside navigation drawer selection. By simple step by step process. It’s simple to combine tab view inside navigation drawer. First start by creating a “Navigation Drawer Activity” in android studio (assuming you are aware of those things). Second part is to create a fragments to handle the navigation drawer activities.

This flow chart may help you to better understand what we want to achieve.

FragmentA contains the Tablayout (Tab View) and view pager, the navigation drawer pass id to FragmentA it displays tabs and content to be displayed in the viewpager according to the navigation drawer and tab selected. In this case the id passed is the name of navigation drawer menu.

This project contains.

MainActivity.java => Navigation Drawer Activity.

FragmentA.java => Fragment containing Tab View.

FragmentB.java => Fragment for viewpager.

FragmentC.java => Fragment for running first and menu without tabs.

Constants.java => Class file for keeping constant values.

SectionsPageAdapter.java => It’s a Fragment Page Adapter to handle FragmentB from FragmentA.

OnFragmentInteractionListener.java => for handling communication between Fragment and parent activity.

Below is a simple step by step explanation.


1.Constants.java

 

This class contain only key values for passing data to fragments.

public class Constants {
    public final static String FRAG_A="fragment_a";
    public final static String FRAG_B="fragment_b";
    public final static String FRAG_C="fragment_c";
}

 

2.OnFragmentInteractionListener.java

 

A simple interface for communicating between fragments and parent activity.

public interface OnFragmentInteractionListener {
    public void onFragmentMessage(int TAG, String data);
}

 

3. FragmentC.java

 

This fragment is only for displaying message of those menu that don’t have any tabs. The arguments are the name of navigation menu name (id).

public class FragmentC extends Fragment {

    private OnFragmentInteractionListener mListener;
    private TextView text_view_for_normal_selection;

    public FragmentC() {
        // Required empty public constructor
    }

    public static FragmentC newInstance(String normalText) {
        FragmentC fragment = new FragmentC();
        Bundle args = new Bundle();
        args.putString(Constants.FRAG_C, normalText);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view =  inflater.inflate(R.layout.fragment_c, container, false);
        text_view_for_normal_selection=(TextView)view.findViewById(R.id.text_view_for_normal_selection);
        text_view_for_normal_selection.setText(getArguments().getString(Constants.FRAG_C));
        return view;
    }


    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }


    @Override
    public void onResume() {
        super.onResume();
    }
}

fragment_c.xml

<FrameLayout 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="logicchip.tabwithnavigation.FragmentC">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:layout_gravity="center"
        android:textColor="@color/colorAccent"
        android:id="@+id/text_view_for_normal_selection"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>



 

4. FragmentB.java

 

FragmentB is for displaying the contents of the tab selected. The arguments are the name of the selected tabs (id).

public class FragmentB extends Fragment {

    private OnFragmentInteractionListener mListener;
    private TextView text_view_for_tab_selection;

    public FragmentB() {
        // Required empty public constructor
    }


    public static FragmentB newInstance(String tabSelected) {
        FragmentB fragment = new FragmentB();
        Bundle args = new Bundle();
        args.putString(Constants.FRAG_B, tabSelected);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_b, container, false);
        text_view_for_tab_selection=(TextView)view.findViewById(R.id.text_view_for_tab_selection);
        text_view_for_tab_selection.setText(getArguments().getString(Constants.FRAG_B));
        return view;
    }



    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    @Override
    public void onResume() {
        super.onResume();
    }
}

fragment_b.xml

<FrameLayout 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="logicchip.tabwithnavigation.FragmentB">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:textColor="@color/colorAccent"
        android:layout_gravity="center"
        android:id="@+id/text_view_for_tab_selection"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>

 

5. SectionsPageAdapter.java

 

This class file is an adapter for handling instance of tabs selected, which displays contents of FragmentB according to the tab selected. It extents FragmentPagerAdapter class.

public class SectionsPagerAdapter extends FragmentPagerAdapter {

    int mNumOfTabs;
    ArrayList<String> tabName;

    public SectionsPagerAdapter(FragmentManager fm, int NumOfTabs, ArrayList<String> tabName) {
        super(fm);
        this.mNumOfTabs = NumOfTabs;
        this.tabName=tabName;
    }

    @Override
    public Fragment getItem(int position) {
        FragmentB comn=new FragmentB();
        return comn.newInstance(tabName.get(position));
    }

    @Override
    public int getCount() {
        return mNumOfTabs;
    }
}

 

6. FragmentA.java

 

This fragment contains tablayout and viewpager. FragmentB is displayed inside viewpager. FragmentA is placed inside the parent activity, so when clicking a menu item it displays Parent Activity and inside it FragmentA with Tabs and Viewpager also FragmentB inside Viewpager.
This figure shows how it’s implemented.

 

public class FragmentA extends Fragment {

    private TabLayout tabLayout;
    private ViewPager mViewPager;
    private OnFragmentInteractionListener mListener;
    private SectionsPagerAdapter mSectionsPagerAdapter;
    ArrayList<String> tabName;

    public FragmentA() {
        // Required empty public constructor
    }
    public static FragmentA newInstance(String navigation) {
        FragmentA fragment = new FragmentA();
        Bundle args = new Bundle();
        args.putString(Constants.FRAG_A, navigation);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_a, container, false);
        tabLayout = (TabLayout)view.findViewById(R.id.tabs);
        mViewPager = (ViewPager)view.findViewById(R.id.container);
        tabName=new ArrayList<String>();
        for(int i=0;i<7;i++){
            tabLayout.addTab(tabLayout.newTab().setText(getArguments().getString(Constants.FRAG_A)+" "+String.valueOf(i)));
            tabName.add(getArguments().getString(Constants.FRAG_A)+" "+String.valueOf(i));
        }
        tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
        mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager(),tabLayout.getTabCount(),tabName);
        mViewPager.setAdapter(mSectionsPagerAdapter);
        mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                mViewPager.setCurrentItem(tab.getPosition());
                getChildFragmentManager().beginTransaction().addToBackStack(null).commit();
            }
            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
            }
            @Override
            public void onTabReselected(TabLayout.Tab tab) {
            }
        });
        return view;
    }


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        // Note that we are passing childFragmentManager, not FragmentManager
        mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager(),tabLayout.getTabCount(),tabName);
        mViewPager.setAdapter(mSectionsPagerAdapter);

    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }


    @Override
    public void onResume() {
        super.onResume();
    }

}

fragment_a.xml

<FrameLayout 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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context="logicchip.tabwithnavigation.FragmentA">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay"
            android:theme="@style/AppTheme.AppBarOverlay"/>

        <android.support.v4.view.ViewPager
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

    </LinearLayout>

</FrameLayout>

 

7. MainActivity.java

The mainactivity.java is the launcher activity (parent activity) it implements navigation item selected listener and OnFragmentInteractionListener (our 2nd step mentioned above). Coding take place in the “onNavigationItemSelected (MenuItem item)” method, handling the menu items clicks. Another method name “homeFragment ()” is also created to display when starting up otherwise we get a blank screen when starting. Back pressed method “onBackPressed ()” is slightly modified to handle back click for selected drawer menu item. All the other things we need are already included in the template “Navigation Drawer Activity in Android Studio”.
Because it’s Navigation Drawer it contains more than one xml file.

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener,OnFragmentInteractionListener {
    private CoordinatorLayout coordinatorLayout;
    private ActionBarDrawerToggle toggle;
    private boolean mToolBarNavigationListenerIsRegistered = false;
    private FloatingActionButton fab;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        coordinatorLayout=(CoordinatorLayout)findViewById(R.id.coordinatorLayout);

        fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            SnackBarMessage("Happy coding.");
            }
        });

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
        homeFragment();
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else if(getFragmentManager().getBackStackEntryCount()>0){
            getFragmentManager().popBackStack();
        }else{
            super.onBackPressed();
        }
    }


    public void SnackBarMessage(String message){
        Snackbar.make(coordinatorLayout, message, Snackbar.LENGTH_LONG).setAction("Action", null).show();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();
        Fragment fragment = null;
        Class fragmentClass = null;
        Bundle args = new Bundle();

        switch (id){
            case R.id.nav_1:fragmentClass =FragmentA.class;args.putString(Constants.FRAG_A,"Import");break;
            case R.id.nav_2:fragmentClass =FragmentA.class;args.putString(Constants.FRAG_A,"Gallery");break;
            case R.id.nav_3:fragmentClass =FragmentA.class;args.putString(Constants.FRAG_A,"Slideshow");break;
            case R.id.nav_4:fragmentClass =FragmentA.class;args.putString(Constants.FRAG_A,"Tools");break;
            case R.id.nav_5:fragmentClass =FragmentC.class;args.putString(Constants.FRAG_C,"Share");break;
            case R.id.nav_6:fragmentClass =FragmentC.class;args.putString(Constants.FRAG_C,"Send");break;
        }
        try {
            fragment = (Fragment) fragmentClass.newInstance();
            fragment.setArguments(args);
            // Insert the fragment by replacing any existing fragment
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.fragment_layout_for_activity_navigation, fragment).addToBackStack(null).commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    @Override
    public void onFragmentMessage(int TAG, String data) {

    }

    public void homeFragment(){
        try {
            Bundle args = new Bundle();
            Class fragmentClass =FragmentC.class;args.putString(Constants.FRAG_C,"Welcome");
            Fragment fragment = (Fragment) fragmentClass.newInstance();
            fragment.setArguments(args);
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.fragment_layout_for_activity_navigation, fragment).commit();

        } catch (Exception e) {
            e.printStackTrace();
        }
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
    }
}

app_bar_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:id="@+id/coordinatorLayout"
    tools:context="logicchip.tabwithnavigation.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>
    <!--
       <include layout="@layout/content_main" />
    -->
    <FrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:context="logicchip.tabwithnavigation.MainActivity"
        tools:showIn="@layout/app_bar_main"
        android:id="@+id/fragment_layout_for_activity_navigation" >

    </FrameLayout>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:srcCompat="@android:drawable/btn_star_big_on" />

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

Download full source code for free