1
votes

We just got some Samsung Galaxy S4 running 4.3 at work and we are using a Mobile Management system that Disables the Camera for security reasons. I have created a FlashLight App (That works fine on my HTC one and Nexus 10) that I would like to use, but I get an error.

The funny thing is, if I use the built in "Assistive light" widget from Samsung, it works fine. So even with the Camera disabled, the LED still works, so it's possible, I just don't know how. I know what some of you might say, why not just use the widget... I just don't like that bulky widget and would like to have my own app.

Here are my Permissions in the Manifest

<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />

And here is my MainActivity.java

package com.company.flashlight;

import java.io.IOException;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.Vibrator;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements Callback {

    public static Camera camera;
    private boolean isFlashOn;
    private boolean hasFlash;
    private SurfaceView sView; 
    private SurfaceHolder sHolder;
    private PowerManager.WakeLock wl;
    Parameters params;
    MediaPlayer mp;
    ImageButton btnSwitch;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "DoNjfdhotDimScreen");

        // flash switch button
        btnSwitch = (ImageButton) findViewById(R.id.btnSwitch);
        sView = (SurfaceView) findViewById(R.id.PREVIEW);

        sHolder = sView.getHolder();     

        // First check if device is supporting flashlight or not
        hasFlash = getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);

        if (!hasFlash) {
            // device doesn't have or support a LED flash
            Toast toast = Toast.makeText(this, (R.string.no_flash_message), Toast.LENGTH_LONG);
            toast.setGravity(Gravity.CENTER, 0, 0);
            toast.show();
            // Show message and sho2w a white screen 
            TextView txtBkupLight=(TextView)findViewById(R.id.tvBkupLightSrc);
            txtBkupLight.setVisibility(View.VISIBLE);
            txtBkupLight.setHeight(1920);
            txtBkupLight.setBackgroundColor(Color.WHITE);

        } else {

        // get the camera
        getCamera();

        // displaying power button image
        togglePowerButtonImage();

        // Switch button click event to toggle flash on/off
        btnSwitch.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if (isFlashOn) {
                    // turn off flash
                    turnOffFlash();
                } else {
                    // turn on flash
                    turnOnFlash();
                }
            }
        });     

        }
    }

    // Get the camera
    private void getCamera() {
        if (camera == null) {
            try {
                sHolder.addCallback(this);
                if(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
                    sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
                params.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
                camera = Camera.open();
                try {
                    camera.setPreviewDisplay(sHolder);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                params = camera.getParameters();
            } catch (RuntimeException e) {
                String err = (e.getMessage()==null)?"Camera failed":e.getMessage();
                Log.e("Camera Error. Failed to Open. Error: ", err);
            }
        }
    }

    // Turning On flash
    private void turnOnFlash() {

        if (!isFlashOn) {
            if (camera == null || params == null) {
                return;
            }

            // check to see if the device can vibrate
            if ( getSystemService(VIBRATOR_SERVICE) != null ) {
            // vibrate device   
                powerVibrate();
            }else{
            // play sound
                playSound();
            }

            params = camera.getParameters();
            params.setFlashMode(Parameters.FLASH_MODE_TORCH);
            camera.setParameters(params);
            camera.startPreview();
            isFlashOn = true;

            // changing button/switch image
            togglePowerButtonImage();
        }
    }

    // Turning Off flash
    private void turnOffFlash() {

        if (isFlashOn) {
            if (camera == null || params == null) {
                return;
            }

            // check to see if the device can vibrate
            if ( getSystemService(VIBRATOR_SERVICE) != null ) {
            // vibrate device   
                powerVibrate();
            }else{
            // play sound
                playSound();
            }

            params = camera.getParameters();
            params.setFlashMode(Parameters.FLASH_MODE_OFF);
            camera.setParameters(params);
            camera.stopPreview();
            isFlashOn = false;

            // changing button/switch image
            togglePowerButtonImage();
        }
    }

    // Vibrate Phone
    public void powerVibrate() {
        if(isFlashOn){
            Vibrator vib = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
            vib.vibrate(50);
        }else{
            Vibrator vib = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
            vib.vibrate(50);
        }
    }

    // Playing sound
    // will play button toggle sound on flash on / off
    private void playSound(){
        if(isFlashOn){
            mp = MediaPlayer.create(MainActivity.this, R.raw.light_switch_off);
        }else{
            mp = MediaPlayer.create(MainActivity.this, R.raw.light_switch_on);
        }
        mp.setOnCompletionListener(new OnCompletionListener() {

            @Override
            public void onCompletion(MediaPlayer mp) {
                mp.release();
            }
        });
        mp.start();
    }

    /*
     * Toggle switch power button images
     * changing image states to on / off
     * */
    private void togglePowerButtonImage(){
        if(isFlashOn){
            btnSwitch.setImageResource(R.drawable.flashlight_on);
        }else{
            btnSwitch.setImageResource(R.drawable.flashlight_off);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    protected void onPause() {
        super.onPause();
        wl.release();

        // on pause turn off the flash
        turnOffFlash();
    }

    @Override
    protected void onRestart() {
        super.onRestart();
    }

    @Override
    protected void onResume() {
        super.onResume();
        wl.acquire();

        // on resume turn on the flash
        if(hasFlash)
            turnOnFlash();
    }

    @Override
    protected void onStart() {
        super.onStart();

        // on starting the app get the camera params
        getCamera();
    }

    @Override
    protected void onStop() {
        super.onStop();

        // on stop release the camera
        if (camera != null) {
            camera.release();
            camera = null;
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {

    }

    @Override
    public void surfaceCreated(SurfaceHolder arg0) {
        try {
            camera.setPreviewDisplay(sHolder);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {

        if (camera != null) {
            camera.release();
            camera = null;
        }
    }

    public boolean onOptionsItemSelected(MenuItem item){
        switch(item.getItemId()){
            case R.id.menuAbout:
                startActivity(new Intent(MainActivity.this, About.class));
                return true;
            case R.id.menuExit:
                finish();     
        }
            return false;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

Here is my layout file activity_main.xml

<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:background="@drawable/radial_background"
    tools:context=".MainActivity" >

            <SurfaceView
                android:id="@+id/PREVIEW"
                android:layout_width="1dip"
                android:layout_height="1dip"/>

            <ImageButton
                android:id="@+id/btnSwitch"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:background="@null"
                android:contentDescription="@null"
                android:src="@drawable/flashlight_on" />

            <TextView
                android:id="@+id/tvBkupLightSrc"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:background="@android:color/background_dark"
                android:textColor="@android:color/primary_text_dark"
                android:visibility="invisible" />

</RelativeLayout>

And here are my errors.........

01-18 11:19:26.750: E/Camera Error. Failed to Open. Error:(28886): Camera failed
01-18 11:19:26.780: D/dalvikvm(28886): GC_FOR_ALLOC freed 996K, 27% free 19145K/25948K, paused 16ms, total 16ms
01-18 11:19:26.790: I/dalvikvm-heap(28886): Grow heap (frag case) to 27.489MB for 3686416-byte allocation
01-18 11:19:26.800: E/Camera Error. Failed to Open. Error:(28886): Camera failed
01-18 11:19:27.201: D/libEGL(28886): loaded /vendor/lib/egl/libEGL_adreno.so
01-18 11:19:27.201: D/libEGL(28886): loaded /vendor/lib/egl/libGLESv1_CM_adreno.so
01-18 11:19:27.201: D/libEGL(28886): loaded /vendor/lib/egl/libGLESv2_adreno.so
01-18 11:19:27.201: I/Adreno-EGL(28886): <qeglDrvAPI_eglInitialize:316>: EGL 1.4 QUALCOMM build:  (CL4169980)
01-18 11:19:27.201: I/Adreno-EGL(28886): OpenGL ES Shader Compiler Version: 17.01.10.SPL
01-18 11:19:27.201: I/Adreno-EGL(28886): Build Date: 09/26/13 Thu
01-18 11:19:27.201: I/Adreno-EGL(28886): Local Branch: 
01-18 11:19:27.201: I/Adreno-EGL(28886): Remote Branch: 
01-18 11:19:27.201: I/Adreno-EGL(28886): Local Patches: 
01-18 11:19:27.201: I/Adreno-EGL(28886): Reconstruct Branch: 
01-18 11:19:27.251: D/OpenGLRenderer(28886): Enabling debug mode 0
01-18 11:19:27.261: D/AndroidRuntime(28886): Shutting down VM
01-18 11:19:27.261: W/dalvikvm(28886): threadid=1: thread exiting with uncaught exception (group=0x4179f898)
01-18 11:19:27.261: E/AndroidRuntime(28886): FATAL EXCEPTION: main
01-18 11:19:27.261: E/AndroidRuntime(28886): java.lang.NullPointerException
01-18 11:19:27.261: E/AndroidRuntime(28886):    at com.company.flashlight.MainActivity.surfaceCreated(MainActivity.java:272)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at android.view.SurfaceView.updateWindow(SurfaceView.java:610)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at android.view.SurfaceView.access$000(SurfaceView.java:93)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:182)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:864)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2140)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1247)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6355)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:791)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at android.view.Choreographer.doCallbacks(Choreographer.java:591)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at android.view.Choreographer.doFrame(Choreographer.java:561)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:777)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at android.os.Handler.handleCallback(Handler.java:730)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at android.os.Handler.dispatchMessage(Handler.java:92)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at android.os.Looper.loop(Looper.java:137)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at android.app.ActivityThread.main(ActivityThread.java:5419)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at java.lang.reflect.Method.invokeNative(Native Method)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at java.lang.reflect.Method.invoke(Method.java:525)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
01-18 11:19:27.261: E/AndroidRuntime(28886):    at dalvik.system.NativeStart.main(Native Method)
1
What is line 272 in MainActivity.java?Henry
camera.setPreviewDisplay(sHolder);Sobo

1 Answers

0
votes

You have a NullPointerException in line 272 in MainActivity.java. This happens because camera is null when surfaceCreated is called.