Scan QRCode and Save it in Google Sheet using Google App Script

This tutorial explains about storing QR code scanned data in Google Spread Sheet. This is very simple application which uses Zxing Qr code api, Android http client and Goolge App script.

 

Here It consists of 2 Parts,

Google App Script Part (Back End)
Android Part (Front End)

   Download Source Code

 

1.Google App Script Part
Step 1: Create new app script project. Click here to create App Script.

Step 2: Copy and paste the below script which recieves scanned data  and inserts in Google Sheet.

 

function doGet(e){

  var ss = SpreadsheetApp.openByUrl("Your Spread Sheet URL");
  var sheet = ss.getSheetByName("Sheet1");
 return insert(e,sheet);


}

function doPost(e){
  var ss = SpreadsheetApp.openByUrl("Your Spread Sheet URL");
  var sheet = ss.getSheetByName("Sheet1");
  return insert(e,sheet);

}

function insert(e,sheet) {

  var scannedData = e.parameter.sdata;
 var d = new Date();
  var ctime =  d.toLocaleString();
  
  sheet.appendRow([scannedData,ctime]);
  
  return ContentService
  .createTextOutput("Success")
  .setMimeType(ContentService.MimeType.JAVASCRIPT);  

  
  
}

Step 3: Change the url of the spread sheet. Make sure sheet is shared .[anyone with the link can view]

Step 4: Go to Publish -> Deploy as web app. A window pop up, here ->Who has access to the app: ->  Anyone,                   even Anonymous

            Publish/Update. Copy the published URL and store it.

 

2. Android Part

Step 1: Create new Android App from Android Studio

Step 2: Go to build.gradle[module: app] and add following dependencies.

note: If you are downloading the source code and modifying. Please make sure build tool version and compileSdk Version in build.gradle[module: dependancyapp] are compatible with your phone. If you are developing from the scratch then no issues, just dependency,

 

 compile 'com.google.zxing:core:3.3.0'
 compile 'com.journeyapps:zxing-android-embedded:3.4.0'

Step 3: Let’s add all layout files.

 

activity_main.xml  This adds a button to Scan

<?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: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="alabs.qsg.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="QR SCAN TO GSHEET"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/textView" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="SCAN"
        android:id="@+id/scan_btn"
        android:layout_below="@+id/textView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="80dp" />

</RelativeLayout>

Step 4: add the following code to MainActivity.java which scans and calls web service

package alabs.qsg;

import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Iterator;

import javax.net.ssl.HttpsURLConnection;

public class MainActivity extends AppCompatActivity {

    String scannedData;


    Button scanBtn;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       final Activity activity =this;
        scanBtn = (Button)findViewById(R.id.scan_btn);

        scanBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                IntentIntegrator integrator = new IntentIntegrator(activity);
                integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE_TYPES);
                integrator.setPrompt("Scan");
                integrator.setBeepEnabled(false);
                integrator.setCameraId(0);
                integrator.setBarcodeImageEnabled(false);
                integrator.initiateScan();
            }
        });


    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        IntentResult result = IntentIntegrator.parseActivityResult(requestCode,resultCode,data);
        if(result!=null) {
            scannedData = result.getContents();
            if (scannedData != null) {
                // Here we need to handle scanned data...
               new SendRequest().execute();


            }else {
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }



    public class SendRequest extends AsyncTask<String, Void, String> {


        protected void onPreExecute(){}

        protected String doInBackground(String... arg0) {

            try{

                //Enter script URL Here
                URL url = new URL("https://script.google.com/macros/s/AKfycbw1a4eDlOlGmWZ6Z0dw4NZ5WzcYlCLvGpoNcMCHz7GUWMajn9I/exec");

                JSONObject postDataParams = new JSONObject();

                //int i;
                //for(i=1;i<=70;i++)


                //    String usn = Integer.toString(i);

                //Passing scanned code as parameter

               postDataParams.put("sdata",scannedData);


                Log.e("params",postDataParams.toString());

                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(15000 /* milliseconds */);
                conn.setConnectTimeout(15000 /* milliseconds */);
                conn.setRequestMethod("GET");
                conn.setDoInput(true);
                conn.setDoOutput(true);

                OutputStream os = conn.getOutputStream();
                BufferedWriter writer = new BufferedWriter(
                        new OutputStreamWriter(os, "UTF-8"));
                writer.write(getPostDataString(postDataParams));

                writer.flush();
                writer.close();
                os.close();

                int responseCode=conn.getResponseCode();

                if (responseCode == HttpsURLConnection.HTTP_OK) {

                    BufferedReader in=new BufferedReader(new InputStreamReader(conn.getInputStream()));
                    StringBuffer sb = new StringBuffer("");
                    String line="";

                    while((line = in.readLine()) != null) {

                        sb.append(line);
                        break;
                    }

                    in.close();
                    return sb.toString();

                }
                else {
                    return new String("false : "+responseCode);
                }
            }
            catch(Exception e){
                return new String("Exception: " + e.getMessage());
            }
        }

        @Override
        protected void onPostExecute(String result) {
            Toast.makeText(getApplicationContext(), result,
                    Toast.LENGTH_LONG).show();

        }
    }

    public String getPostDataString(JSONObject params) throws Exception {

        StringBuilder result = new StringBuilder();
        boolean first = true;

        Iterator<String> itr = params.keys();

        while(itr.hasNext()){

            String key= itr.next();
            Object value = params.get(key);

            if (first)
                first = false;
            else
                result.append("&");

            result.append(URLEncoder.encode(key, "UTF-8"));
            result.append("=");
            result.append(URLEncoder.encode(value.toString(), "UTF-8"));

        }
        return result.toString();
    }
}









 

Step 5: Add web App URL from script and pass the parameter as defined in script in above MainActivity.java

 protected String doInBackground(String... arg0) {

            try{

                //Enter script URL Here
                URL url = new URL("Your Script web app URL");

                JSONObject postDataParams = new JSONObject();

                //Passing scanned code as parameter

               postDataParams.put("sdata",scannedData);

----------------------------
-----------------------------
----------------------------

 

 

Step 6: Add Internet Permission in manifest file

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

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
    <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>
    </application>

</manifest>

 Download Source Code