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)
[maxbutton id=”1″ url=”https://github.com/androidLabsCode/QrCodeToGsheet” ]
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>
[maxbutton id=”1″ url=”https://github.com/androidLabsCode/QrCodeToGsheet” ]
I couldn’t deploy the web app like you said in the video. It is saying App is not verified
Just go ahead, proceed with unsecured way, since you are the application owner , no issue with the security, Just observe the video carefully, or you can refer my other video for proceeding with security issue
package com.example.sudeep.qrscanner;
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 ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Activity activity =this;
scanBtn = (Button)findViewById(R.id.scan_bt);
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 {
protected void onPreExecute(){}
protected String doInBackground(String… arg0) {
try{
//Enter script URL Here
URL url = new URL(“https://script.google.com/macros/s/AKfycby1Agw8Yh43ydEKELId-UP2_PGjBMgqIL5U3LXxbBfy-4EIR_g/exec”);
JSONObject postDataParams = new JSONObject();
//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 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();
}
}
this is my code .
it is throwing exception of result string on postexecute method
this one:
@Override
protected void onPostExecute(String result) {
Toast.makeText(getApplicationContext(), result,
Toast.LENGTH_LONG).show();
only showing toast not updating spreadsheet..
https://uploads.disquscdn.com/images/2a001113aacb7d6730e7dd0c4040bb04a6679aaa8579a3ff5f0b92240bd36a1d.png
Thank You for sharing your Android Tutorials. Can you show a tutorial were we can get the current location of the user and save his/her location co-ordinates through Android Phone into the Spreadsheet with the name, current time and date.
Sorry as of now I can’t make but, I can guide u for that,
1st search for tutorial on saving current location
2nd merge my tutorial to store location details in sheet,
please i want to refrence other variables on the sheet like name, surname etc just by the user inputing his id in android app please ur reply is fully appreciated. neeb teying to get it done but no progress so far…
Hi,
I followed your Tuto from your YouTube channel and it works great, thanks a lot !!
Is it possible to guide us in adding a textbox or ListPicker so the data input or selected is sent along with the QR code scanned?
Would appreciate a basic tutorial on how to achieve that if you can. It will help us to be more creative in using this tool.
Once again, thanks a lot
Nice Script
How to Scan Continues?
Sorry for late reply, you need to wait untill you get response from server, so you can scan for every 3 to 5 seconds… Or else you can store in local device and later you can send it to server that is sheet… You can use text watcher to send text of fixed size automatically,
Hi Admin,
I’m getting the toast message as ” false:404″ after scanning the QR code.
Please help.
Thanks,in advance.
Hi PIYUSH MANGTANI , please check spelling of parameters you are passing , if you face issues further please send script to help@crazycodersclub.com
Hello sir it’s the same problem for me when i send date to google sheet then it’s says false: 404 error. How to can i fix it???
Hi … problem is fales:401 … what solution ??
Hi crazyCoders can u please provide similar app on Phonegap platform please i am doing same college project on phonegap??
tengo un problema cuando copio el codigo 1 en el script dice Falta “;” delante del enunciado. (línea 5, archivo “Código”) y no me deja publicar. que falta?
hi thank you very much for this video…..it worked perfectly for me!!!
but I have a question…..If I wanted the app to scan barcode instead how would I go about doing that?……is there any way I could tweak the code so that it could do that or would I need to rewrite the whole code??
Please you can email me a response here mduru@upei.ca or just reply the comment!!