Wednesday 2 October 2013

Barcode scanning on android

Implement Barcode scanning on android in only 12 steps.
1.   Creating new project
File -> New -> Android project -> Then Press finish button



2.   it will create  project hierarchy given below




3.  Create Layout File




  • activity_main.xml layout file name


<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=".MainActivity" >
    <Button
        android:id="@+id/startScanning"
        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:minHeight="70dp"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true"        android:onClick="onStartBrScan"        android:layout_marginTop="60dp"        android:text="Start Barcode Scan" />
    <TextView
        android:id="@+id/scannedbr"
        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerHorizontal="true"        android:layout_centerVertical="true"        android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>

4.   Implement call back methods and add  REQUEST_CODE_BARCODE = 3000.
package com.example.barcodescanner;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;

public class MainActivity extends Activity {
/*
     * Add this line in the activity which will initiate barcode to scanner
       */
private final int REQUEST_CODE_BARCODE = 3000;
private TextView mBCScanTxt;

  @Override
        protected void onCreate(Bundle savedInstanceState) {
               super.onCreate(savedInstanceState);
               setContentView(R.layout.activity_main);
               mBCScanTxt = (TextView)findViewById(R.id.scannedbr);
        }
public void onStartBrScan(View view){
}

}


5.  Download this project and add it as a library project. Right click on project select properties-> android-> scroll down -> press add button -> select "com.jwetherell.quick_response_code.CaptureActivity".





6.  Library will be added to your project now as below.





 7.   Come back to your project,and modify onStartScan callback method as below.

public void onStartBrScan(View view){
startActivityForResult(new Intent(MainActivity.this,
DecoderActivity.class), REQUEST_CODE_BARCODE);
}


8.    Add onactivityresult method.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (data != null) {
switch (requestCode) {
case REQUEST_CODE_BARCODE:
mBCScanTxt.setText(data.getExtras().getString("ISBN"));
break;

default:
break;
}

}

}



9.    Add camera permission  to the AndroidManifest.xml


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

10.    Add the below activity in the AndroidManifest.xml file under the application tag.Modified AndroidManifest.xml is given below.

       <activity
            android:name="com.jwetherell.quick_response_code.CaptureActivity"
            android:clearTaskOnLaunch="true"            android:configChanges="orientation|keyboardHidden"
            android:icon="@drawable/icon"
            android:label="@string/capture_name"
            android:screenOrientation="landscape"            android:stateNotNeeded="true"            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:windowSoftInputMode="stateAlwaysHidden" >        </activity>        <activity            android:name="com.jwetherell.quick_response_code.DecoderActivity"
            android:clearTaskOnLaunch="true"            android:configChanges="orientation|keyboardHidden"
            android:icon="@drawable/icon"
            android:label="@string/decoder_name"
            android:screenOrientation="landscape"            android:stateNotNeeded="true"            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:windowSoftInputMode="stateAlwaysHidden" >        </activity>        <activity            android:name="com.jwetherell.quick_response_code..EncoderActivity"
            android:clearTaskOnLaunch="true"            android:configChanges="orientation|keyboardHidden"
            android:icon="@drawable/icon"
            android:label="@string/encoder_name"
            android:screenOrientation="landscape"            android:stateNotNeeded="true"            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:windowSoftInputMode="stateAlwaysHidden" >        </activity>


11.    Modified AndroidManifest.xml is given below.
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.barcodescanner"
    android:versionCode="1"    android:versionName="1.0" >  
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="17" />
    <application
        android:allowBackup="true"        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >      
        <activity            android:name="com.example.barcodescanner.MainActivity"
            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>         <activity            android:name="com.jwetherell.quick_response_code.CaptureActivity"
            android:clearTaskOnLaunch="true"            android:configChanges="orientation|keyboardHidden"
            android:icon="@drawable/icon"
            android:label="@string/capture_name"
            android:screenOrientation="landscape"            android:stateNotNeeded="true"            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:windowSoftInputMode="stateAlwaysHidden" >        </activity>        <activity            android:name="com.jwetherell.quick_response_code.DecoderActivity"
            android:clearTaskOnLaunch="true"            android:configChanges="orientation|keyboardHidden"
            android:icon="@drawable/icon"
            android:label="@string/decoder_name"
            android:screenOrientation="landscape"            android:stateNotNeeded="true"            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:windowSoftInputMode="stateAlwaysHidden" >        </activity>        <activity            android:name="com.jwetherell.quick_response_code..EncoderActivity"
            android:clearTaskOnLaunch="true"            android:configChanges="orientation|keyboardHidden"
            android:icon="@drawable/icon"
            android:label="@string/encoder_name"
            android:screenOrientation="landscape"            android:stateNotNeeded="true"            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:windowSoftInputMode="stateAlwaysHidden" >        </activity>    </application>
</manifest>

12.   Congrates :) You are done now .


                SourceCode




















Saturday 28 September 2013

Android WebView with https loadUrl shows blank/empty page

I recently encountered this problem while trying to develop a WebView that is supported on Doughnut (1.6) and above. When presented with a https url the WebView just renders a blank page.
It seems that until Froyo, Android didn’t provide a public API to let you manually decide if you wanted to proceed to an untrusted web site via a WebView.
Note that in this case it is not even that the web site was untrusted (in the conventional sense) – it is because Thawte is not in the default list of trusted certificate authorities on Android. If you use the standard web browser on Android, the browser presents a typical warning dialog (as presented below) that enables you to accept the certificate and carry on.

If you are using Froyo as the target SDK then you can use:
mWebView = (WebView) findViewById(R.id.my_webview);
mWebView.setWebViewClient(new WebViewClient() {
 public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) {
 handler.proceed() ;
 }
}
However, if you are not using Froyo then it seems you are out of luck. After some research, I concluded that I had the following options:

a) intercept all page requests and forward to external web browser if url begins with https (not a clean or nice user experience and totally unnecessary for Froyo and above)

b) add certificate of website to local keystore (in this case I am serving multiple web pages and the origin of many of these is not known until runtime)

c) make Froyo the minSDK and discard previous versions of Android (not a suitable option)

d) hack and use some private apis (the option described below)

To solve this problem we have to use a private interface (not published on SDK but present in real SDK runtime). As you can see in the Android src tree, the onReceivedSslError is indeed present (and used – it simply cancels the request) in Doughnut. However, this method is not presented to us in the SDK  - it is hidden because it contains a parameter type SslError which is located in a hidden package.  Therefore, we need to copy these src files into our project so that we can access them:

1) Copy WebViewClient.java into the package “android.webkit” within your src folder.

2) Copy SslError.java into the package “android.net.http” within your src folder.



3) Since we replicated the paths to the src files in the SDK, our code to override onSslError above now works on Android 1.6.



Caution: bear in mind that we are using a private API and Google reserve the right to change private APIs at any time – though in this case it is unlikely since they’ve now made this available in Froyo.