音乐文件应该下载到应用程序本身,它不应该存储在移动内存(文件管理器或SD卡)。
FileManager class用于在应用程序文件夹中存储mp3文件。
public class FileManager {
private final Context context;
FileManager(Context context) {
this.context = context;
}
public String getRootPath() {
File file = new File(context.getFilesDir(),"");
return file.getAbsolutePath();
}
public String getFilePath(String name) {
File file = new File(context.getFilesDir(), name);
return file.getAbsolutePath();
}
}
下载请求@RequiresApi(api = Build.VERSION_CODES.O)
private void initDownload(String soundUri) {
Log.d(TAG, "initDownload: " + soundUri);
Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).build();
ApiService retrofitInterface = retrofit.create(ApiService.class);
Call<ResponseBody> request = retrofitInterface.downloadFile(soundUri);
request.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.body() != null) {
Thread thread = new Thread(() -> {
try {
saveVoice(response.body());
} catch (IOException e) {
Log.d(TAG, "onResponse: " + e);
}
});
thread.start();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void saveVoice(ResponseBody body) throws IOException {
try {
String mp3Key= "YOUR_KEY_TO_STORE_FILE";
int count;
byte data[] = new byte[1024 * 4];
InputStream bis = new BufferedInputStream(body.byteStream(), 1024 * 8);
File outputFile = new File(fileManager.getRootPath(), voiceKey);
OutputStream output = new FileOutputStream(outputFile);
long startTime = System.currentTimeMillis();
int timeCount = 1;
while ((count = bis.read(data)) != -1) {
long currentTime = System.currentTimeMillis() - startTime;
if (currentTime > 1000 * timeCount) {
timeCount++;
}
output.write(data, 0, count);
}
output.flush();
output.close();
bis.close();
} catch (Exception e) {
Log.d(TAG, "saveVoice: " + e);
}
}
下载成功后,你可以用你写文件到应用程序存储的密钥读取文件。
String filePath = fileManager.getFilePath(mp3Key); // filePath returns local url of file
例如:
mediaPlayer.setDataSource(filePath );