Taschenlampe - Camera Flash - App

  • 26 Antworten
  • Letztes Antwortdatum
Feelix333

Feelix333

Stamm-User
348
Hallo zusammen,

Ich möchte eine einfach App erstellen, bei der beim drücken eines Buttons die Kamera LED angeht.
Das Grundgerüst ist kein Problem - nur bekomme ich den Blitz nicht zum laufen.
Ich habe schon ca 100 Seiten auf stackoverflow durchgelesen, aber ohne Erfolg..

Der Code sieht so aus:

Code:
public class MainActivity extends Activity implements OnClickListener {

	private Button button1;	
	
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button1 = (Button)findViewById(R.id.button1);
		button1.setVisibility(View.VISIBLE);
		button1.setBackgroundColor(Color.TRANSPARENT);
		button1.setOnClickListener(this);
		
	}

	public void onClick(View arg0) {
		
		Vibrator vibrator1 = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
		
		if (arg0 == button1); {
			
			vibrator1.vibrate(80);

			Camera cam = Camera.open();
			Parameters p = cam.getParameters();
			p.setFlashMode(Parameters.FLASH_MODE_TORCH);
			cam.setParameters(p);
			cam.startPreview();
			
			}
	}
}

Im Manifest habe ich die Permissions:

Code:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" />

Statt:

Code:
Camera cam = Camera.open();
			Parameters p = cam.getParameters();
			p.setFlashMode(Parameters.FLASH_MODE_TORCH);
			cam.setParameters(p);
			cam.startPreview();

Hatte ich auch schon:

Code:
Camera flash;
		    Camera flash;
		    Camera.Parameters params;
		    flash = Camera.open();
		    params = flash.getParameters();
		    params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);        
		    flash.setParameters(params);

Bin gerade etwas ratlos..
Ich entwickle mit dem aktuellem SDK auf meinem Nexus 5, falls das relevant ist.

Hoffe ihr könnt mir helfen!
Danke!

mfg
Felix
 
Hattest du auch mal das mit dem
Code:
cam.autoFocus(new AutoFocusCallback() {
                public void onAutoFocus(boolean success, Camera camera) {
                }
            });
probiert?


Auch benutzen sie hier etwas mehr berechtigungen:
Code:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera.flash" />


Der ursprüngliche Beitrag von 14:28 Uhr wurde um 14:29 Uhr ergänzt:

Stop, alle man zurück! :D

Schau dir mal deine if() an:
Code:
if (arg0 == button1); {
			
			vibrator1.vibrate(80);

			Camera cam = Camera.open();
			Parameters p = cam.getParameters();
			p.setFlashMode(Parameters.FLASH_MODE_TORCH);
			cam.setParameters(p);
			cam.startPreview();
			
			}
Na? Wo wird sie schon beendet? ;)
Dein Code wird niemas ausgeführt...

Gruß
 
  • Danke
Reaktionen: Feelix333
Ich habe nicht den kompletten Code eingefügt ;)
Keine Angst so einfach ist es nicht - die if() wird schon beendet^^

Das andere Probieren ich gleich mal aus :)

Gruß
 
StefMa schrieb:
Stop, alle man zurück! :D

Schau dir mal deine if() an:
Code:
if (arg0 == button1)[COLOR="Red"][SIZE="5"];[/SIZE][/COLOR] {
			
			vibrator1.vibrate(80);

			Camera cam = Camera.open();
			Parameters p = cam.getParameters();
			p.setFlashMode(Parameters.FLASH_MODE_TORCH);
			cam.setParameters(p);
			cam.startPreview();
			
			}
Na? Wo wird sie schon beendet? ;)
Dein Code wird niemas ausgeführt...

Gruß

Gutes Auge, wär mir gar nicht aufgefallen :biggrin: Aber der Code wird ausgeführt, und zwar immer, egal ob die Bedingung erfüllt ist oder nicht. Nach dem Semikolon folgt ein neuer Code-Block, der nichts mehr mit der if-Anweisung zu tun hat.
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: Feelix333
Stimmt Zoopa ;)
Dennoch ist das if "falsch" ^^
 
  • Danke
Reaktionen: Feelix333
Ich geb mal den weiteren Hinweis:

View == Button?
 
  • Danke
Reaktionen: Feelix333
Das sollte aber m.M.n. funktionieren, wenn es die gleichen Objekte sind.
Aber ein equals ist eigentlich immer die bessere Variante. ;)
 
  • Danke
Reaktionen: Feelix333
Hallo zusammen,

StefMa schrieb:
Auch benutzen sie hier etwas mehr berechtigungen:
Code:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera.flash" />
An den Berechtigungen liegt es imho nicht.
Sonst würde ich ja die Fehlermeldung 'Application requires permission' bekommen.
Aber nichts desto trotz - ausprobiert und keine Veränderung.

Ich habe auch schon dieses Tutorial ausprobiert.
Selbst wenn ich den Code 1-zu-1 kopiere funktioniert die LED nicht!
LogCat gibt mir zwar 'Torch is turn on!/off!' aus, aber es geht nichts.

Liegt das an meinem Nexus 5 und 4.4 KitKat?

Mit
Code:
button1.getId() == ((Button)arg0).getId()
statt dem
Code:
arg0 == button1
geht es genauso wenig, kleinerkathe ;)

Der Code sieht so aus:
(Mit allen Klammern und Semikolons ;) )

Code:
public class MainActivity extends Activity implements OnClickListener {

	private Button button1;	
	
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button1 = (Button)findViewById(R.id.button1);
		button1.setVisibility(View.VISIBLE);
		button1.setBackgroundColor(Color.TRANSPARENT);
		button1.setOnClickListener(this);
		
	}

	public void onClick(View arg0) {
		
		Vibrator vibrator1 = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
		
		if (button1.getId() == ((Button)arg0).getId()) {
			
			vibrator1.vibrate(80);

			Camera cam = Camera.open();
			Parameters p = cam.getParameters();
			p.setFlashMode(Parameters.FLASH_MODE_TORCH);
			cam.setParameters(p);
			cam.startPreview();
			
			}
	}
}

Auch wenn er klar nicht so gut ist wie der im oben beschriebenen Tutorial arbeite ich wieder an meinem eigenem.

Kann mir irgendjemand helfen, langsam wird es frustrierend, das es selbst mit einem scheinbar perfektem Code nicht funktioniert?!

Gruß
Felix
 
Zuletzt bearbeitet:
Ich habe diesen Link gefunden, vielleicht ist das bei dir dasselbe Problem. Der Entwickler sagt dort, dass es bei einigen Geräten nur funktioniert, wenn eine SurfaceView verwendet wird.

Bin nicht ganz sicher ob ich deinen letzten Kommentar mit den Semikolons und Klammern richtig oder falsch verstanden habe :razz: Aber der eine Fehler, den StefMa ganz am Anfang entdeckt hat, ist immernoch drin (Hat aber erstmal nichts mit deinem eigentlichen Problem zu tun).

Code:
if (button1.getId() == ((Button)arg0).getId()); {

Du hast ein Semikolon zwischen der schliessenden runden Klammer und der öffnenden geschweiften Klammer. Dadurch hast du eine "leere" if-Abfrage und der Code in den geschweiften Klammer wird immer ausgeführt.

Ausserdem kannst du dir den Cast in der if-Abfrage sparen. Aber deine ursprüngliche Variante
Code:
arg0 == button1
sollte auch funktionieren. Ist meiner Meinung nach sogar lesbarer bei if-Abfragen.

Wobei ich auch getId() verwenden würde, aber im Zusammenhang mit einem switch-Statement:

Code:
public void onClick(View arg0) {
    switch(arg0.getId()) {
        case R.id.button1:
            //...
        case R.id.button2:
           //
    }
}

aber das ist schlussendlich Geschmacksache ;)
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: Feelix333
Ah!
Jetzt habe ich das Semikolon gefunden was ihr gemeint habt!
So wäre die if-Abfrage richtig ;)
Code:
if (arg0 == button1) {

Aber selbst wenn ich es so ändere, passiert beim ersten Klick auf den transparenten Button absolut nichts (aber durch die Vibration merke ich, das er gedrückt wurde) - und beim zweiten Klick wird die App beendet (LogCat: RuntimeException: Fail to connect to camera service).
Code:
switch(arg0.getId()) {
        case R.id.button1:
			
			vibrator1.vibrate(80);

			Camera cam = Camera.open();
			Parameters p = cam.getParameters();
			p.setFlashMode(Parameters.FLASH_MODE_TORCH);
			cam.setParameters(p);
			cam.startPreview();
			
			}

Das kann doch nicht so schwierig sein??
Warum funktioniert das nicht?
Kann doch nicht an meinem Nexus 5 liegen?

Mit dem SurfaceView bin ich gerade ziemlich überfordert.. :-/
 
Ob du if oder switch verwendest ist eigentlich egal, nimm das, was dir am besten gefällt ;)

Du könntest mal folgenden Code testen:

Code:
public class MainActivity extends Activity implements SurfaceHolder.Callback{
Camera mCamera;
public static SurfaceView preview;
public static SurfaceHolder mHolder;

public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    preview = (SurfaceView) findViewById(R.id.camSurface);
    mHolder = preview.getHolder();
    mHolder.addCallback(this);
    mCamera = Camera.open();
    try {
        mCamera.setPreviewDisplay(mHolder);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Button onLEDbtn = (Button) findViewById(R.id.button1);
    onLEDbtn.setOnClickListener(new OnClickListener(){

        public void onClick(View v) {
            Toast.makeText(getApplicationContext(), "test", Toast.LENGTH_SHORT).show();
            Parameters params = mCamera.getParameters();
            params.setFlashMode(Parameters.FLASH_MODE_TORCH);
            mCamera.setParameters(params);      
            mCamera.startPreview();
        }

    });
}

in deiner activity_main.xml musst du noch eine SurfaceView hinzufügen:

Code:
<SurfaceView
    android:id="@+id/camSurface"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />

evtl musst du die Grösse noch etwas anpassen, falls dein Layout sonst kaputt geht. Aber anscheinend darf die Grösse der SurfaceView nicht 0 sein

Selber testen kann ich das leider grad nicht, aber den Code hab ich von HIER (noch angepasst um den ersten Kommentar und einige Namen / IDs geändert)
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: Feelix333
Ja, ich weiß - ich persönlich nehme meist if() ;)

Hab den Code von dir verwendet, Variablen und Namen angepasst und Methoden implementiert.
Code:
public class MainActivity extends Activity implements SurfaceHolder.Callback{
Camera mCamera;
public static SurfaceView preview;
public static SurfaceHolder mHolder;
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    preview = (SurfaceView) findViewById(R.id.camSurface);
    mHolder = preview.getHolder();
    mHolder.addCallback(this);
    mCamera = Camera.open();
    try {
        mCamera.setPreviewDisplay(mHolder);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Button onLEDbtn = (Button) findViewById(R.id.button1);
    onLEDbtn.setOnClickListener(new OnClickListener(){

        public void onClick(View v) {
            Toast.makeText(getApplicationContext(), "test", Toast.LENGTH_SHORT).show();
            Parameters params = mCamera.getParameters();
            params.setFlashMode(Parameters.FLASH_MODE_TORCH);
            mCamera.setParameters(params);      
            mCamera.startPreview();
        }

    });
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
		int height) {
	// TODO Auto-generated method stub
	
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
	// TODO Auto-generated method stub
	
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
	// TODO Auto-generated method stub
	
}
}
Es funktioniert allerdings trotzdem nicht - der Toast "test" wird ausgegeben, aber das war es auch schon. LogCat sagt auch nichts weiter. Kein Fehler nichts - nur die Kamera-LED scheint einfach nicht angehen zu wollen -.-
 
siehst du die SurfaceView? Ich denke, darin sollte dargestellt werden, was die Kamera gerade sieht. Habe nochmals nachgelesen: Laut Stackoverflow muss die Grösse der SurfaceView > 0 sein und sie muss anscheinend auch sichtbar sein. Sonst weiss ich ehrlich gesagt auch nicht mehr weiter
 
  • Danke
Reaktionen: Feelix333
Ja, die SurfaceView ist da - ein großes, rechteckiges, schwarzes Feld.
Darunter ist der button1. Allerdings sehe ich nach dem starten der App nicht das was die Kamera "sehen" sollte.
Ja ich hab auch gelesen >0 und nicht transparent.
Ich habe auch keine von beiden eingestellt.

Bin auch echt am Ende - dachte mir das kann doch nicht so schwer sein?
Weiß auch nicht ob es am Nexus 5 und Android 4.4.2 liegt.
Kann ich aber kaum glauben - schließlich funktioniert diese App seid jeher auch einwandfrei..

Falls noch jemand eine Idee hat und Code den man ausprobieren könnte gerne immer raus damit.

Danke!
mfg
Felix
 
Hat niemand eine Idee - oder vielleicht auch ein Nexus 5 auf dem er das testen könnte?
Wäre echt super :thumbup:

EDIT:

Ich habe jetzt diesen Code hier von stackoverflow:

Code:
public void onClick(View arg0) {
		
		Vibrator vibrator1 = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
		
		if (arg0 == button1) {
				
				vibrator1.vibrate(80);
				
				cam = Camera.open();     
			    Parameters params = cam.getParameters();
			    params.setFlashMode(Parameters.FLASH_MODE_ON);
			    cam.setParameters(params);
			    cam.startPreview();
			    cam.autoFocus(new AutoFocusCallback() {
			                public void onAutoFocus(boolean success, Camera camera) {
			                }
			            });
			}
	}

Nein, es funktioniert immer noch nicht - aber ich bekomme eine neue Fehlermeldung (Neue Fehlermeldung, neues Glück :D).
Beim klick auf den Button wird die App geschlossen und LogCat gibt aus:
FATAL EXCEPTION: main
RuntimeException: autoFocus failed

Können wir damit mehr anfangen?
An den Rechten kann es wieder wsl nicht liegen, da ist immer noch die gesamte Palette im Manifest:

Code:
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera.flash" />
Danke!

Gruß
Felix
 
Zuletzt bearbeitet:
So gerade mal nachgebaut deinen Code.
Was dir fehlt ist, dass du die surfaceView auch an die Camera anbindest.

cam.setPreviewDisplay(surfaceView.getHolder());

läuft zumindest so bei mir auf dem Nexus 5 beim 2. klick stürzt er natürlich ab, aber das dürfte dann das geringe übel sein.

EDIT:
Auch wenn ich eigentlich schlafen sollte Hier mal meine "fertige" Taschenlampe.
Ich kann den button drücken zum einschalten und zum ausschalten.
SurfaceView muss mindeste 1x1 groß sein.

Code:
package de.amfa.Flashlight;

import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Vibrator;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;

public class Flashlight extends Activity implements View.OnClickListener{
    Button button1;
    SurfaceView surfaceView;
    boolean isOn = false;
    Camera cam = null;

    /**
     * Called when the activity is first created.
     *
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        button1 = (Button)findViewById(R.id.button1);
        button1.setOnClickListener(this);
        surfaceView = (SurfaceView)findViewById(R.id.surfaceView);

    }
    public void onClick(View arg0) {

        Vibrator vibrator1 = (Vibrator) getSystemService(this.VIBRATOR_SERVICE);

        if (arg0 == button1) {

            if (!isOn) {
                cam = Camera.open();
            vibrator1.vibrate(80);
            try {
            cam.setPreviewDisplay(surfaceView.getHolder());
            }
            catch (java.io.IOException ioe) {

            }
            Camera.Parameters params = cam.getParameters();
            params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
            cam.setParameters(params);
            cam.startPreview();
                cam.autoFocus(new Camera.AutoFocusCallback() {
                    public void onAutoFocus(boolean success, Camera camera) {
                    }
                });
            isOn = true ;
            }
            else {
                if (cam != null) {
                 cam.stopPreview();
                cam.release();
             }
                isOn = false;

            }
        }
    }
}
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: Feelix333
Danke amfa!
Du hattest recht, eine SurfaceView wird benötigt.

Ganz funktioniert es allerdings noch nicht.
Ich habe deinen Code so übernommen und mir im Layout eine 250x250px SurfaceView über einem 250x250px Button erstellt.

Beim ersten Klick auf den Button leuchtet das Licht nur solange wie die Kamera fokussiert (sehe ich am Bildausschnitt im SurfaceView).
Dann geht die LED wieder aus.
Beim zweiten Klick friert das Bild ein (als ob ein Foto geschossen wurde), aber das Licht bleibt aus.
Beim dritten Klick ist es dann wieder wie beim ersten Klick:
Kamera-LED leuchtet für kurzen Augenblick bis fokussiert wurde.


Wir sind nah dran, aber ganz passt es noch nicht!
Ich probiere mal noch bisschen rum - sollte jemand bis dahin des Rätsels Lösung haben, kann er ja hier bitte Bescheid geben.

Danke!

mfg
Felix
 
Camera.Parameters.FLASH_MODE_TORCH
Sollte die Lösung sein.
(Ich hab beim testen nicht lang genug gewartet ;))
 
  • Danke
Reaktionen: Feelix333
Verdammt! Das hätte mir doch auch noch auffallen müssen! :D
Danke jetzt funktioniert es! :)
 
Zurück
Oben Unten