Tuesday, November 20, 2012

Java Calculator

Hi all!
         This is my first time posting to the REGNARTS blog.
So, this post as is rightfully titled, explains java applet through a simple calculator program which takes in 2 numbers, adds, subtracts, multiplies and divides them. Also it checks for possible errors in the input of the 2 numbers and displays the error if any.

PRE-REQUISITES: A little java education along with the concept of classes and a little experience with the eclipse java ide. For those who want to download the eclipse ide, the link's here.

Now lets look at the program,


If you see the first few lines before the commented boundary in green, they are called packages. Packages are collections of  related classes and interfaces(You'll learn about interfaces in an another post maybe. :P ) eg) to develop windows programs, applets, networking etc. The Java API consists of many such packages. Here "awt" means Abstract Window Tools, "applet" includes all those methods (btw functions in java are called methods) which are required to run this Applet, and "awt.event" controls any action performed within the applet window.

Now after the green commented boundary you'll see a line "public class AplNum extends Applet implements ActionListener". Here public class means objects of this class can be created in different files that are in the same folder as this file. If you are using some other editor then its important to name the file same as the name of the public class in the file in the file. Same reason you can have only one public class in one java file. Now the name of a class has to start with a capital letter as per proper java standards. It extends Applet implies it inherits properties and elements from the class Applet. The term applet is used for small java apps that are usually used for web designing. And finally it implements ActionListener implies the Applet runs the methods in ActionListener interface, that is used to detect any action happening inside the applet window. It contains one method which we are supposed to redefine in our code called as the "actionPerformed". Again first letter of any method is small case as per java standards!

Now inside the class we declare the members of the class, that is labels, buttons and textfields. Where label is used to display a msg, button used to click on something, and textfield is used to input and output data. Notice that all label elements have their names prefixed with 'l', buttons with 'b' and textfields with 't'. That is good program organisation for you!
now we discuss the init() function which is used to create the Applet. In this function you initialise the various members you have already created. first you use GridLayout to brand a layout to the applet. GridLayout gives a table like layout. Here it gives 8 row, 2 column table, with 15 pixel horizontal spacing and 10 pixel vertical spacing between the members. setSize is used to set the size of the applet window. The members are then added in order to the table. For a label, we initialise it to a default text supplied in "" inside the brackets. Textfields are initialised to size of text allowed in the textfield. And if that textfield is not used for inputting then we need to disallow editing using setEditable(false). And buttons are initialised to default display text. addActionListener(this) implies action performed on those members are detected by the actionListener interface. Finally add() is used to add the member to the respective record in the layout. Like this all members of the class are intitialised.

Now lets check the next function used to input numbers and check for errors!
Try catching is an error handling mechanism in java. Here if any error occurs in java, that catch statement is executed that has the erroneous object as its parameter. getNos() function returns true if the inputs are correct and returns false if inputs are wrong. Here flag is set to false meaning default assumption is that the input is erroneous. Then inside try{} we use getText() of textfield to get any string entered in that textfield. Then we use Integer.parseInt() to convert the string into number. If the string doesnt just contain numbers then it throws an error. All errors belong to the Exception class. This error is caught and respective steps are taken to handle it. In this case, we set the format using different functions and display the error msg in tmsg and clear up the tnum1 and tnum2 for further input.If all the numbers are entered correctly then tmsg is cleared.

Now that we have safely input the numbers, lets look at the actionPerformed function that I previously said we need to redefine to suit our code.
First it checks for the integrity of the input numbers given. Then it displays the respective results. If you click the add button, the actionListener gets activated and it raises the actionPerformed function and if the source of the action is the add Button, the sum will be displayed and an "Addition successfull" msg is shown. Same thing goes for subtract, multiply and divide with respective solutions and msges. But for division it also checks for divide by zero error!

Now that you've written the project, compile and run it in eclipse and you will get the following applet window:
I've already performed the operations so you'll see all the textfields are full!
Now for those who want to run the applet though command prompt and you already have jdk installed in your system and your classpaths set up you can first create the following html file named AplNum.html:
then run the command: javac AplNum.java to compile the file and give the class file. then run the command: AppletViewer AplNum.html in your command window and poof! you'll get the same applet window!
I seriously hope you people try it out, and please comment you're reviews about the post and the program!
Also, I have a question for you, Which editor have I used to code the above program? Answer to win a chance to acquire some guaranteed goodies! :)
I thank Regnarts for allowing me to post on his blog.
Dude, you are not always awesome but then that's the beauty of it! ;)
Yours,
anty_kryst
Follow me at twitter "@anty_kryst" or on facebook "antykrissh".
Bye!

Friday, October 19, 2012

Audio Amplifier | LM386

I managed to create a basic audio amplifier using the IC LM386. This post is just a walk through to the creation. LM386 is a very good audio amp, but sometimes it tends to oscillate at low frequencies hence producing a lot of unwanted noise. The basic circuit is

Put this on a bread board. And connect a 3.5mm jack to the other end to input Vin. Use a coupling capacitor of possibly 10uF. The 10K Pot is to control the intensity. Use Vcc of around 9V. I've used a 8ohm speaker.



video


There is one more mode according to the datasheet. This is supposed to provide a gain of 200.



Sometimes when the gain is more the output is distorted. Be sure to keep that in mind. It is not that powerful. I've always had a hard time handling it, lot of distortions and noise. Check out other modes, experiment, enjoy.




video

Thursday, October 18, 2012

Android app building | Android Camera

There have been a lot of posts on this blog relating to android but none of them say anything about android application development. This is the first one to be talking about android application development. Yes that's right ".apk". Though its customary for you to build a "Hello, World!" program whenever you start to learn some new language, I took a small detour to teach you guys how easy it will be to utilize real hardware on your phone. This post will outline an app to take pictures from your phone camera("Yes!, it does the same work as your default camera app").

If you don't have Android SDK downloaded and installed along with Eclipse. And ADT plugin configured with it. Do it fast.

Now fire up your IDE and create a new project with appropriate name. Now that we want to create a camera app, let's see what google has to offer. Android has a page to describe building a camera app, nice!!.

The first snippet it gives is to detect the camera availability. It runs like this.


/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
        // this device has a camera
        return true;
    } else {
        // no camera on this device
        return false;
    }
}

This is a really useful piece of code I decided to put out of my program, becoz I know my phone has a camera(lol). Anyways if you want to check out run it in your program. The next code is to get an instance of the camera. You'll obviously need it in your program.


/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
    }
    catch (Exception e){
        // Camera is not available (in use or does not exist)
    }
    return c; // returns null if camera is unavailable
}

Now here is something that you must know. Android handles camera as an OBJECT. So this code creates a camera object and calls the associated function camera.open(). This creates an exception if the camera doesn't exist or the resource isn't available (Some other program utilizing it). Now your layout will typically look like this over eclipse


We need to change this (obviously!!) to display our camera. We'll add a frame to the display to make a viewfinder out of it.


<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" >
    
     <FrameLayout
         android:id="@+id/camera_preview"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         android:layout_alignParentLeft="true"
         android:layout_alignParentTop="true"
         />
     
      <Button
             android:id="@+id/button_capture"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:gravity="center|left"
             android:text="capture" />

   
</RelativeLayout>

Now that you have a button that says capture and a frame to display the camera view. It must pretty much look like this.

We'll come back to refining this later. Now let us add the code to the main program. Eclipse has created initial code for me, that runs like this

package com.regnartstranger.cam;

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

public class Cam extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cam);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_cam, menu);
        return true;
    }
}


Adding up our program to get the camera resource. Now the file is


Observe that we haven't declared the variable camera that is giving us an error. So create an object to hold our camera. We'll call it camera itself(yes, because we have already started using the name).


package com.regnartstranger.cam;

import android.hardware.Camera;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;

public class Cam extends Activity {

private String TAG = "Cam";
private Camera camera;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cam);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_cam, menu);
        return true;
    }
    
    public void getCameraResource(){
    try{
        camera = Camera.open();
        }catch(Exception ioe)
        {
        Log.d(TAG,ioe.getMessage());
        }
    }
}



Notice that I've also used a TAG and updated the log on error(Like a good programmer should). Also note the extra importing of the android.hardware.camera that the eclipse has done for me(Thank you!). Now to create a preview, the developer website list's it to be a class called preview class


/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null){
          // preview surface does not exist
          return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
          // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }
}


To display the picture on the screen we use SurfaceView. SurfaceView is a class in android that can be used to paint a canvas to the screen. To use it we create a new class that inherits SurfaceView and implements its call back. So the functions surfacecreated, surfacedestoryed, surfacechanged implement these call backs. We initialize the class by creating a camera object, a holder for the Surface and adding callback to that holder.
Now using the same code into our app. We get


package com.regnartstranger.cam;

import java.io.IOException;

import android.hardware.Camera;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class Cam extends Activity {

private String TAG = "Cam";
private Camera camera;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cam);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_cam, menu);
        return true;
    }
    /** A basic Camera preview class */
    public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
        private SurfaceHolder mHolder;
        private Camera mCamera;

        public CameraPreview(Context context, Camera camera) {
            super(context);
            mCamera = camera;
            mHolder = getHolder();
            mHolder.addCallback(this);
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        public void surfaceCreated(SurfaceHolder holder) {
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
                Log.d(TAG, "Error setting camera preview: " + e.getMessage());
            }
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
        }

        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

            if (mHolder.getSurface() == null){
              return;
            }

            try {
                mCamera.stopPreview();
            } catch (Exception e){
            }


            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();

            } catch (Exception e){
                Log.d(TAG, "Error starting camera preview: " + e.getMessage());
            }
        }
    }
    
    public void getCameraResource(){
    try{
        camera = Camera.open();
        }catch(Exception ioe)
        {
        Log.d(TAG,ioe.getMessage());
        }
   
    }
}



Now to create a preview in the screen, we need to create an object that handles it. It is called camerapreview. So adding these three lines of code sets up the camera view activity.


 mPreview = new CameraPreview(this, camera);
 FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
 preview.addView(mPreview);

The whole code looks like this now


package com.regnartstranger.cam;

import java.io.IOException;
import android.hardware.Camera;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.FrameLayout;

public class Cam extends Activity {

private String TAG = "Cam";
private Camera camera;
public CameraPreview mPreview;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cam);
        getCameraResource();
        mPreview = new CameraPreview(this, camera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.addView(mPreview);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_cam, menu);
        return true;
    }
    /** A basic Camera preview class */
    public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
        private SurfaceHolder mHolder;
        private Camera mCamera;

        public CameraPreview(Context context, Camera camera) {
            super(context);
            mCamera = camera;
            mHolder = getHolder();
            mHolder.addCallback(this);
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        public void surfaceCreated(SurfaceHolder holder) {
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
                Log.d(TAG, "Error setting camera preview: " + e.getMessage());
            }
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
        }

        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

            if (mHolder.getSurface() == null){
              return;
            }

            try {
                mCamera.stopPreview();
            } catch (Exception e){
            }


            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();

            } catch (Exception e){
                Log.d(TAG, "Error starting camera preview: " + e.getMessage());
            }
        }
    }
    
    public void getCameraResource(){
    try{
        camera = Camera.open();
        }catch(Exception ioe)
        {
        Log.d(TAG,ioe.getMessage());
        }
   
    }
}

At this point if you just add android.permission.CAMERA to the manifest file you'll be able to run the program.


The camera now looks like this. If you want to capture a photograph all you need to do is to implement a callback method to save the photograph to a file in memory. The callback is described in the developer website as

private PictureCallback mPicture = new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {

        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
        if (pictureFile == null){
            Log.d(TAG, "Error creating media file, check storage permissions: " +
                e.getMessage());
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }
};

Add this to your code.It would finally look like this


package com.regnartstranger.cam;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;

public class Cam extends Activity {

private String TAG = "Cam";
private Camera camera;
public CameraPreview mPreview;
public Button captureButton;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cam);
        getCameraResource();
        captureButton = (Button) findViewById(R.id.button_capture);
        mPreview = new CameraPreview(this, camera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.addView(mPreview);
        captureButton.setOnClickListener(
           new View.OnClickListener() {
               public void onClick(View v) {
                   // get an image from the camera
                   camera.takePicture(null, null, mPicture);
               }
           }
        );
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_cam, menu);
        return true;
    }
    private PictureCallback mPicture = new PictureCallback() {

        public void onPictureTaken(byte[] data, Camera camera) {
        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyCameraApp");
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File mediaFile;
            mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg");

            if (mediaFile == null){
                Log.d(TAG, "Error creating media file, check storage permissions\n");
                return;
            }

            try {
                FileOutputStream fos = new FileOutputStream(mediaFile);
                fos.write(data);
                fos.close();
            } catch (FileNotFoundException e) {
                Log.d(TAG, "File not found: " + e.getMessage());
            } catch (IOException e) {
                Log.d(TAG, "Error accessing file: " + e.getMessage());
            }
        }
    };
    /** A basic Camera preview class */
    public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
        private SurfaceHolder mHolder;
        private Camera mCamera;

        public CameraPreview(Context context, Camera camera) {
            super(context);
            mCamera = camera;
            mHolder = getHolder();
            mHolder.addCallback(this);
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        public void surfaceCreated(SurfaceHolder holder) {
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
                Log.d(TAG, "Error setting camera preview: " + e.getMessage());
            }
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
        }

        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

            if (mHolder.getSurface() == null){
              return;
            }

            try {
                mCamera.stopPreview();
            } catch (Exception e){
            }


            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();

            } catch (Exception e){
                Log.d(TAG, "Error starting camera preview: " + e.getMessage());
            }
        }
    }
    
    public void getCameraResource(){
    try{
        camera = Camera.open();
        }catch(Exception ioe)
        {
        Log.d(TAG,ioe.getMessage());
        }
   
    }
}


Add the permission to write to sdcard [android.permission.WRITE_EXTERNAL_STORAGE]. Now you are good to go. Run the app once, you must be able to click pictures.

To create a more formal looking app. Add android:theme="@android:style/Theme.NoTitleBar.Fullscreen" under application in the manifest file. And android:screenOrientation="landscape" under activity. It must finally look like this.


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.regnartstranger.cam"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.CAMERA"/>
    

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
        <activity
            android:name=".Cam"
            android:label="@string/title_activity_cam"
            android:screenOrientation="landscape" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


This gives it a decent camera look. Run the program to get your basic Camera App

Have a nice day!!