2017-08-28 22 views
3

我有一个以BLOB格式保存音频数据的表格。我想播放音频文件,但在从数据库调用方法时遇到问题。播放列表<byte[]>来自SQLite数据库的音频文件

这是我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; 
} 

这是我的活动课,我想打电话给我getAudio()方法。它说它找不到符号变量文件(来自Uri.fromFile(文件))。

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; 
} 

任何人都知道如何调用getAudio()方法?谢谢。

+1

**可怕的**练习,用BLOBs膨胀一个数据库! –

+1

为什么?为什么'File.createTempFile'并将它写入BLOB内容,同时可以将它保存在某个文件中,并将路径保存在数据库中?同意ModularSynth 100%... – pskink

+0

@ModularSynth对不起。即时通讯新的android。任何建议我应该怎么做? – chernting

回答

0

您没有添加任何内容到list,您只能将字节写入文件,另一方面是file在另一种方法中,您将无法从您的活动中看到该引用。

而不是写入文件(在getAutdio中)将字节添加到列表并返回它。

现在从列表中您可以播放音频或写入文件然后播放音频。

你的代码可能是这样的:

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; 
} 

以及播放,你可以写在一个文件中byte[]创建MediaPlayer 参考,以this answer它只是一个概念,你可能需要改变它一点点位,或者使用最新的代码使用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(); 
    } 
} 

NOW:因为你主要是利用文件(播放的媒体)的d,通过上述评论的建议,你可以而不是存储的音频文件的字节存储文件名和路径(如字符串) 你就可以立刻从DB retrive文件名和启动媒体播放器

编辑:播放文件一个接一个,你可能想使List<byte[]> audio类范围,并调用playMp3(audio.get(index));其中index是您提高每一次你玩一个文件时,一个整数(但要小心,不要检查

类范围:

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

然后onClick的播放按钮:

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

我现在可以播放音频,但它会创建多种声音,如果要一个接一个地播放音频,我该怎么做?我是否需要使用其他方法而不是循环? – chernting

+0

@chernting是的,检查我的答案(编辑) – Yazan