JavascriptProva

giovedì 31 marzo 2016

La mia vecchia libreria jacSpeech: la classe per il riconoscimento vocale.

Ed ecco un bel codice che ho creato un paio di anni fa in VB.NET e che devo ristudiare...

Imports System.Threading
Public Class jacRecognizer
    Dim WithEvents motore As New SpeechRecognitionEngine(New Globalization.CultureInfo("it-IT"))
    Dim costruttore As GrammarBuilder
    Dim grammatica As Grammar

    Public Event riconoscimento(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs)
    Public Event noise(ByVal sender As Object, ByVal e As SpeechDetectedEventArgs)
    Public lista As New ArrayList
    Public matrice() As String

    Sub New()
        motore.SetInputToDefaultAudioDevice()
        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")
        Dim scelte As New Choices("u")
        costruttore.Append(scelte)
        grammatica = New Grammar(costruttore)
        motore.LoadGrammar(grammatica)
        motore.RecognizeAsync(RecognizeMode.Multiple)
    End Sub
    Sub New(ByVal nomeFile As String)
        motore.SetInputToDefaultAudioDevice()

        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")

        Dim str As String = ""


        FileOpen(1, nomeFile, OpenMode.Input)
        Do Until EOF(1)
            str = LineInput(1)
            lista.Add(str)
        Loop
        FileClose(1)

        ReDim matrice(lista.Count - 1)
        lista.CopyTo(matrice)

        Dim scelte As New Choices(matrice)
        costruttore.Append(scelte)
        grammatica = New Grammar(costruttore)
        motore.LoadGrammar(grammatica)
        motore.RecognizeAsync(RecognizeMode.Multiple)
    End Sub
    Public Sub recognizing(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs) Handles motore.SpeechRecognized
        RaiseEvent riconoscimento(sender, e)
    End Sub
    Public Sub rumore(ByVal sender As Object, ByVal e As SpeechDetectedEventArgs) Handles motore.SpeechDetected
        RaiseEvent noise(sender, e)
    End Sub
End Class



Public Class jacSpeaker
    Public sintetizzatore As New SpeechSynthesizer
    Sub New()
        sintetizzatore.SetOutputToDefaultAudioDevice()
        sintetizzatore.SelectVoice("Microsoft Server Speech Text to Speech Voice (it-IT, Lucia)")
        sintetizzatore.Volume = 100
    End Sub
    Sub parla(ByVal parola As String)
        sintetizzatore.Speak(parola)
    End Sub
End Class


Public Class jacEngRecognizer
    Dim WithEvents motore As New SpeechRecognitionEngine(New Globalization.CultureInfo("en-US"))
    Dim costruttore As GrammarBuilder
    Dim grammatica As Grammar

    Public Event riconoscimento(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs)

    Public lista As New ArrayList
    Public matrice() As String


    Sub New(ByVal nomeFile As String)
        motore.SetInputToDefaultAudioDevice()

        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("en-US")

        Dim str As String = ""


        FileOpen(1, nomeFile, OpenMode.Input)
        Do Until EOF(1)
            str = LineInput(1)
            lista.Add(str)
        Loop
        FileClose(1)

        ReDim matrice(lista.Count - 1)
        lista.CopyTo(matrice)

        Dim scelte As New Choices(matrice)
        costruttore.Append(scelte)
        grammatica = New Grammar(costruttore)
        motore.LoadGrammar(grammatica)
        motore.RecognizeAsync(RecognizeMode.Multiple)
    End Sub
    Public Sub recognizing(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs) Handles motore.SpeechRecognized
        RaiseEvent riconoscimento(sender, e)
    End Sub

End Class


Public Class jacRecorder
    Declare Function mciSendString Lib "winmm" Alias "mciSendStringA" (ByVal messaggio As String, ByVal retmessage As String, ByVal valore As Integer, ByVal handle As Integer) As Integer

    Public path As String
    Sub record(ByVal tempo As Integer)
        mciSendString("open new type waveaudio alias suono", 0, 0, 0)
        mciSendString("record suono", 0, 0, 0)
        Dim sw As New Stopwatch
        sw.Start()
        Thread.Sleep(tempo)
        sw.Stop()
        mciSendString("save suono " + path, 0, 0, 0)
        mciSendString("close suono", "", 0, 0)
    End Sub
    Sub play()
        mciSendString("open " + path + " alias suono", 0, 0, 0)
        mciSendString("play suono wait", 0, 0, 0)
        mciSendString("close suono", 0, 0, 0)

    End Sub
End Class

Bene. Ci sono due classi. Comincio a studiarmi la prima...
Public Class jacRecognizer
    Dim WithEvents motore As New SpeechRecognitionEngine(New Globalization.CultureInfo("it-IT"))
    Dim costruttore As GrammarBuilder
    Dim grammatica As Grammar

    Public Event riconoscimento(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs)
    Public Event noise(ByVal sender As Object, ByVal e As SpeechDetectedEventArgs)
    Public lista As New ArrayList
    Public matrice() As String

    Sub New()
        motore.SetInputToDefaultAudioDevice()
        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")
        Dim scelte As New Choices("u")
        costruttore.Append(scelte)
        grammatica = New Grammar(costruttore)
        motore.LoadGrammar(grammatica)
        motore.RecognizeAsync(RecognizeMode.Multiple)
    End Sub
    Sub New(ByVal nomeFile As String)
        motore.SetInputToDefaultAudioDevice()

        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")

        Dim str As String = ""


        FileOpen(1, nomeFile, OpenMode.Input)
        Do Until EOF(1)
            str = LineInput(1)
            lista.Add(str)
        Loop
        FileClose(1)

        ReDim matrice(lista.Count - 1)
        lista.CopyTo(matrice)

        Dim scelte As New Choices(matrice)
        costruttore.Append(scelte)
        grammatica = New Grammar(costruttore)
        motore.LoadGrammar(grammatica)
        motore.RecognizeAsync(RecognizeMode.Multiple)
    End Sub
    Public Sub recognizing(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs) Handles motore.SpeechRecognized
        RaiseEvent riconoscimento(sender, e)
    End Sub
    Public Sub rumore(ByVal sender As Object, ByVal e As SpeechDetectedEventArgs) Handles motore.SpeechDetected
        RaiseEvent noise(sender, e)
    End Sub
End Class
Dunque... innanzitutto vengono dichiarate delle variabili:
  • SpeechRecognitionEngine
  • GrammarBuilder
  • Grammar
E poi altre variabili di tipo Event eccetera... che vedrò dopo...

Intanto, nel costruttore di JacRecognizer si eseguono alcune istruzioni:
Viene chiamato il metodo
motore.SetInputToDefaultAudioDevice()
che probabilmente setta l'input per il riconoscitore al microfono del dispositivo.

Quindi viene fatto "qualcosa" a carico del GrammarBuilder (che io con una scelta infelice ho chiamato "costruttore" generando facile confusione con il costruttore della classe).
        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")
        Dim scelte As New Choices("u")
        costruttore.Append(scelte)
Per prima cosa viene istanziato l'oggetto della classe GrammarBuilder
costruttore = New GrammarBuilder


Viene attribuita la lingua a questo oggetto GrammarBuilder chiamato "costruttore":
costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")


Vengono create delle "scelte" (oggetti Choices) e "appese" al costruttore di tipo GrammarBuilder:
Dim scelte As New Choices("u")
        costruttore.Append(scelte)
Il significato di quella "u" mi sfugge completamente.

Ah, ecco! In pratica, costruiamo l'oggetto costruttore (GrammarBuilder) e gli attribuiamo due cose:
  • la proprietà Culture, ossia la lingua;
  • Le scelte, ossia le parole che comprenderà la "grammatica".
La grammatica verrà costruita semplicemente ponendo il costruttore come parametro nel suo costruttore (che brutta denominazione che ho scelto! Confusiva al massimo!)
        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")
        Dim scelte As New Choices("u")
        costruttore.Append(scelte)
e poi:
grammatica = New Grammar(costruttore)

...quindi il motore si "carica" la grammatica:
motore.LoadGrammar(grammatica)
Resta da studiare l'ultimo metodo del motore, RecognizeAsync...

Ecco: sarebbe mettere il motore in condizioni di eseguire il riconoscimento.
motore.RecognizeAsync(RecognizeMode.Multiple)
Il "Multiple" starebbe per "multiple operazioni di riconoscimento.


Nel mio jacRecognizer ho overloadato il costruttore, però, avendone anche un altro con un parametro:
    Sub New(ByVal nomeFile As String)
        motore.SetInputToDefaultAudioDevice()

        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")

        Dim str As String = ""


        FileOpen(1, nomeFile, OpenMode.Input)
        Do Until EOF(1)
            str = LineInput(1)
            lista.Add(str)
        Loop
        FileClose(1)

        ReDim matrice(lista.Count - 1)
        lista.CopyTo(matrice)

        Dim scelte As New Choices(matrice)
        costruttore.Append(scelte)
        grammatica = New Grammar(costruttore)
        motore.LoadGrammar(grammatica)
        motore.RecognizeAsync(RecognizeMode.Multiple)
    End Sub
Ecco: il parametro fornito a questo costruttore è una stringa contenente il nome di un file.
Questo file viene aperto e le righe vengono lette e caricate in una ArrayList (quella che viene dichiarata e istanziata inizialmente nella dichiarazione della classe); quindi dalla ArrayList vengono poste in una matrice.
    Sub New(ByVal nomeFile As String)
        motore.SetInputToDefaultAudioDevice()

        costruttore = New GrammarBuilder
        costruttore.Culture = Globalization.CultureInfo.GetCultureInfo("it-IT")

        Dim str As String = ""


        FileOpen(1, nomeFile, OpenMode.Input)
        Do Until EOF(1)
            str = LineInput(1)
            lista.Add(str)
        Loop
        FileClose(1)

        ReDim matrice(lista.Count - 1)
        lista.CopyTo(matrice)
(in celeste, le operazioni di lettura del file il cui indirizzo è stato passato come parametro, in rosso la copiatura dell'ArrayList nella matrice)

Quindi questa matrice viene usata per creare delle scelte (Choices) e "appesa" al costruttore, col quale verrà costruita la grammatica, che sarà quindi caricata dal motore, come prima, quindi il motore si mette in ascolto:
        Dim scelte As New Choices(matrice)
        costruttore.Append(scelte)
        grammatica = New Grammar(costruttore)
        motore.LoadGrammar(grammatica)
        motore.RecognizeAsync(RecognizeMode.Multiple)
    End Sub

Restano le subroutines di elevazione degli eventi:
    Public Sub recognizing(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs) Handles motore.SpeechRecognized
        RaiseEvent riconoscimento(sender, e)
    End Sub
    Public Sub rumore(ByVal sender As Object, ByVal e As SpeechDetectedEventArgs) Handles motore.SpeechDetected
        RaiseEvent noise(sender, e)
    End Sub
End Class
Questi eventi erano stati dichiarati inizialmente:
    Public Event riconoscimento(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs)
    Public Event noise(ByVal sender As Object, ByVal e As SpeechDetectedEventArgs)
E' importante, nelle subroutines che evocano gli eventi, la parte Handles:
       Public Sub recognizing(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs) Handles motore.SpeechRecognized
        RaiseEvent riconoscimento(sender, e)
    End Sub
    Public Sub rumore(ByVal sender As Object, ByVal e As SpeechDetectedEventArgs) Handles motore.SpeechDetected
        RaiseEvent noise(sender, e)
    End Sub

Bene.
Adesso apro il programma che usa questo oggetto jacRecognizer...

E ho trovato la via spianata per la costruzione di tutto quello che voglio! Verso l'infinito e oltre!!!

martedì 29 marzo 2016

Promemoria: codice per il "pinch zoom" di un layout.

Ho sistemato il problema ponendo un minimo e un massimo:
public class MainActivity extends Activity {
 
  RelativeLayout mainLayout;
  LinearLayout ll;
  ScaleGestureDetector detector;
  float scala=1.f;
  int bmpWidth, bmpHeight;
  TextView textView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mainLayout=(RelativeLayout) findViewById(R.id.mainLayout);
        ll=new LinearLayout(this);
        RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
        params.width=300;
        params.height=200;
        ll.setLayoutParams(params);
        ll.setBackgroundColor(Color.GREEN);
        mainLayout.addView(ll);
        
        detector=new ScaleGestureDetector(this,new listener());
        bmpWidth=300;
        bmpHeight=200;
        textView=(TextView)findViewById(R.id.textView1);
        
        drawMatrix();
        
    }
    
    public void drawMatrix(){
     bmpWidth=(int) (Math.round(bmpWidth*scala));
     bmpHeight=(int) (Math.round(bmpHeight*scala));
     LayoutParams p=(LayoutParams)ll.getLayoutParams();
     p.width=bmpWidth;
     if(bmpWidth>=400){
      bmpWidth=400;
      bmpHeight=(int)(400/1.5);
     }
     if(bmpWidth<=220){
      bmpWidth=220;
      bmpHeight=(int)(220/1.5);
     }
     p.height=bmpHeight;
     ll.setLayoutParams(p);
    
     
     textView.setText(bmpWidth+" "+bmpHeight);
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event){
     detector.onTouchEvent(event);
  return true;
     
    }
    
    class listener extends ScaleGestureDetector.SimpleOnScaleGestureListener{
     
     @Override
     public boolean onScale(ScaleGestureDetector detector){
      scala=detector.getScaleFactor();
      drawMatrix();
   return true;
      
     }
    }
    
}

Annotazione di codice per il pinch zoom

Ecco un codice che sembra funzionare, per il pinch zoom di una bitmap:
public class MainActivity extends Activity {
 
  RelativeLayout mainLayout;
  ImageView immagine;
  Bitmap bitmap;
  ScaleGestureDetector detector;
  float scala=1.f;
  int bmpWidth, bmpHeight;
  TextView textView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mainLayout=(RelativeLayout) findViewById(R.id.mainLayout);
        
        
        detector=new ScaleGestureDetector(this,new listener());
        immagine=(ImageView)findViewById(R.id.imageView1);
        textView=(TextView)findViewById(R.id.textView1);
        
        
        
        bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.calcestruzzo);
        bmpWidth=bitmap.getWidth();
        bmpHeight=bitmap.getHeight();
        drawMatrix();
        
    }
    
    public void drawMatrix(){
     bmpWidth=(int) (bmpWidth*scala);
     bmpHeight=(int) (bmpWidth*scala);
     Bitmap resizedBitmap=Bitmap.createScaledBitmap(bitmap, bmpWidth, bmpHeight, false);
     immagine.setImageBitmap(resizedBitmap);
     textView.setText(bmpWidth+" - "+bmpHeight);
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event){
     detector.onTouchEvent(event);
  return true;
     
    }
    
    class listener extends ScaleGestureDetector.SimpleOnScaleGestureListener{
     
     @Override
     public boolean onScale(ScaleGestureDetector detector){
      scala=detector.getScaleFactor();
      
      drawMatrix();
   return true;
      
     }
    }
    
}

Me lo annoto prima di giocherellarci sopra...

sabato 26 marzo 2016

Zoomare l'immagine con due dita (ScaleGestureDetector e SimpleOnScaleGestureListener)

Ridimensionare un'immagine con due dita.

Ci sto combattendo un po'...

Credo di essere arrivato a qualche conclusione.
Esiste una classe che si chiama ScaleGestureDetector.
Questa classe viene creata con un costruttore che assume come parametri context e un listener, per cui va creato anche il listener.

Dopo aver scritto un codice funzionante modificando pedissequamente il codice trovato in rete, come al solito rompo il Mandala e lo ricostruisco daccapo a titolo di esercitazione...

public class MainActivity extends Activity {
 
 //dichiarazioni
 ScaleGestureDetector scaleGestureDetector;
 
 RelativeLayout mainLayout;
 ImageView imageView;
 Bitmap bitmap;
 int bitmapHeight,bitmapWidth;
 float scala=1.f;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  scaleGestureDetector=new ScaleGestureDetector(this,new simpleOnScaleGestureListener());
  mainLayout=(RelativeLayout)findViewById(R.id.mainLayout);
  imageView=new ImageView(this);
  mainLayout.addView(imageView);
  
  bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.calcestruzzo);
  bitmapHeight=bitmap.getHeight();
  bitmapWidth=bitmap.getWidth();  
  drawMatrix();
   
 }
 private void drawMatrix(){
  bitmapWidth*=scala;
  bitmapHeight*=scala;
  Bitmap resizedBitmap=Bitmap.createScaledBitmap(bitmap, bitmapWidth, bitmapHeight, false);
  imageView.setImageBitmap(resizedBitmap);
 }
 
 @Override
 public boolean onTouchEvent(MotionEvent event){
  scaleGestureDetector.onTouchEvent(event);
  return true;
  
 }
 private class simpleOnScaleGestureListener extends SimpleOnScaleGestureListener{
  
  @Override
  public boolean onScale(ScaleGestureDetector detector){
   scala=detector.getScaleFactor();
   drawMatrix();
   return true;
   
  }
 } 

}
Ecco: solo che aumentando e diminuendo le dimensioni un po' di volte mi allunga l'immagine...
Ma per il momento c'è da essere soddisfatti!

lunedì 21 marzo 2016

FileInputStream

Ho messo un file wav nella memoria dell'emulatore: si tratta di un file che ho preso da qualche parte, contenente una canzoncina comica, tanto per mantenere l'allegria, e voglio leggere il file in un buffer.
Ecco il codice:
public class MainActivity extends Activity {

// dichiarazioni di variabili oggetto dell'activity
 Button button;
 Button button2;
 Button button3;
 Button button4;

//il percorso del file
 String filePath = Environment.getExternalStorageDirectory()
   .getAbsolutePath() + "/vaffanculo.wav";

// registratore e riproduttore (dichiarazioni)
 AudioRecord audioRecord;
 AudioTrack audioTrack;

//impostazioni audio
 int audioSource=AudioSource.MIC;
 int sampleRate=44100;
 int channelConfig=AudioFormat.CHANNEL_IN_STEREO;
 int audioFormat=AudioFormat.ENCODING_PCM_16BIT;
 int minBufferSize=AudioRecord.getMinBufferSize(sampleRate, 
             channelConfig, 
             audioFormat);
 
// dichiarazione del buffer
 byte[] buffer= new byte[minBufferSize];
 
 
 
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  
//istanziazione dei bottoni
  button = (Button) findViewById(R.id.button1);
  button2 = (Button) findViewById(R.id.button2);
  button3 = (Button) findViewById(R.id.button3);
  button4 = (Button) findViewById(R.id.button4);

//listeners
  button.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    try {
     
     FileInputStream fis=new FileInputStream(filePath);
     fis.read(buffer,0,minBufferSize);
     for(int i=0; i < minBufferSize;i++){
      Log.v(i+"",buffer[i]+"");
     }
    } catch (FileNotFoundException e) {
     e.printStackTrace();
    } catch (IOException e) {
     e.printStackTrace();
    }
    
    
   }
  });
    

  button2.setOnClickListener(new View.OnClickListener() {

   @Override
   public void onClick(View v) {
    
   }
  });
  button3.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    
   }
  });
  
  button4.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    
   }
  });
  
// termine listeners
 }

}
La parte notevole è questa:
  button.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    try {
     
     FileInputStream fis=new FileInputStream(filePath);
     fis.read(buffer,0,minBufferSize);
     for(int i=0; i < minBufferSize;i++){
      Log.v(i+"",buffer[i]+"");
     }
    } catch (FileNotFoundException e) {
     e.printStackTrace();
    } catch (IOException e) {
     e.printStackTrace();
    }
    
    
   }
  });
Creo un FileInputStream con l'indirizzo del file, e quindi con la riga scritta in verde "leggo" i bytes del file nel buffer.
Quindi schiaccio il bottone, produco il LogCat e mi leggo pezzo per pezzo ogni byte, di cui riporto i primi 100:
03-21 08:22:49.520: V/0(19511): 74
03-21 08:22:49.520: V/1(19511): 1
03-21 08:22:49.520: V/2(19511): 74
03-21 08:22:49.520: V/3(19511): 1
03-21 08:22:49.520: V/4(19511): 50
03-21 08:22:49.520: V/5(19511): 1
03-21 08:22:49.520: V/6(19511): 50
03-21 08:22:49.520: V/7(19511): 1
03-21 08:22:49.520: V/8(19511): 22
03-21 08:22:49.520: V/9(19511): 1
03-21 08:22:49.520: V/10(19511): 22
03-21 08:22:49.520: V/11(19511): 1
03-21 08:22:49.520: V/12(19511): -9
03-21 08:22:49.520: V/13(19511): 0
03-21 08:22:49.520: V/14(19511): -9
03-21 08:22:49.520: V/15(19511): 0
03-21 08:22:49.520: V/16(19511): -42
03-21 08:22:49.520: V/17(19511): 0
03-21 08:22:49.520: V/18(19511): -42
03-21 08:22:49.520: V/19(19511): 0
03-21 08:22:49.520: V/20(19511): -77
03-21 08:22:49.520: V/21(19511): 0
03-21 08:22:49.520: V/22(19511): -77
03-21 08:22:49.520: V/23(19511): 0
03-21 08:22:49.520: V/24(19511): -112
03-21 08:22:49.520: V/25(19511): 0
03-21 08:22:49.520: V/26(19511): -112
03-21 08:22:49.520: V/27(19511): 0
03-21 08:22:49.520: V/28(19511): 110
03-21 08:22:49.520: V/29(19511): 0
03-21 08:22:49.520: V/30(19511): 110
03-21 08:22:49.520: V/31(19511): 0
03-21 08:22:49.520: V/32(19511): 79
03-21 08:22:49.520: V/33(19511): 0
03-21 08:22:49.520: V/34(19511): 79
03-21 08:22:49.520: V/35(19511): 0
03-21 08:22:49.520: V/36(19511): 51
03-21 08:22:49.520: V/37(19511): 0
03-21 08:22:49.520: V/38(19511): 51
03-21 08:22:49.520: V/39(19511): 0
03-21 08:22:49.520: V/40(19511): 27
03-21 08:22:49.520: V/41(19511): 0
03-21 08:22:49.520: V/42(19511): 27
03-21 08:22:49.520: V/43(19511): 0
03-21 08:22:49.520: V/44(19511): 8
03-21 08:22:49.520: V/45(19511): 0
03-21 08:22:49.520: V/46(19511): 8
03-21 08:22:49.520: V/47(19511): 0
03-21 08:22:49.520: V/48(19511): -8
03-21 08:22:49.520: V/49(19511): -1
03-21 08:22:49.520: V/50(19511): -8
03-21 08:22:49.520: V/51(19511): -1
03-21 08:22:49.520: V/52(19511): -22
03-21 08:22:49.520: V/53(19511): -1
03-21 08:22:49.520: V/54(19511): -22
03-21 08:22:49.520: V/55(19511): -1
03-21 08:22:49.520: V/56(19511): -35
03-21 08:22:49.520: V/57(19511): -1
03-21 08:22:49.520: V/58(19511): -35
03-21 08:22:49.520: V/59(19511): -1
03-21 08:22:49.520: V/60(19511): -48
03-21 08:22:49.520: V/61(19511): -1
03-21 08:22:49.520: V/62(19511): -48
03-21 08:22:49.520: V/63(19511): -1
03-21 08:22:49.520: V/64(19511): -62
03-21 08:22:49.520: V/65(19511): -1
03-21 08:22:49.520: V/66(19511): -62
03-21 08:22:49.520: V/67(19511): -1
03-21 08:22:49.520: V/68(19511): -78
03-21 08:22:49.520: V/69(19511): -1
03-21 08:22:49.520: V/70(19511): -78
03-21 08:22:49.520: V/71(19511): -1
03-21 08:22:49.520: V/72(19511): -96
03-21 08:22:49.520: V/73(19511): -1
03-21 08:22:49.520: V/74(19511): -96
03-21 08:22:49.520: V/75(19511): -1
03-21 08:22:49.520: V/76(19511): -114
03-21 08:22:49.520: V/77(19511): -1
03-21 08:22:49.520: V/78(19511): -114
03-21 08:22:49.520: V/79(19511): -1
03-21 08:22:49.520: V/80(19511): 125
03-21 08:22:49.520: V/81(19511): -1
03-21 08:22:49.520: V/82(19511): 125
03-21 08:22:49.520: V/83(19511): -1
03-21 08:22:49.520: V/84(19511): 109
03-21 08:22:49.520: V/85(19511): -1
03-21 08:22:49.520: V/86(19511): 109
03-21 08:22:49.520: V/87(19511): -1
03-21 08:22:49.520: V/88(19511): 96
03-21 08:22:49.520: V/89(19511): -1
03-21 08:22:49.520: V/90(19511): 96
03-21 08:22:49.520: V/91(19511): -1
03-21 08:22:49.520: V/92(19511): 87
03-21 08:22:49.520: V/93(19511): -1
03-21 08:22:49.520: V/94(19511): 87
03-21 08:22:49.520: V/95(19511): -1
03-21 08:22:49.520: V/96(19511): 82
03-21 08:22:49.520: V/97(19511): -1
03-21 08:22:49.520: V/98(19511): 82
03-21 08:22:49.520: V/99(19511): -1
03-21 08:22:49.520: V/100(19511): 81
Sono 278 bytes in totale. Ma il buffer di che dimensione è?
Modifico il codice per ottenere minBufferSize in LogCat:

     FileInputStream fis=new FileInputStream(filePath);
     fis.read(buffer,0,minBufferSize);
     for(int i=0; i < minBufferSize;i++){
      Log.v("BUFFERSIZE",i+"",buffer[i]+"");
     }
.....   
Ottengo 640, che è pure il valore che ottengo come risultato della funzione fis.read(buffer,0,minBufferSize).

Ma adesso voglio trovare modi diversi di inserire i valori nel buffer.
     FileInputStream fis=new FileInputStream(filePath);
     for(int i=0; i < minBufferSize;i++){
      buffer[i]=(byte)fis.read();
     }
     for(int i=0; i < minBufferSize;i++){
      Log.v(i+"",buffer[i]+"");
     }
ed ecco il risultato:
03-21 08:59:47.970: V/0(26357): 74
03-21 08:59:47.970: V/1(26357): 1
03-21 08:59:47.970: V/2(26357): 74
03-21 08:59:47.970: V/3(26357): 1
03-21 08:59:47.970: V/4(26357): 50
03-21 08:59:47.970: V/5(26357): 1
03-21 08:59:47.970: V/6(26357): 50
03-21 08:59:47.970: V/7(26357): 1
03-21 08:59:47.970: V/8(26357): 22
03-21 08:59:47.970: V/9(26357): 1
03-21 08:59:47.970: V/10(26357): 22
03-21 08:59:47.970: V/11(26357): 1
03-21 08:59:47.970: V/12(26357): -9
03-21 08:59:47.970: V/13(26357): 0
03-21 08:59:47.970: V/14(26357): -9
03-21 08:59:47.970: V/15(26357): 0
03-21 08:59:47.970: V/16(26357): -42
03-21 08:59:47.970: V/17(26357): 0
03-21 08:59:47.970: V/18(26357): -42
03-21 08:59:47.970: V/19(26357): 0
03-21 08:59:47.970: V/20(26357): -77
03-21 08:59:47.970: V/21(26357): 0
03-21 08:59:47.970: V/22(26357): -77
03-21 08:59:47.970: V/23(26357): 0
03-21 08:59:47.970: V/24(26357): -112
03-21 08:59:47.970: V/25(26357): 0
03-21 08:59:47.970: V/26(26357): -112
03-21 08:59:47.970: V/27(26357): 0
03-21 08:59:47.970: V/28(26357): 110
03-21 08:59:47.970: V/29(26357): 0
03-21 08:59:47.970: V/30(26357): 110
03-21 08:59:47.970: V/31(26357): 0
03-21 08:59:47.970: V/32(26357): 79
03-21 08:59:47.970: V/33(26357): 0
03-21 08:59:47.970: V/34(26357): 79
03-21 08:59:47.970: V/35(26357): 0
03-21 08:59:47.970: V/36(26357): 51
03-21 08:59:47.970: V/37(26357): 0
03-21 08:59:47.970: V/38(26357): 51
03-21 08:59:47.970: V/39(26357): 0
03-21 08:59:47.970: V/40(26357): 27
03-21 08:59:47.970: V/41(26357): 0
03-21 08:59:47.970: V/42(26357): 27
03-21 08:59:47.970: V/43(26357): 0
03-21 08:59:47.970: V/44(26357): 8
03-21 08:59:47.970: V/45(26357): 0
03-21 08:59:47.970: V/46(26357): 8
03-21 08:59:47.970: V/47(26357): 0
03-21 08:59:47.970: V/48(26357): -8
03-21 08:59:47.970: V/49(26357): -1
03-21 08:59:47.970: V/50(26357): -8
03-21 08:59:47.970: V/51(26357): -1
03-21 08:59:47.970: V/52(26357): -22
03-21 08:59:47.970: V/53(26357): -1
03-21 08:59:47.970: V/54(26357): -22
03-21 08:59:47.970: V/55(26357): -1
03-21 08:59:47.970: V/56(26357): -35
03-21 08:59:47.970: V/57(26357): -1
03-21 08:59:47.970: V/58(26357): -35
03-21 08:59:47.970: V/59(26357): -1
03-21 08:59:47.970: V/60(26357): -48
03-21 08:59:47.970: V/61(26357): -1
03-21 08:59:47.970: V/62(26357): -48
03-21 08:59:47.970: V/63(26357): -1
03-21 08:59:47.970: V/64(26357): -62
03-21 08:59:47.970: V/65(26357): -1
03-21 08:59:47.970: V/66(26357): -62
03-21 08:59:47.970: V/67(26357): -1
03-21 08:59:47.970: V/68(26357): -78
03-21 08:59:47.970: V/69(26357): -1
03-21 08:59:47.970: V/70(26357): -78
03-21 08:59:47.970: V/71(26357): -1
03-21 08:59:47.970: V/72(26357): -96
03-21 08:59:47.970: V/73(26357): -1
03-21 08:59:47.970: V/74(26357): -96
03-21 08:59:47.970: V/75(26357): -1
03-21 08:59:47.970: V/76(26357): -114
03-21 08:59:47.970: V/77(26357): -1
03-21 08:59:47.970: V/78(26357): -114
03-21 08:59:47.970: V/79(26357): -1
03-21 08:59:47.970: V/80(26357): 125
03-21 08:59:47.970: V/81(26357): -1
03-21 08:59:47.970: V/82(26357): 125
03-21 08:59:47.970: V/83(26357): -1
03-21 08:59:47.970: V/84(26357): 109
03-21 08:59:47.970: V/85(26357): -1
03-21 08:59:47.970: V/86(26357): 109
03-21 08:59:47.970: V/87(26357): -1
03-21 08:59:47.970: V/88(26357): 96
03-21 08:59:47.970: V/89(26357): -1
03-21 08:59:47.970: V/90(26357): 96
03-21 08:59:47.970: V/91(26357): -1
03-21 08:59:47.970: V/92(26357): 87
03-21 08:59:47.970: V/93(26357): -1
03-21 08:59:47.970: V/94(26357): 87
03-21 08:59:47.970: V/95(26357): -1
03-21 08:59:47.970: V/96(26357): 82
03-21 08:59:47.970: V/97(26357): -1
03-21 08:59:47.970: V/98(26357): 82
03-21 08:59:47.970: V/99(26357): -1
03-21 08:59:47.970: V/100(26357): 81
Questi valori sono esattamente uguali a quelli ricavati prima.

domenica 20 marzo 2016

Leggere i bytes da un file

Ed ecco ora il FileInputStream per leggere i bytes di un file in un buffer:
public class MainActivity extends Activity {

 Button button;
 Button button2;
 Button button3;
 Button button4;

 String filePath = Environment.getExternalStorageDirectory()
   .getAbsolutePath() + "/ilmiofiledalnomelungolungo";

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

  button = (Button) findViewById(R.id.button1);
  button2 = (Button) findViewById(R.id.button2);
  button3 = (Button) findViewById(R.id.button3);
  button4 = (Button) findViewById(R.id.button4);

  button.setOnClickListener(new View.OnClickListener() {

   @Override
   public void onClick(View v) {

    try {
     FileOutputStream fos = new FileOutputStream(filePath);
     byte[] nome = { 0x41, 0x4e, 0x54, 0x4f, 0x4e, 0x45, 0x4c,
       0x4c, 0x4f };
     fos.write(nome);
    } catch (Exception e) {
     e.printStackTrace();
    }

   }
  });
  button2.setOnClickListener(new View.OnClickListener() {

   @Override
   public void onClick(View v) {
    try {
     FileInputStream fis=new FileInputStream(filePath);
     byte[] buffer=new byte[50];
     fis.read(buffer);
     for(int i=0;i<50;i++){
      Log.d(i+"",buffer[i]+"");
     }
    } catch (Exception e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }

   }
  });
 }

}
Ecco il risultato in LogCat:
03-19 17:03:03.740: D/0(15493): 65
03-19 17:03:03.740: D/1(15493): 78
03-19 17:03:03.740: D/2(15493): 84
03-19 17:03:03.740: D/3(15493): 79
03-19 17:03:03.740: D/4(15493): 78
03-19 17:03:03.740: D/5(15493): 69
03-19 17:03:03.740: D/6(15493): 76
03-19 17:03:03.740: D/7(15493): 76
03-19 17:03:03.740: D/8(15493): 79
03-19 17:03:03.740: D/9(15493): 0
03-19 17:03:03.740: D/10(15493): 0
03-19 17:03:03.740: D/11(15493): 0
...che sono i codici ASCII di "ANTONELLO" in notazione decimale.
65/16= 4 con resto di 1: 0x41
78/16= 4 con resto di 14 (E): 0x4e
84/16= 5 con resto di 4; 0x54
79/16= 4 con resto di 15 (F): 0x4f
...eccetera...

E' valso la pena, imparare la tabellina del 16, per fare i calcoli un po' più agevolmente! :D

Scrivere un byte e un array di bytes sul file creato nella memoria del cellulare

Inizio a scrivere sui files creati.
Ora metto l'iniziale del mio nome sul file:
   button.setOnClickListener(new View.OnClickListener() {
  
  @Override
  public void onClick(View v) {
   
   try {
    FileOutputStream fos=new FileOutputStream(filePath);
    fos.write(65);
   } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   
  }
 });
Aprendo in Hex Editor, leggo 41 che viene tradotto in A come da tabella ASCII.
Perfetto!
Ora voglio scrivere un array di bytes... Scrivo il mio nome usando direttamente i numeri in formato esadecimale perché ricordo meglio i codici ASCII.
   button.setOnClickListener(new View.OnClickListener() {
  
  @Override
  public void onClick(View v) {
   
   try {
    FileOutputStream fos=new FileOutputStream(filePath);
    byte[] nome= {0x41,0x4e,0x54,0x4f,0x4e,0x45,0x4c,0x4c,0x4f};
    fos.write(nome);
   } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   
  }
 });
Riuscito perfettamente: aggiungo l'estensione .txt al nome del file e lo apro con Blocco Note:
ANTONELLO