I am going to demonstrate developing a simple android application. This application is about turning on and off device flashlight / torchlight with simple touch. To enshure yourself that the app would work please don't change anything frome above.
1. Create a new project in Eclipse IDE by going to File ⇒ New ⇒ Android Application Project . I named my package as app.technozed.s
impleflashlight and main activity as MainActivity
impleflashlight and main activity as MainActivity
2. Open your AndroidManifest.xml file and add required permissions.
android.permission.CAMERA – required to access the camera device
android.permission.FLASHLIGHT – required to access the FLASHLIGHT device
android.hardware.camera - required to acces camera hardware featuresandroid.hardware.camera.flash - required to acces camera flash hardware features
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="app.technozed.simpleflashlight"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" /><uses-permission android:name="android.permission.FLASHLIGHT" /><uses-permission android:name="android.permission.CAMERA" /><uses-feature android:name="android.hardware.camera" /><uses-feature android:name="android.hardware.camera.flash" /><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name="app.technozed.simpleflashlight.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></application></manifest>
(click on image names to open them in a new page)
Also we will need a xml file for switching images when will click on them (on/off button)
In Eclipse right click on drawable-nodpi folder New -> Android XML File name it onoffbutton choose Root element: selector and click Finish. Open it, and in the <selector> tag add this:
4. Now open activity_main.xml file located under res ⇒ layout folder, in Graphical mode in the middle add a SurfaceView with the id: preview_view and a ToggleButton with the id: tog1 and in XML mode to you ToggleButton change the background="@drawable/onoffbutton" This layout file acts as main screen of the application.
Now save all and Run it.
It should work.
Thank you.
Take a look at my app on play.store -> Max-Power Flashlight Vintage
Also we will need a xml file for switching images when will click on them (on/off button)
In Eclipse right click on drawable-nodpi folder New -> Android XML File name it onoffbutton choose Root element: selector and click Finish. Open it, and in the <selector> tag add this:
<item android:state_checked="true"
android:drawable="@drawable/db" />
<item android:state_checked="false"
android:drawable="@drawable/dbc" />
4. Now open activity_main.xml file located under res ⇒ layout folder, in Graphical mode in the middle add a SurfaceView with the id: preview_view and a ToggleButton with the id: tog1 and in XML mode to you ToggleButton change the background="@drawable/onoffbutton" This layout file acts as main screen of the application.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"5. Open your MainActivity.java file and add the following code:
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<SurfaceView
android:id="@+id/preview_view"
android:layout_width="1dip"
android:layout_height="1dip" />
<ToggleButton
android:id="@+id/tog1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="@drawable/onoffbutton"
android:textOff=""
android:textOn="" />
</RelativeLayout>
package app.technozed.simpleflashlight;The App detects if the phone has or not Flashlight and informs you.
import java.io.IOException;import java.util.Collection;import android.app.Activity;import android.content.pm.PackageManager;import android.hardware.Camera;import android.hardware.Camera.AutoFocusCallback;import android.os.Bundle;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.WindowManager;import android.widget.CompoundButton;import android.widget.Toast;import android.widget.ToggleButton;
public class MainActivity extends Activity implements SurfaceHolder.Callback { private static String TAG = "flashlight"; private ToggleButton toggleButton1; boolean cameraOpened; private boolean hasSurface; static Camera cam = null;
@Override public void onPause() { Log.i(TAG, "[32] onPause()"); super.onPause(); if (cam != null) { Log.i("flashlight", "[35] onPause() cam not null. Calling stopPreview and release cam. Setting cam to null."); cam.stopPreview(); cam.release(); cam = null; } }
public void turnFlashOn() { Log.i(TAG, "[42] turnFlashOn()"); if (cam == null) { Log.i(TAG, "turnFlashOn() step 1"); cam = Camera.open(); Log.i(TAG, "[64] turnFlashOn() cam was null. Camera.open() called"); /* new stuff */ SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view); SurfaceHolder surfaceHolder = surfaceView.getHolder(); Log.i(TAG, "[174] turnFlashOn() calling initCamera(surfaceHolder) hasSurface is " + hasSurface ); initCamera(surfaceHolder); /* end new stuff */ } if (cam != null) { Log.i(TAG, "[67] turnFlashOn() cam nit null. calling setDesiredCameraParameters(cam)."); setDesiredCameraParameters(cam); Log.i(TAG, "[69] turnFlashOn() before startPreview"); cam.startPreview(); Log.i(TAG,"[75] turnFlashOn() after startPreview"); cam.autoFocus(new AutoFocusCallback() { public void onAutoFocus(boolean success, Camera camera) { if (success) { Log.i(TAG, "[80] turnFlashOn() onAutoFocus success = true"); } else { Log.i(TAG, "[83] turnFlashOn() onAutoFocus success = false"); } } }); } }
void setDesiredCameraParameters(Camera camera) { Camera.Parameters parameters = camera.getParameters(); Log.i("flashlight", "[77] FlashlightActivity.java setDestiredVcmaeria paramers"); if (parameters == null) { Log.w(TAG, "Device error: no camera parameters are available. Proceeding without configuration."); return; }
Log.i(TAG, "[84] Initial camera parameters: " + parameters.flatten());
// SharedPreferences prefs = // PreferenceManager.getDefaultSharedPreferences(context);
initializeTorch(parameters); camera.setParameters(parameters); }
private void initializeTorch(Camera.Parameters parameters) { Log.i(TAG, "[95] initializeTorch()"); doSetTorch(parameters); }
private void doSetTorch(Camera.Parameters parameters) { Log.i(TAG, "[100] dosetTorch()"); String flashMode;
flashMode = findSettableValue(parameters.getSupportedFlashModes(), Camera.Parameters.FLASH_MODE_TORCH); Log.i(TAG, "[104] doSetTorch() flashmode is " + flashMode); // , // Camera.Parameters.FLASH_MODE_ON, // Camera.Parameters.FOCUS_MODE_INFINITY); if (flashMode != null) { Log.i(TAG, "[109] openDriver() called parameters.setFlashMode( " + flashMode + ")"); parameters.setFlashMode(flashMode); }
}
private static String findSettableValue(Collection<String> supportedValues, String... desiredValues) { Log.i(TAG, "[117] findSettableValue() Supported values: " + supportedValues); String result = null; if (supportedValues != null) { for (String desiredValue : desiredValues) { if (supportedValues.contains(desiredValue)) { result = desiredValue; Log.i("flashlight", "[123] findSettableValue() result set to : " + desiredValue); break; } } } Log.i("flashlight", "[128] findSettableValue() Settable value: " + result); return result; }
public void turnFlashOff() { Log.i("flashlight", "[133] turnFlashOff()"); if (cam != null) { Log.i("flashlight", "[135] turnFlashOff() cam is not null."); cam.stopPreview(); cam.release(); cam = null; } }
public void addListenerOnButton() { Log.i("flashlight", "[143] addListenerOnButton()"); toggleButton1 = (ToggleButton) findViewById(R.id.tog1); toggleButton1.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Log.i("flashlight", "[148] onCheckedChanged() isChecked = " + isChecked); if (isChecked) { turnFlashOn(); } else { turnFlashOff(); } } }); }
/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { Log.i(TAG, "[163] onCreate() hasSurface is " + hasSurface ); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view); SurfaceHolder surfaceHolder = surfaceView.getHolder();
if (hasSurface) { // The activity was paused but not stopped, so the surface still // exists. Therefore // surfaceCreated() won't be called, so init the camera here. Log.i(TAG, "[174] onCreate() calling initCamera() hasSurface is " + hasSurface ); initCamera(surfaceHolder); } else { Log.i(TAG, "[177] does not have surface, so install callback and wait for surfaceCreated() to init the camera"); // Install the callback and wait for surfaceCreated() to init the // camera. surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); }
if (this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) { cam = Camera.open(); Log.i(TAG, "[202] onCreate(). Camera.open() called"); addListenerOnButton(); } else { Toast.makeText(getApplicationContext(), "This device does not have flash bulb.\nExitting.", 60) .show(); } }
@Override public void surfaceCreated(SurfaceHolder holder) { Log.i(TAG, "[196] surfaceCreated() hasSurface is " + hasSurface ); if (holder == null) { Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!"); } if (!hasSurface) { hasSurface = true; Log.i("flashlight", "[201] surfaceCreated() set hasSurface to true."); initCamera(holder); } }
@Override public void surfaceDestroyed(SurfaceHolder holder) { Log.i("flashlight", "[209] surfaceDestroyed()"); hasSurface = false; }
@Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.i("flashlight", "[216] surfaceChanged(holder,format,width,height)"); }
@Override protected void onDestroy() { Log.i("flashlight", "[220] onDestroy()"); try { cam.stopPreview(); cam.setPreviewCallback(null); try { cam.release(); } catch (Exception e) { } cam = null; } catch (Exception e) { } super.onDestroy(); }
/* new stuff */ private void initCamera(SurfaceHolder surfaceHolder) { Log.i(TAG, "[236] initCamera() trying to call openDriver(holder)");
try { openDriver(surfaceHolder); } catch (Exception e) { e.printStackTrace(); } }
/** * Opens the camera driver and initializes the hardware parameters. * * @param holder * The surface object which the camera will draw preview frames * into. * @throws IOException * Indicates the camera driver failed to open. */ public synchronized void openDriver(SurfaceHolder holder) throws IOException { Log.i(TAG, "[256] openDriver() top");
Camera theCamera = cam; if (theCamera == null) { Log.i(TAG, "[278] openDriver()"); theCamera = Camera.open(); Log.i(TAG, "[280] openDriver() Camera.open() called"); if (theCamera == null) { Log.i(TAG, "[263] openDriver()"); throw new IOException(); } cam = theCamera; } /* * do this as per * http://developer.android.com/reference/android/hardware/Camera.html * step 5 */ Log.i(TAG, "[281] openDriver() calling setPreviewDisplay(holder)"); theCamera.setPreviewDisplay(holder); }
public synchronized boolean isOpen() { return cam != null; }
/** * Closes the camera driver if still in use. */ public synchronized void closeDriver() { Log.i(TAG, "[285] closeDriver()"); if (cam != null) { cam.release(); cam = null; } }
/* end new stuff */}
Now save all and Run it.
It should work.
Thank you.
Take a look at my app on play.store -> Max-Power Flashlight Vintage