Tuesday, February 2, 2016

Adding SMS Verification Like WhatsApp to Android Application Part-I

In my last articles i.e creating-rest-api-to-generate-otp-part-2 and creating-rest-api-to-generate-otp-part-1 you have learnt how to create the REST API to generate the OTP and get it verified through the website.

Now we will create an android app for which registration process is going to use this RESR API to get the use registered.

In this, I am going to use Volley Librbary to make http class. We will discuss more about this volley library in another article. Also before going through this article you need to have basic knowledge about Android Service, Broadcast receivers and intent service

In  this project, we are going to use broadcast receiver to read the SMS whenever the device receives the OTP And an Intent Service to execute the http request to send the received OTP back to server and get it verified.

Creating the  Android Application

1. In Android Studio, create a new project by navigating to File ⇒ New Project and fill all the required details. When it prompts to select a default activity, select Blank Activity and proceed.









2. Press the finish button to create the project. This creates the android project SMSVerify

3. Open build.gradle located under Gradle Scripts folder and add volley library dependency by adding 'com.mcxiaoke.volley:library-aar:1.0.0'



4. Open strings.xml located under res ⇒ values and add below string values.
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">SMSVerify</string>
    <string name="action_settings">Settings</string>
    <string name="title_activity_sms">SMSVerify</string>
    <string name="action_logout">Logout</string>
    <string name="msg_enter_mobile">Enter your mobile number to get started!</string>
    <string name="lbl_name">Name</string>
    <string name="lbl_email">Email</string>
    <string name="lbl_mobile">Mobile</string>
    <string name="lbl_next">NEXT</string>
    <string name="msg_sit_back">Sit back &amp; Relax! while we verify your mobile number</string>
    <string name="msg_manual_otp">(Enter the OTP below in case if we fail to detect the SMS automatically)</string>
    <string name="lbl_enter_otp">Enter OTP</string>
    <string name="lbl_submit">SUBMIT</string>
</resources>
5. Open colors.xml located under res ⇒ values and add below color values.
<?xml version="1.0" encoding="utf-8"?><resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="textColorPrimary">#FFFFFF</color>
    <color name="windowBackground">#FFFFFF</color>
    <color name="navigationBarColor">#000000</color>
    <color name="bg_view_sms">#ffd423</color>
    <color name="bg_view_otp">#fc6d38</color>

</resources>
6. Now open styles.xml located under res ⇒ values and add below styles.

<resources>
    
<style name="MyMaterialTheme" parent="MyMaterialTheme.Base">
    </style>
    <style name="MyMaterialTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
</resources
7. Under res directory, create a folder named values-v21. In this folder create another styles.xml and add below code.
<resources>
    <style name="MyMaterialTheme" parent="MyMaterialTheme.Base">
        <item name="android:windowContentTransitions">true</item>
        <item name="android:windowAllowEnterTransitionOverlap">true</item>
        <item name="android:windowAllowReturnTransitionOverlap">true</item>
        <item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
        <item name="android:windowSharedElementExitTransition">@android:transition/move</item>
    </style>
</resources>
8. Finally open the AndroidManifest.xml and add the MyMaterialTheme to <application> tag.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"   
 package="marutsoft.com.smsverify">

    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:supportsRtl="true"        android:theme="@style/MyMaterialTheme">
        .
        .
    </application>
</manifest
9.  Now create five packages named activityapphelperreceiver and service. These packages helps in keeping the project organized.
10. Under app package, create a class named Config.java. This class contains very important app configuration information


/** * Created by Karjol G T on 01-02-2016. */

public class Config {

    // server URL configuration    
public static final String URL_REQUEST_SMS = "http://192.168.0.3/OTP_SMS/request_sms.php";
    public static final String URL_VERIFY_OTP =  "http://192.168.0.3/OTP_SMS/verify_otp.php";

    public static final String SMS_ORIGIN = "SWNAND";

    // special character to prefix the otp. Make sure this character appears only once in the sms    public static final String OTP_DELIMITER = ":";
}
11. Under app package, create a class named MyApplication.java. This class initiates the volley core objects. This class extends from Application class which should be added in your AndroidManifest.xml<application> tag.
package marutsoft.com.smsverify.app;

import android.app.Application;
import android.text.TextUtils;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;

/** * Created by Karjol G T on 01-02-2016. */
public class MyApplication extends Application {
    public static final String TAG = MyApplication.class            
                 .getSimpleName();

    private RequestQueue mRequestQueue;

    private static MyApplication mInstance;

    @Override    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }

    public static synchronized MyApplication getInstance() {
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }

        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req, String tag) {
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(req);
    }

    public <T> void addToRequestQueue(Request<T> req) {
        req.setTag(TAG);
        getRequestQueue().add(req);
    }

    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }

}
12.  Open the AndroidManifest.xml and add the MyApplication to <application> tag.
13.  In helper package, create a class named MyViewPager.java. This is a custom ViewPager class where we disable the swipe functionality of it.
package marutsoft.com.smsverify.helper;

/** * Created by Karjol G T on 01-02-2016. */import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;

public class MyViewPager extends ViewPager {

    public MyViewPager(Context context) {
        super(context);
    }

    public MyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override    public boolean onInterceptTouchEvent(MotionEvent event) {
        // Never allow swiping to switch between pages        return false;
    }

    @Override    public boolean onTouchEvent(MotionEvent event) {
        // Never allow swiping to switch between pages        return false;
    }
}
14. Create a class named PrefManager.java under helper package. This class contains methods to store user information in Shared Preferences.
package marutsoft.com.smsverify.helper;

/** * Created by Karjol G T on 01-02-2016. */import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import java.util.HashMap;

public class PrefManager {


    SharedPreferences pref;

    // Editor for Shared preferences    Editor editor;

    // Context    Context _context;

    // Shared pref mode    int PRIVATE_MODE = 0;

    // Shared preferences file name    private static final String PREF_NAME = "AndroidHive";

    // All Shared Preferences Keys    private static final String KEY_IS_WAITING_FOR_SMS = "IsWaitingForSms";
    private static final String KEY_MOBILE_NUMBER = "mobile_number";
    private static final String KEY_IS_LOGGED_IN = "isLoggedIn";
    private static final String KEY_NAME = "name";
    private static final String KEY_EMAIL = "email";
    private static final String KEY_MOBILE = "mobile";

    public PrefManager(Context context) {
        this._context = context;
        pref = _context.getSharedPreferences(PREF_NAME, PRIVATE_MODE);
        editor = pref.edit();
    }

    public void setIsWaitingForSms(boolean isWaiting) {
        editor.putBoolean(KEY_IS_WAITING_FOR_SMS, isWaiting);
        editor.commit();
    }

    public boolean isWaitingForSms() {
        return pref.getBoolean(KEY_IS_WAITING_FOR_SMS, false);
    }

    public void setMobileNumber(String mobileNumber) {
        editor.putString(KEY_MOBILE_NUMBER, mobileNumber);
        editor.commit();
    }

    public String getMobileNumber() {
        return pref.getString(KEY_MOBILE_NUMBER, null);
    }

    public void createLogin(String name, String email, String mobile) {
        editor.putString(KEY_NAME, name);
        editor.putString(KEY_EMAIL, email);
        editor.putString(KEY_MOBILE, mobile);
        editor.putBoolean(KEY_IS_LOGGED_IN, true);
        editor.commit();
    }

    public boolean isLoggedIn() {
        return pref.getBoolean(KEY_IS_LOGGED_IN, false);
    }

    public void clearSession() {
        editor.clear();
        editor.commit();
    }

    public HashMap<String, String> getUserDetails() {
        HashMap<String, String> profile = new HashMap<>();
        profile.put("name", pref.getString(KEY_NAME, null));
        profile.put("email", pref.getString(KEY_EMAIL, null));
        profile.put("mobile", pref.getString(KEY_MOBILE, null));
        return profile;
    }
}
The Remaining part, we will continue in next Part II of this blog.

No comments: