Saturday, July 31, 2010

Live Camera Preview on Android

Android SDK provides a full control on Android devices' hardware, so that you can use any component of your device in your applications. Thanks to this feature, you can use your device's camera to obtain live camera preview in your application. So that, you can build your own camera application with additional features.

Basically in a camera application, you need a camera surface and a button to take photos. First we start with getting required permission for Camera component. Also put a control into the activity tag to keep screen in landscape mode.


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

 <activity .......
    android:screenOrientation="landscape" ...... >


Then we create a simple layout includes a SurfaceView and a Button.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="horizontal"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">

 <SurfaceView
  android:id="@+id/preview"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:layout_weight="1">
 </SurfaceView>

 <Button
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:id="@+id/buttonTakePhoto"
  android:text="Click"
  android:gravity="center">
 </Button>

</LinearLayout>

Now we are ready to build our application to put the camera preview into our SurfaceView and to set the button's behavior for taking photos. Our activity must implement the SurfaceHolder.Callback interface in order to provide a camera preview.


 // Let's name our Activity as CamDroid.
public class CamDroid extends Activity implements SurfaceHolder.Callback

Then we create our Camera, Surface and Button fields which will be initialized when our activity is started.


    private Camera mCamera;
    private Button takePictureButton;
    private SurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder;

After this fields we need to declare which actions will be performed when user takes a photo.


    Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] data, Camera c) {
         
         FileOutputStream outStream = null;
          try {
          
          // Directory and name of the photo. We put system time
          // as a postfix, so all photos will have a unique file name.
          outStream = new FileOutputStream("/sdcard/CamDroid_" +
              System.currentTimeMillis()+".jpg");
          outStream.write(data);
          outStream.close();
          Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
         } catch (FileNotFoundException e) {
          e.printStackTrace();
         } catch (IOException e) {
          e.printStackTrace();
         } finally {
        }

            Log.e(TAG, "PICTURE CALLBACK: data.length = " + data.length);
            mCamera.startPreview();
        }
    };

Now we can implement the onCreate method of the Activity to initialize our surface and Button.


    public void onCreate(Bundle icicle)
    {
        super.onCreate(icicle);

        // We don't need a title for our camera window.
        // It makes our view smaller.
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        Log.e(TAG, "onCreate");
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        // In my case, name of the layout file is camdroid.xml
        setContentView(R.layout.camdroid);

        // Initialize the surface
        mSurfaceView = (SurfaceView)findViewById(R.id.preview);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        
        // Initialize the Button
        takePictureButton = (Button)findViewById(R.id.buttonTakePhoto);
        
        // Set the button's behavior
        takePictureButton.setOnClickListener(new OnClickListener() {
         public void onClick(View v) {
          mCamera.takePicture(null, null, mPictureCallback);
         }
        });
    }

Then we must provide some methods for our surface to create first preview, change preview, and stop preview.


    // Create camera preview.
    public void surfaceCreated(SurfaceHolder holder)
    {
        Log.e(TAG, "surfaceCreated");
        mCamera = Camera.open();
        //mCamera.startPreview();
    }

    // Change preview's properties (i.e. size or format).
    public void surfaceChanged(SurfaceHolder holder,
          int format, int w, int h)
    {
        Log.e(TAG, "surfaceChanged");

        // XXX stopPreview() will crash if preview is not running
        if (mPreviewRunning) {
            mCamera.stopPreview();
        }

        Camera.Parameters p = mCamera.getParameters();
        p.setPreviewSize(w, h);
        mCamera.setParameters(p);
        try {
         mCamera.setPreviewDisplay(holder);
        } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }
        mCamera.startPreview();
        mPreviewRunning = true;
    }

    // Stop the preview.
    public void surfaceDestroyed(SurfaceHolder holder)
    {
        Log.e(TAG, "surfaceDestroyed");
        mCamera.stopPreview();
        mPreviewRunning = false;
        mCamera.release();
    }

Now we have a basic camera application which has a camera preview and a button on screen. You can start taking photos with your applications by pressing the button on the screen. Or you can add this method to use your device's built-in "OK" Button (Trackpad for HTC, OK Button for Samsungs etc.) for taking photos.


    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            return super.onKeyDown(keyCode, event);
        }
 
        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            mCamera.takePicture(null, null, mPictureCallback);
            return true;
        }

        return false;
    }

ScreenShot:

Enjoy your new camera applications and take good photos :)

Wednesday, July 28, 2010

Create your own Browser using WebView

Using a WebView activity, you can display webpages over the Internet or display webpages or any other content from your device's drive. You might use this webview as a Webkit in your applications to display web contents, which can even have integrated Javascripts.


WebView activity will use the Internet, so you must add the Internet usage permission in your AndroidManifest.xml file.


 <uses-permission android:name = "android.permission.INTERNET"/>
In order to create a WebView, firstly you must create your layout including a WebView content. You can put a WebView into your layout xml file and in set its width and height as "fill_parent" to reach a fullscreen view.


Then in your main Activity, define a WebView and associate it with your layout.

 mWebView = (WebView) findViewById(R.id.web_view);
For a WebView you have a few choices about displaying contents. You can open a URL, you can create your HTML code inside your Activity and display it, you can open HTML files from your device's drive and also you can display other contents from your device's drive.


 // Loading a URL
 mWebView.loadUrl("http://www.androtips.com");

 // Loading HTML code created in the Activity
 String data = "<html><body><h2>Hello WebView</h2></body></html>";
 String mimeType = "text/html";
 String encoding = "utf-8";
 mWebView.loadData(data , mimeType , encoding);
 // Loading an HTML file or any content from sd card
 String filePath = "file:///data/data/com.webkitdemo/test.html";
 mWebView.loadUrl(filePath);

Now you have a basic WebView to display your contents. The problem with this default WebView is, when you click to a link in the webpage, Android will attempt to open its default Browser. Of course we want to open any links from our WebView open in our own WebView. To do this, we must add this small inner-class to our Activity.

 private class mWebViewClient extends WebViewClient {
    
     /** Opens new links in the same WebView instead of opening it in Browser Application.
* 
      */
     @Override
        public boolean shouldOverrideUrlLoading(WebView view , String url) {
view.loadUrl(url);
            return true;
        }
    }

Another good feature to add to our activity is setting the behavior of the Back button of device. So that we can go back from a link we went from our WebView.

 @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
            mWebView.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

Because we have small display sizes on mobile devices, we might need to add zoom controls to our WebView to enhance readability. In order to add zoom controls, you must add this controls into your onCreate method.

 @Override
    public void onCreate(Bundle savedInstanceState) {
        ...
        ...
// Zoom controls
        FrameLayout mContentView = (FrameLayout) getWindow().getDecorView().findViewById(android.R.id.content);
        final View zoom = this.mWebView.getZoomControls();
        mContentView.addView(zoom, ZOOM_PARAMS);
        zoom.setVisibility(View.GONE);
...
...
}

Your WebView is ready to use now. You can display any content in this WebView and integrate it into your Applications.


Enjoy!

Monday, July 26, 2010

Development Using Eclipse IDE



In this first blog post about Android Development, I would like to explain how to start development using Eclipse IDE and Android SDK (On MS Windows).


  1. Firstly you must download and install Java SE Development Kit (JDK) in order to use Eclipse IDE.
  2. Then download the Android SDK.
  3. After downloading, create a directory named android, on your local disk C. (C:\android)
  4. Extract the android_sdk zip file into the C:\android directory.
  5. Now you need an easy setting in order to use Android SDK on Windows. Right-click to Computer, then click Properties. In the Properties window, open Advanced tab. Click the Environment Variables button at bottom-right side.,
  6. In the User Variables view, double-click the Path to change this variable. As Variable Value, write C:\Program Files\Java\jre6bin then click OK.
  7. In the System Variables view, double-click the Path to change this variable. Add the android tools directory to the end of the current value in Variable Value as C:\android\tools then click OK.
  8. Now you are ready to use Eclipse IDE. You can download the latest version of Eclipse from the official download page. You can choose the type of your operating system from the list and start download.
  9. Create a directory named eclipse, in your local disk C.(C:\eclipse)
  10. Extract the eclipse zip file into the C:\eclipse directory.
  11. Double-click eclipse.exe to open Eclipse IDE and specify your workplace directory as you wish.
  12. In the Eclipse main window, click Help > Software Updates. Then click on Available Software tab and click on Add Site button.
  13. In the Add Site window, write https://dl-ssl.google.com/android/eclipse as Location value.
  14. Then click the checkbox of the site you added and click Install Software button.
  15. After installing, Eclipse will restart itself.
  16. Now click Window > Preferences on Eclipse menu. Choose Android from left frame and write C:\android to the SDK Location box.

Saturday, July 24, 2010

Hello Android

I know that there are lots of Android Development Blogs over the Internet, but i just would like to open my own blog to share my experiences on Android Development. In this blog, you will find useful tips and Android programming examples, which I tried and used for my projects.








I hope you will find this blog useful, and please leave comments if you have advices for me.

Hello again and enjoy!