2017-08-28 1 views
3

Ich habe eine Tabelle mit Audiodaten im BLOB-Format gespeichert. Ich möchte die Audiodateien abspielen, habe aber Probleme beim Aufrufen der Methode aus der Datenbank.Wiedergabeliste <byte[]> Audiodateien von SQLite-Datenbank

Das ist mein DatabaseAccess.java

public List<byte[]> getAudio(long i) { 
    List<byte[]> list = new ArrayList<>(); 
    File file; 
    FileOutputStream fos; 

    byte[] byteaudio = null; 
    String selectAudio = "SELECT VocabAudio FROM Vocab WHERE VocabTopic =" + i; 
    Cursor c = database.rawQuery(selectAudio, null); 
    if(c.moveToFirst()) 
     do{ 
      byteaudio = c.getBlob(c.getColumnIndex("VocabAudio")); 

      try{ 
       file = File.createTempFile("audio", "audio"); 
       fos = new FileOutputStream(file); 
       fos.write(byteaudio); 
       fos.close(); 

      }catch (IOException e){ 
       e.printStackTrace(); 
      } 

     }while(c.moveToNext()); 

    return list; 
} 

Dies ist meine Aktivitätsklasse, wo ich meine getAudio() -Methode aufrufen möchten. Es besagt, dass es keine Symbolvariablendatei finden kann (aus der Uri.fromFile (Datei)).

public void startSlides() { 

    timer = new Timer(); 
    timer.scheduleAtFixedRate(new TimerTask() { 

     public void run() { 
      runOnUiThread(new Runnable() { 
       public void run() { 

        Intent intent = getIntent(); 
        long topicId = intent.getLongExtra("SelectedTopicId", 0); 

        databaseAccess.open(); 

        List<byte[]> audio = databaseAccess.getAudio(topicId); 

        mp= MediaPlayer.create(Choice.this,Uri.fromFile(file)); 
        i++; 
        mp.start(); 


        databaseAccess.close(); 

        if (j == vocab.size()+1) { 
         timer.cancel(); 
        } 
       } 
      }); 
     } 

    }, 0, 1000; 
} 

Wer weiß, wie sollte ich die Methode getAudio() aufrufen? Vielen Dank.

+1

** ** Horrible Praxis eine db mit BLOBs aufblasen !! –

+1

Warum? Warum 'File.createTempFile' und schreibe es mit deinem BLOB-Inhalt, während du es in irgendeiner Datei behalten und den Pfad in deiner db behalten kannst? stimme ModularSynth zu 100% zu ... – pskink

+0

@ModularSynth Es tut mir leid. Ich bin neu in Android. Irgendein Vorschlag wie soll ich es tun? – chernting

Antwort

0

Sie fügen nichts zu list hinzu, Sie schreiben nur Bytes in eine Datei, die andere Sache ist file ist in einer anderen Methode, Sie werden nicht in der Lage sein, diese Referenz von Ihrer Aktivität zu sehen.

stattdessen die Datei zu schreiben (in getAutdio) das Bytes in die Liste aufnehmen und es zurück.

nun aus der Liste können Sie das Audio abspielen oder die Dateien schreiben und dann den Ton wiederzugeben.

Ihr Code kann wie folgt aussehen:

public List<byte[]> getAudio(long i) { 
    List<byte[]> list = new ArrayList<>(); 

    byte[] byteaudio = null; 
    String selectAudio = "SELECT VocabAudio FROM Vocab WHERE VocabTopic =" + i; 
    Cursor c = database.rawQuery(selectAudio, null); 
    if(c.moveToFirst()) 
    do{ 
     byteaudio = c.getBlob(c.getColumnIndex("VocabAudio")); 
     list.add(byteaudio); 
    }while(c.moveToNext()); 

    return list; 
} 

Und zum Spielen, können Sie die byte[] in einer Datei erstellen, die MediaPlayer refere zu this answer schreiben es nur ein Konzept, können Sie es ein wenig ändern müssen Bit oder neuesten Code verwenden MediaPlayer

public void run() { 

    Intent intent = getIntent(); 
    long topicId = intent.getLongExtra("SelectedTopicId", 0); 

    databaseAccess.open(); 
    List<byte[]> audio = databaseAccess.getAudio(topicId); 
    databaseAccess.close(); 

    for(byte[] track : audio){ 
     playMp3(track); 
    }//for loop 

    if (j == vocab.size()+1) { 
     timer.cancel(); 
    } 
} 

JETZT zu verwenden: da Sie hauptsächlich Dateien verwenden ein (die Medien zu spielen) d wie oben durch Kommentare vorgeschlagen, können Sie anstelle von Bytes der Audiodatei, speichern Sie die Dateinamen und den Pfad (als String) Speicher können Sie dann sofort die Dateinamen aus DB retrive und dem Media-Player

EDIT starten: Dateien spielen eins nach dem anderen, Sie können List<byte[]> audio Klassenbereich, machen wollen und playMp3(audio.get(index)); nennen, wo index eine ganze Zahl, die Sie jedes Mal, wenn Sie eine Datei wiedergeben erhöhen (aber darauf achten, nicht

Klasse Scope zu überprüfen:

private List<byte[]> audio; 
private int index =0; 

Dann onClick der Play-Taste:

@Override 
public void onClick(View view){ 
    if(index >= audio.size()){ 
     index = 0; // back to first track ? 
    } 
    playMp3(audio.get(index)); 
    ++index; 
} 
+0

Ich kann jetzt das Audio abspielen, aber es erzeugt mehrere Sounds, wie kann ich es tun, wenn ich das Audio eins nach dem anderen abspielen möchte? Muss ich eine andere Methode anstelle einer for-Schleife verwenden? – chernting

+0

@chernting ja, überprüfe meine Antwort (EDIT) – Yazan