CS453 | mobile programming
  • outline
  • projects
  • syllabus
  • links

Android Application using Another Application

e.g. Using ZXING Android BarCode Scanner Application as an INTENT in YOUR own Android Application

  • Here is an example of using a different Android Application that your Application communicates to via an "INTENT".
  • PRO: You can use their code and don't have to rewrite.
  • CON: You will require this application to be installed on the device for this to work in your application. This is an important decision. Okay with Applications that are standard Android but, becareful ---like with this one where the app is not standard.

 

STEP 1: Download 3rd party application (i.e. barcode scanner) to your device (or machine you have emulator on)

  • The barcode application has a dependency on the ZXing application that is supposed to be installed on the client device; it is available as an .apk file.

Example

To download ZXing app:

https://market.android.com/details?id=com.google.zxing.client.android&feature=search_result#?t=W251bGwsMSwxLDEsImNvbS5nb29nbGUuenhpbmcuY2xpZW50LmFuZHJvaWQiXQ ..

 

 

STEP 2: Get or create code to "communicate" with the 3rd party Application

  • Your application must communicate with the 3rd party application that is now on your sytem (either the phone or machine with emulator).
  • Sometimes as is the case for ZXing, they have produced some code --typically an Intent based set of classes -- for you to "activate" their application and recieve results. As mentioned this will be done with an Android Intent they have created that you activate and in an asynchronous manner get the results

General Idea

  1. CREATE INTENT TO 3rd PARTY APP: Create Intent describing the 3rd party Application and any usage parameters and its location on the device/emulator
  2. CREATE ACTIVTY ASSOCIATED WITH INTENT Create an Activity based on Intent in #1 and MAKE SURE you create activity using startActivityForResult(Intent, int) so that you can get results back if you need it...mostly this will be the case but, you may want to lauch a 3rd party application that does not return results to your application
  3. RECIEVE RESULTS OF 3rd PARTY APP ACTIVITY Add code that implements onActivityResult(int, int, Intent) this is teh CALL back function that gets the returned results from the Activity in #2. Parse results as desired

Example 3rd Party App = ZXing Barcode Application

To download the ZXing library:

http://code.google.com/p/zxing/downloads/detail?name=ZXing-1.7.zip (local copy)

CONTENTS includes:

to use to make the ZXing app available via an intent:

\ZXing-1.7\zxing\android-integration\src\com\google\zxing\integration\android

  • IntentIntegrator  = class created by ZXing that you put INTO YOUR Application project code that will create an Android Intent to use their application --- You will use this class as follows in your code

    1. This class creates an Intent associated with the 3rd party ZXING Barcode App
    2. It then creates an Activity using this intent
      • You want to get a result back from this activity when it ends. For example,you want the ZXING Barcode App to take picture of a barcode and then return the barcode information/product information.
      • To do this, you call the startActivityForResult(Intent, int) version with a second integer parameter identifying the call.
      • The result will come back through your onActivityResult(int, int, Intent) method. The Intent contains the RETURNED DATA.
    3. Create some code in your application for onActivityResult(***)

    IntentResults  = class created by ZXing that you put INTO YOUR Application project code that will parse the results of running the ZXING barcode application triggered with IntentIntegrator class --- See below for highlights of code useage.

GET ENTIRE CODE FOR THIS APPLICATION (that uses the ZXING application) here

//SOME Class File That is part of YOUR APPLICATION

//partial code


//method to create Intent and Activity to use the 3rd party ZXING Barcode App

// here it is shown as being inside Event Handling code which is
// in response to a UI event-user hit button saying user wants to take a picture and 
// process the bar code (that is assumed to be in the field of view of the camera)
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId())
{
case R.id.screen1_btnStartScan: // to invoke a scan
IntentIntegrator integrator = new IntentIntegrator(Screen1.this);
integrator.initiateScan();
break; ......... } //method to recieve results of 3rd Party ZXING Barcode Application when it is finished public void onActivityResult(int requestCode, int resultCode, Intent intent) { //Uses Helper class IntentResult that parses the results for you
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
if (scanResult != null) {
// Retrieving the result of the scan

Bundle received_bundle = intent.getExtras(); //note that the format of the recieved data is something the 3rd party app // would need to document for you to use it and know these string names to get results
String type = received_bundle.getString("SCAN_RESULT_FORMAT");
barcode = received_bundle.getString("SCAN_RESULT");
tvBarCodeType.setText("Code Type: "+type);
tvBarCode.setText("Code: "+barcode);
hasBarCode = true;

}
else{
tvBarCodeType.setText("");
tvBarCode.setText("Sorry unable to scan");
}


} GET ENTIRE CODE FOR THIS APPLICATION (that uses the ZXING application) here


//IntentIntegrator class

//taken from ZXING and NOW part of YOUR APPLICATION
//  partial code... again go here for entire application code 
 public IntentIntegrator(Activity activity) {
this.activity = activity; //note it saves the Activity of THIS,YOUR application
title = DEFAULT_TITLE;
message = DEFAULT_MESSAGE;
buttonYes = DEFAULT_YES;
buttonNo = DEFAULT_NO;
targetApplications = TARGET_ALL_KNOWN;
}
 /**
   * Initiates a scan only for a certain set of barcode types, given as strings corresponding
   * to their names in ZXing's {@code BarcodeFormat} class like "UPC_A". You can supply constants
   * like {@link #PRODUCT_CODE_TYPES} for example.
    */
public AlertDialog initiateScan(Collection<String> desiredBarcodeFormats) {

      //Start to setup Intent for 3rd party ZXING Barcode App
      Intent intentScan = new Intent(BS_PACKAGE + ".SCAN");
      intentScan.addCategory(Intent.CATEGORY_DEFAULT);
      // check which types of codes to scan for
      if (desiredBarcodeFormats != null) {
           // set the desired barcode types
           StringBuilder joinedByComma = new StringBuilder();
           for (String format : desiredBarcodeFormats) {
                 if (joinedByComma.length() > 0) {
                    joinedByComma.append(',');
                     }
                 joinedByComma.append(format);
              }
           intentScan.putExtra("SCAN_FORMATS", joinedByComma.toString());
       }
      
       // Find 3rd party ZXING Barcode application ---if can't return Error message to user saying need it
       String targetAppPackage = findTargetAppPackage(intentScan);
       if (targetAppPackage == null) {
           return showDownloadDialog();
       }
 

       //Associate Intent with Package location on device/emulator of 3rd party ZXING Barcode app
       intentScan.setPackage(targetAppPackage);
       intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
       intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);

       //CREATE Activity based on Intent associated with 3rd party ZXING Barcode app and ask for results
       activity.startActivityForResult(intentScan, REQUEST_CODE);
       return null;
 }
   

//Method to find the 3rd party ZXING Barcode Application on the device/system
private String findTargetAppPackage(Intent intent) {
       PackageManager pm = activity.getPackageManager();
       List<ResolveInfo> availableApps = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
       if (availableApps != null) {
                 for (ResolveInfo availableApp : availableApps) {
                    String packageName = availableApp.activityInfo.packageName;
                    if (targetApplications.contains(packageName)) {
                        return packageName;  //found the application
                        }
                 }
        }
        return null; //couldn't find it
 }
     

//method to used to parse results from 3rd party ZXING Barcode App
/**
* <p>Call this from your {@link Activity}'s
* {@link Activity#onActivityResult(int, int, Intent)} method.</p>
*
* @return null if the event handled here was not related to this class, or
* else an {@link IntentResult} containing the result of the scan. If the user cancelled scanning,
* the fields will be null.
*/
public static IntentResult parseActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
String contents = intent.getStringExtra("SCAN_RESULT");
String formatName = intent.getStringExtra("SCAN_RESULT_FORMAT");
return new IntentResult(contents, formatName);
}
return new IntentResult(null, null);
}
return null;
}
 


//IntentIntegrator class

// go to code here to see this class which is provided by ZXING and now part of your,this application.

 

Explanation of the Application that uses the ZXING barcode app to do Search in Google and Amazon

(CLICK HERE FOR VIDEO DEMO)

(VIDEO DEMOING INTEGRATION OF ZXING)

(VIDEO DEMOING INSTALL OF AN APK ONTO A PHSICAL DEVICE)

main interface of app

  1. We invoke the scanning function by using any event as a trigger such as a click of the button on our application.
  2. We scan a barcode and retrieve the information that is decoded and delivered by the ZXing library. The working of the ZXing library is in the form of the following stages
  3. At the end of the page we show OUR application uses the bar code number to search for the product on the Internet..which search engine choose by user hitting one of the buttons above

How ZXING WORKS (basically) TO GET BAR CODE

Stage1: invoke the camera of the phone using an intent.

Stage 2: Convert the captured image into a bitmap.

Stage 3: Use Non-Determinism (of efficiently by using Hints) to determine the format of the barcode.

Stage 4: Use the pertinent barcode reader to decode the information encoded in the barcode by adhering to the protocol of the corresponding barcode.

Stage 5: deliver the encoded information, barcode format to the calling function.

Instantiate a reader

We first need to instantiate a reader to establish the type of code we intend our application to read and decode. For generic applications there is a comprehensive code decoder that we could instantiate and deploy.

Reader reader = new MultiFormatReader();

The variable reader is of type Reader that is a user defined type.

Or if we want our application to be more specific in purpose (i.e. if we develop an application to read only a certain type of barcode, we use the other readers provided in the library)

The other readers include

 QRCodeReader
 PDF417Reader
 Code39Reader
 CodaBarReader
 Code93Reader
 Code128Reader
 EAN8Reader
 EAN13Reader
 ITFReader
 OneDReader
 UPCAReader
 UPCEANReader
 UPCEReader
 DataMatrixReader
 AztecReader

ZXING captures image

app using ZXING app to capture image of barcode

capture an image by invoking an intent to the phone’s camera

To invoke the phone’s camera (upon an event like the click of a button) ...read ZXING code (go on web) for actual details

 i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); // creating  an intent 
 startActivityForResult(i,cameraData); // starting the intent 

ZXing must get Image for processing ...here I am showing it saved to local bmp file (here called data)

   super.onActivityResult(requestCode, resultCode, data); 
   if(resultCode == RESULT_OK) // if an image has been captured successfully 
  { 
    Bundle extras = data.getExtras(); // create and instantiate a Bundle 
   // retrieve the image and cast it into a Bitmap  
    bmp = (Bitmap) extras.get("data");     
  } 

ZXING must now perform Image Processing and Recognition to Detect the Barcode

(see ZXING code for actual implementation)

The bitmap of the image captured is provided as a parameter to the Reader (interface) that returns the decoded information from the bitmap.

In the Result class, the Barcode format is non deterministically obtained by testing out all the supported barcode formats. In other cases, the Result class also takes in “Hints” as parameters to efficiently cut down on the format determination time by passing in the format of the pertinent barcode.

Going ahead I am elaborating on the retrieval of the information of a EAN13 code. (The decoding of different types of barcodes needs to follow different protocols as indicated by the same)

For an EAN-13 barcode, the first digit is represented by the parities used to encode the next six digits, according to the table below. For example, if the barcode is 5 123456 789012 then the value of the first digit is signified by using odd for '1', even for '2', even for '3', odd for '4', odd for '5', and even for '6'. // Parity of next 6 digits

  Digit   0     1     2     3     4     5 
 0    Odd   Odd   Odd   Odd   Odd   Odd 
  1    Odd   Odd   Even  Odd   Even  Even 
 2    Odd   Odd   Even  Even  Odd   Even 
 3    Odd   Odd   Even  Even  Even  Odd 
  4    Odd   Even  Odd   Odd   Even  Even 
 5    Odd   Even  Even  Odd   Odd   Even 
  6    Odd   Even  Even  Even  Odd   Odd 
  7    Odd   Even  Odd   Even  Odd   Even 
 8    Odd   Even  Odd   Even  Even  Odd 
 9    Odd   Even  Even  Odd   Even  Odd 

The encoding is represented by the following array, which is a bit pattern using Odd = 0 and Even = 1. For example, 5 is represented by:

Odd Even Even Odd Odd Even

in binary:

0 1 1 0 0 1 == 0x19

Based on pattern of odd-even ('L' and 'G') patterns used to encode the explicitly-encoded digits in a barcode, determines the implicitly encoded first digit and adds it to the result string.

If a string is successfully decoded, it is sent returned to the calling function.

The Intent Integrator class that is available as a part of the client project.

1. Searches for the ZXing barcode scanner app and prompts the user to install the same from android market.
2. Upon a successful validation of the app’s presence it invokes a scan with all the supported barcode types.
3. The result is encapsulated by the IntentResult class that delivers the barcode format and barcode as
a. SCAN_RESULT_FORMAT
b. SCAN_RESULT


Now do a search using Google or Amazon or Yahoo! that accept barcode=**** in the URL

We could then proceed to embed/utilize the barcode information as conceived by the application that we create.

application barcode search results

 

cs453:mobile programming

  • home
  • outline
  • projects
  • syllabus
  • links