Autore Topic: Applicazione che si stoppa  (Letto 806 volte)

Offline enrico_84

  • Nuovo arrivato
  • *
  • Post: 29
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy SII
  • Sistema operativo:
    Windows 7
Applicazione che si stoppa
« il: 12 Giugno 2013, 14:22:01 CEST »
0
Salve, ho creato una piccola app che scatta foto, registra video e li riproduce. Ho create tre pulsanti, Scatta, Registra e Riproduci per riprodurre i video registrati. Dopo che premo il tasto per Riprodurre, e successivamente lo stoppo, quando poi vado a premere ad esempio il tasto per fare foto "Scatta", l'app si chiude inaspettatamente. Però nel logcat non vengono riportati errori, e ciò mi sembra strano. Come mai l'app allora si chiude? Grazie

Offline theBaffo

  • Utente normale
  • ***
  • Post: 164
  • Respect: +24
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Nexus
  • Sistema operativo:
    Windows 8.1
Re:Applicazione che si stoppa
« Risposta #1 il: 12 Giugno 2013, 14:43:14 CEST »
0
Intanto posta il codice che viene eseguito dai vari pulsanti, e il logcat, cosi vediamo cos'è che non và  ;-)
Se ti sono stato utile, premi "thanks" ;)

"Errare è umano, ma per incasinare davvero tutto è necessario un computer" - Arthur Bloch

Offline enrico_84

  • Nuovo arrivato
  • *
  • Post: 29
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy SII
  • Sistema operativo:
    Windows 7
Re:Applicazione che si stoppa
« Risposta #2 il: 12 Giugno 2013, 18:31:25 CEST »
0
Vi riporto il file .java per intero:
Codice (Java): [Seleziona]
package com.enrico.scattaAcquisisci;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.media.CamcorderProfile;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.view.SurfaceHolder.Callback;
import android.widget.Toast;

public class ScattaAcquisisciActivity extends Activity {
       
        private Camera camera;
        private boolean anteprimaAttiva;
        private int scattate = 0;
       
        private SurfaceHolder surfaceHolder;
       
        private MediaRecorder mediaRecorder;
        private MediaPlayer mediaPlayer;
       
        private boolean registrando;
        private boolean riproducendo;

        //Metodo che gestice l'activity principale
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_scatta_acquisisci);
               
                //Otteniamo un riferimento all'oggetto SurfaceView del layout
                SurfaceView surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
                //Otteniamo l'oggetto SurfaceHolder che gestisce la SurfaceView
                surfaceHolder = surfaceView.getHolder();
                //Aggiungiamo al gestore SurfaceHolder la nostra classe MyCallback
                surfaceHolder.addCallback(new MyCallback());
        }
       
       
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                // Inflate the menu; this adds items to the action bar if it is present.
                getMenuInflater().inflate(R.menu.scatta_acquisisci, menu);
                return true;
        }
       
       
        //Metodo associato al Button "scatta"
        public void scatta(View button) {
                camera.takePicture(null, null, new MyPictureCallback());
                Toast.makeText(this, "Immagine salvata", Toast.LENGTH_LONG).show();
        }
       
       
        /* Metodo che rilascia la camera per passare
         * dallo stato di anteprima a quello di registrazione video */

        private void disposeCamera() {
                camera.stopPreview();
                camera.release();
                camera = null;
                anteprimaAttiva = false;
        }
       
       
        /* Metodo che rilascia l'oggetto registrazione
         * e riattiva l'anteprima della camera*/

        private void resetCamera() {
                camera = Camera.open();
                anteprimaAttiva = true;
                try {
                        camera.setPreviewDisplay(surfaceHolder);
                } catch(IOException e) {
                        e.printStackTrace();
                }
                camera.startPreview();
        }
       
       
        //Metodo associato al Button "registra"
        public void registra(View button) {
                if(!riproducendo) { //Se non è in riproduzione un filmato...
                        if(!registrando) { //..e se la registrazione non è attiva
                               
                                disposeCamera();  //Metto da parte l'oggetto camera
                               
                                preparaRegistrazione();
                               
                                mediaRecorder.start();  //Avvio la registrazione col metodo start()
                               
                                Toast.makeText(this, "Ora sto registrando...",
                                  Toast.LENGTH_SHORT).show(); //Informo l'utente che sto registrando
                               
                        ((Button) button).setText("Stop"); //Modifico il testo del bottone
                               
                                registrando = true;
                       
                        } else {  //Se invece la registrazione è già attiva
                               
                                fermaRegistrazione();
                               
                                Toast.makeText(this, "Registrazione terminata",
                                  Toast.LENGTH_SHORT).show(); //Informo l'utente della registrazione terminata
                               
                                ((Button) button).setText("Registra");  //Modifico il testo del bottone
                               
                                registrando = false;
                        }
                }
        }
       
       
        //Preparo l'oggetto mediaRecorder alla registrazione video su file
        private void preparaRegistrazione() {
                /* Assegno microfono e camera esterna come sorgenti
                * del flusso da registrare */

                mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
                mediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
               
                //Specifico la qualità del video
                mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
               
                //Specifico il file in cui salvo la registrazione
                mediaRecorder.setOutputFile("/sdcard/MioVideo.mp4");
               
                /* Setto la durata massima della registrazione
                * e lo spazio massimo occupato in memoria */

                mediaRecorder.setMaxDuration(60000); //1 minuto registrato
                mediaRecorder.setMaxFileSize(5000000); //5 MB occupati
               
                /* Specifico che l'anteprima della registrazione sarà mostrata
                * sulla superficie del surfaceHolder */

                mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
               
                try {                        //rendo effettivi i settaggi fatti
                        mediaRecorder.prepare(); //e preparo l'oggetto mediaRecorder alla chiamata
                } catch (Exception e) {      //del metodo start()
                        e.printStackTrace();
            }
        }
       
       
        //Fermo la registrazione video
        public void fermaRegistrazione() {
                mediaRecorder.stop();  //chiudo il flusso che arriva al file
                mediaRecorder.release();  //libero la memoria
                resetCamera();         //ripristino lo stato iniziale della camera
        }
       
       
        /* Metodo che riproduce i filmati registrati
        * associato al Button "play" */

        public void play(View button) {
                if(!registrando) { //Se non sta registrando un filmato...
                    if(!registrando) { //..e se non sta riproducendo
                               
                                disposeCamera();  //Metto da parte l'oggetto camera
                               
                                avviaRiproduzione();
                               
                                Toast.makeText(this, "Riproduzione avviata...",
                                  Toast.LENGTH_SHORT).show(); //Informo l'utente che sto riproducendo
                               
                        ((Button) button).setText("Stop"); //Modifico il testo del bottone
                               
                                riproducendo = true;
                       
                        } else {  //Se invece la riproduzione è già attiva
                               
                                terminaRiproduzione();
                               
                                Toast.makeText(this, "Riproduzione terminata",
                                  Toast.LENGTH_SHORT).show(); //Informo l'utente che la riproduzione è terminata
                               
                                ((Button) button).setText("Play");  //Modifico il testo del bottone
                               
                                riproducendo = false;
                        }
                }
        }
       
       
        //Preparo l'oggetto mediaPlayer alla riproduzione del filmato
        private void avviaRiproduzione() {
                mediaPlayer = new MediaPlayer(); //inizializzo il mediaPlayer
               
                //Mi riferisco al file creato in fase di registrazione
                File file = new File("/sdcard/MioVideo.mp4");
                try {
                        mediaPlayer.setDataSource(file.getAbsolutePath()); //fonte da cui riprodurre
                       
                        mediaPlayer.setDisplay(surfaceHolder);
                       
                        //il video viene riprodotto all'infinito
                        //finchè non viene fermato manualmente
                        mediaPlayer.setLooping(true);
                       
                        mediaPlayer.prepare(); //rendo effettivi i settaggi
               
                } catch (Exception e) {
                        e.printStackTrace();
                }
               
                mediaPlayer.start(); //avvio la riproduzione
        }
       
       
        //Metodo per fermare la riproduzione
        private void terminaRiproduzione() {
                mediaPlayer.stop();
                mediaPlayer.release();
                mediaPlayer = null; //elimino l'oggetto mediaPlayer
                resetCamera();
        }
       
       
        private class MyCallback implements Callback {
               
                //Metodo che inizializza la SurfaceView
                @Override
                public void surfaceCreated(SurfaceHolder holder) {
                        camera = Camera.open();
                        registrando = false;
                        riproducendo = false;
                        mediaRecorder = new MediaRecorder(); //inizializzo il mediaRecorder
                }
       
               
                //Metodo che si attiva quando si modifica la SurfaceView
                @Override
                public void surfaceChanged(SurfaceHolder holder, int format, int width,
                                int height) {
                        if(anteprimaAttiva)
                                camera.stopPreview();
                       
                        camera.getParameters().setPreviewSize(width, height);
                       
                        try {
                                camera.setPreviewDisplay(holder);
                        } catch (IOException e) {
                                e.printStackTrace();
                        }
                       
                        camera.startPreview(); //avvia l'anteprima della camera
                       
                        anteprimaAttiva = true;
                }


                //Metodo che si attiva quando l'anteprima non è più utilizzata
                @Override
                public void surfaceDestroyed(SurfaceHolder holder) {
                        if(camera != null) {
                                camera.stopPreview();
                                anteprimaAttiva = false;
                                camera.release(); //rilascia la memoria occupata dalla camera
                                camera = null;
                       
                        }
                        if(mediaRecorder != null) {
                                mediaRecorder.release();
                                mediaRecorder = null;  //elimino il mediaRecorder
                        }
                        registrando = false;
                        riproducendo = false;
            }
    }
       
        //Classe che gestisce lo scatto
        private class MyPictureCallback implements PictureCallback {

                /* Metodo che prende l'oggetto camera che scatta la foto
                 * e la foto stessa sotto forma di array di byte */

                @Override
                public void onPictureTaken(byte[] data, Camera camera) {
                       
                        scattate++;
                       
                        /* Oggetto file che si riferisce alla cartella
                           in cui memorizziamo le foto */

                        File memoriaSD = Environment.getExternalStorageDirectory();
                       
                        //Stringa che rappresenta il nome delle foto
                        String nameFile = "foto" + "scattate" + ".jpg";
                       
                        //File che fa riferimento alla foto
                        File imgFile = new File(memoriaSD, nameFile);
                       
                        try {
                                FileOutputStream fos = new FileOutputStream(imgFile);
                                //Salvo l'immagine compressa in Bitmap
                                BitmapFactory.decodeByteArray(data, 0,
                                                data.length).compress(CompressFormat.JPEG, 100, fos);
                        } catch (FileNotFoundException e) {
                                e.printStackTrace();
                        }
                       
                        camera.startPreview();
                       
                }
               
        }
       
}

Mentre il logCat è questo:
06-12 16:25:46.140: W/Trace(1758): Unexpected value from nativeGetEnabledTags: 0
06-12 16:25:46.140: E/Trace(1758): error opening trace file: No such file or directory (2)
06-12 16:25:46.140: W/Trace(1758): Unexpected value from nativeGetEnabledTags: 0
06-12 16:25:46.140: W/Trace(1758): Unexpected value from nativeGetEnabledTags: 0
06-12 16:25:46.250: W/Trace(1758): Unexpected value from nativeGetEnabledTags: 0
06-12 16:25:46.250: W/Trace(1758): Unexpected value from nativeGetEnabledTags: 0
06-12 16:25:46.280: W/Trace(1758): Unexpected value from nativeGetEnabledTags: 0
06-12 16:25:47.850: W/Trace(1758): Unexpected value from nativeGetEnabledTags: 0
06-12 16:25:47.850: W/Trace(1758): Unexpected value from nativeGetEnabledTags: 0
06-12 16:25:47.860: W/Trace(1758): Unexpected value from nativeGetEnabledTags: 0
06-12 16:25:47.860: W/Trace(1758): Unexpected value from nativeGetEnabledTags: 0

Offline theBaffo

  • Utente normale
  • ***
  • Post: 164
  • Respect: +24
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Nexus
  • Sistema operativo:
    Windows 8.1
Re:Applicazione che si stoppa
« Risposta #3 il: 13 Giugno 2013, 09:17:02 CEST »
+1
Se ti sono stato utile, premi "thanks" ;)

"Errare è umano, ma per incasinare davvero tutto è necessario un computer" - Arthur Bloch

Offline enrico_84

  • Nuovo arrivato
  • *
  • Post: 29
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy SII
  • Sistema operativo:
    Windows 7
Re:Applicazione che si stoppa
« Risposta #4 il: 13 Giugno 2013, 17:34:08 CEST »
0
Quindi dovrei usare un Api che va dalla 16 in giù, da come specificato nel link che mi hai messo. Ho modificato l'emulatore inserendo come target una API 15 e poi una API 16, solo che l'app non parte proprio. Così  ho provato a cambiare il device, inserendo un Nexus 4, poi un Nexus 7 e poi un Nexus 10 e sempre con API 17, ma l'app non parte ancora.  Poi se torno al vecchio emulatore che ho provato all'inizio mi da questo errore :

06-13 15:52:51.660: W/Trace(1610): Unexpected value from nativeGetEnabledTags: 0
06-13 15:52:51.660: W/Trace(1610): Unexpected value from nativeGetEnabledTags: 0
06-13 15:52:51.670: D/AndroidRuntime(1610): Shutting down VM
06-13 15:52:51.670: W/dalvikvm(1610): threadid=1: thread exiting with uncaught exception (group=0xb5cc9908)
06-13 15:52:51.670: E/AndroidRuntime(1610): FATAL EXCEPTION: main
06-13 15:52:51.670: E/AndroidRuntime(1610): java.lang.IllegalStateException: Could not execute method of the activity
06-13 15:52:51.670: E/AndroidRuntime(1610):    at android.view.View$1.onClick(View.java:3597)
06-13 15:52:51.670: E/AndroidRuntime(1610):    at android.view.View.performClick(View.java:4202)
06-13 15:52:51.670: E/AndroidRuntime(1610):    at android.view.View$PerformClick.run(View.java:17340)
06-13 15:52:51.670: E/AndroidRuntime(1610):    at android.os.Handler.handleCallback(Handler.java:725)
06-13 15:52:51.670: E/AndroidRuntime(1610):    at android.os.Handler.dispatchMessage(Handler.java:92)
06-13 15:52:51.670: E/AndroidRuntime(1610):    at android.os.Looper.loop(Looper.java:137)
06-13 15:52:51.670: E/AndroidRuntime(1610):    at android.app.ActivityThread.main(ActivityThread.java:5039)
06-13 15:52:51.670: E/AndroidRuntime(1610):    at java.lang.reflect.Method.invokeNative(Native Method)
06-13 15:52:51.670: E/AndroidRuntime(1610):    at java.lang.reflect.Method.invoke(Method.java:511)
06-13 15:52:51.670: E/AndroidRuntime(1610):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
06-13 15:52:51.670: E/AndroidRuntime(1610):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
06-13 15:52:51.670: E/AndroidRuntime(1610):    at dalvik.system.NativeStart.main(Native Method)
06-13 15:52:51.670: E/AndroidRuntime(1610): Caused by: java.lang.reflect.InvocationTargetException
06-13 15:52:51.670: E/AndroidRuntime(1610):    at java.lang.reflect.Method.invokeNative(Native Method)
06-13 15:52:51.670: E/AndroidRuntime(1610):    at java.lang.reflect.Method.invoke(Method.java:511)
06-13 15:52:51.670: E/AndroidRuntime(1610):    at android.view.View$1.onClick(View.java:3592)
06-13 15:52:51.670: E/AndroidRuntime(1610):    ... 11 more
06-13 15:52:51.670: E/AndroidRuntime(1610): Caused by: java.lang.NullPointerException
06-13 15:52:51.670: E/AndroidRuntime(1610):    at com.enrico.scattaAcquisisci.ScattaAcquisisciActivity.disposeCamera(ScattaAcquisisciActivity.java:73)
06-13 15:52:51.670: E/AndroidRuntime(1610):    at com.enrico.scattaAcquisisci.ScattaAcquisisciActivity.play(ScattaAcquisisciActivity.java:171)
06-13 15:52:51.670: E/AndroidRuntime(1610):    ... 14 more



Non è che è qualcosa nel codice che non và?
« Ultima modifica: 13 Giugno 2013, 17:59:46 CEST da enrico_84 »

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Applicazione che si stoppa
« Risposta #5 il: 13 Giugno 2013, 19:20:12 CEST »
0
Non so esattamente quale sia il problema e nemmeno se è un problema o un bug, però in generale prima di usare un qualsiasi oggetto è buona norma controllare SEMPRE che non sia null (perchè se qualcosa può essere null, prima o poi lo sarà quando meno te lo aspetti).

Cioè questo:
Codice (Java): [Seleziona]
camera.stopPreview();
Lo cambierei in:
Codice (Java): [Seleziona]
if (camera!=null) camera.stopPreview();
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline enrico_84

  • Nuovo arrivato
  • *
  • Post: 29
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy SII
  • Sistema operativo:
    Windows 7
Re:Applicazione che si stoppa
« Risposta #6 il: 13 Giugno 2013, 20:10:27 CEST »
0
Non so esattamente quale sia il problema e nemmeno se è un problema o un bug, però in generale prima di usare un qualsiasi oggetto è buona norma controllare SEMPRE che non sia null (perchè se qualcosa può essere null, prima o poi lo sarà quando meno te lo aspetti).

Cioè questo:
Codice (Java): [Seleziona]
camera.stopPreview();
Lo cambierei in:
Codice (Java): [Seleziona]
if (camera!=null) camera.stopPreview();

Quindi dici di cambiare il codice solo nel metodo disposeCamera() ?
O anche nel metodo surfaceChanged()?

Ho fatto come tu dici ma gli errori rimangono sempre

Post unito: 13 Giugno 2013, 20:41:14 CEST
C'era un errore nel metodo play, l'ho corretto ed ora funziona
« Ultima modifica: 13 Giugno 2013, 20:41:14 CEST da enrico_84, Reason: Merged DoublePost »

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Applicazione che si stoppa
« Risposta #7 il: 13 Giugno 2013, 20:47:31 CEST »
0
Quindi dici di cambiare il codice solo nel metodo disposeCamera() ?
O anche nel metodo surfaceChanged()?

Come buona norma generale, ogni volta che usi un oggetto che può essere null, controlla che non lo sia prima di usarlo. Altrimenti prima o poi genererà un nullpointerexception.

Nei casi ovvi puoi chiaramente evitare (esempio se crei l'ogetto due righe prima).
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline theBaffo

  • Utente normale
  • ***
  • Post: 164
  • Respect: +24
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Nexus
  • Sistema operativo:
    Windows 8.1
Re:Applicazione che si stoppa
« Risposta #8 il: 14 Giugno 2013, 09:18:59 CEST »
0
Come spiegato da bradipao, è buona norma controllare che l'oggetto non sia null. L'errore è qui:

Codice (Java): [Seleziona]
06-13 15:52:51.670: E/AndroidRuntime(1610):    at com.enrico.scattaAcquisisci.ScattaAcquisisciActivity.disposeCamera(ScattaAcquisisciActivity.java:73)
Alla riga 73 (se notepad non dice castronerie) c'è questo codice:

Codice (Java): [Seleziona]
camera.stopPreview();
Io cambierei il metodo in questo modo:

Codice (Java): [Seleziona]
private boolean disposeCamera()
{
        if(camera == null) return false;
       
        camera.stopPreview();
    camera.release();
    camera = null;
    anteprimaAttiva = false;
       
        return true;
}
« Ultima modifica: 14 Giugno 2013, 09:24:15 CEST da theBaffo »
Se ti sono stato utile, premi "thanks" ;)

"Errare è umano, ma per incasinare davvero tutto è necessario un computer" - Arthur Bloch