I am dynamically generating midi files (in cache dir) with an android app.
After generation, I play the file with MediaPlayer within the same app.
When running the app for the first time, it already needs the file to be there in the cache directory (the app crashes). It works on the emulator if I use the filemanager to put a dummy file there first. How can I circumvent this?
I need the app to run on a tablet for the first time, without requiring the file.
I am using these commands now:
try {
filePath = getCacheDir() + "/optimuse" + song + ".mid";
file = new File(filePath);
inputStream = new FileInputStream(file);
if (inputStream.getFD().valid()) {
System.out.println("Valid!");
}
} catch (Exception e1) {
e1.printStackTrace();
System.exit(-1);
}
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(inputStream.getFD());
inputStream.close();
} catch (Exception e1) {
e1.printStackTrace();
System.exit(-1);
}
try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Is there any way around this?
Thanks!
Maybe check whether the file exists before using it? You can achieve this using the File#exists() method.
First, you use the Context#getFileStreamPath(String) method - where the String is the filename of the file you are trying to access. Then you can call File#exists() on the returned object.
Related
I'm trying to build a sync system for my writing application, so that I can synchronize my text files with a Dropbox folder and edit them from my computer.
Thing is, when a file is uploaded, its modification date corresponds to that of the upload time, not the last time the file's content was modified, and it looks as if the Dropbox file was modified more recently than the local file. Same thing for download, as the local version gets a more recent modification date than the Dropbox one.
This makes things complicated when I want to compare dates to determine which version is the most recent one between the local and the network versions, and if I need to upload the local version or download the network one to be up-to-date.
Is there a way to keep the modification date of the original file ? Currently, I'm using these functions, but maybe I should use a completely different method.
public void uploadFile(String local_path, String db_path) {
try {
InputStream in = new FileInputStream(local_path);
client.files().uploadBuilder(db_path)
.withMode(WriteMode.OVERWRITE)
.uploadAndFinish(in);
}
catch (FileNotFoundException fne) { fne.printStackTrace(); }
catch (IOException ioe) { ioe.printStackTrace(); }
catch (DbxException dbxe) { dbxe.printStackTrace(); }
}
public void downloadFile(String db_path, String local_path) {
try {
File dest = new File(local_path);
try (OutputStream outputStream = new FileOutputStream(dest)) {
client.files().download(db_path).download(outputStream);
}
}
catch (DbxException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
}
You can set the clientModified date using UploadBuilder.withClientModified. It's not possible to override the serverModified date though.
I have some mp3 file in my web server.
I have to use in my app.
My mp3 on server might increase or decrease.(teacher would upload new file or delete old file
My mp3 name is T1.mp3, T2.mp3, T3.mp3, etc.
I have a next button,I hope when mp3 file not found,it would show it is last one.
EX: I am in T40.mp3 I click next to go to T41.mp3, but T41 was delete by teacher,
So, I would show this file not found.
I try it but it can not show and will be shutdown...
how can I do?
this is my code:
private ImageView.OnClickListener nextbtn=new ImageView.OnClickListener(){
#Override
public void onClick(View v) {
String tmp=url; //url=www.XXX......
T++;
tmp+="/"+filename[T]; //filename is number ex:T21.mp3
try {
totalTime=0;
mediaplayer.reset();
mediaplayer.setDataSource(tmp);
mediaplayer.prepare();
totalTime=mediaplayer.getDuration();
if(mediaplayer.getDuration()==0){
//show that mp3 is not found
mytoast("not found");
}
else{
totalTime=mediaplayer.getDuration();
}
mediaplayer.start();
} catch (IllegalStateException e) { }
catch (IOException e) { }
}
};
thanks
You can replace the 2 empty catch blocks with
catch (Throwable e) {
mytoast("not found"); // or something else happened
}
Also, check out this question, it by itself provides a method to check if a file is playable.
Today i tested "files" instead of a normal path.
Here is my code:
File path=new File(getFilesDir(),"uf");
File test = new File(path.getAbsolutePath(),"test.txt");
if(!path.exists()){
path.mkdir();
}
if(!test.isFile()){
try {
test.createNewFile();
} catch (IOException e) {
//TODO in errorlog -> filecreation
e.printStackTrace();
}
}else{
try {
OutputStreamWriter mywriter = new OutputStreamWriter(openFileOutput(test.getAbsolutePath().toString(),Context.M ODE_PRIVATE));
mywriter.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
In the error code comes everytime: illegal Arguments: contains a path seperator!
Thank you for your help in advance
Maybe add more info about your error. But...
This error is about that you are trying to full path (include you subdirectories) to access to private data area.
Solution is use FileOutputStream, more here. And use
new File(YOUR_FILE)
to create your file.
Keep on mind that you should call method mkDirs() to create all necessary directories and subdirectories. More about mkDirs() here
Note: There is also method mkDir(), here is doc. This one will create a single directory.
I generate a midi file and write it like this:
File output = new File("exampleout.mid");
I think I might need to change this, so it is in the right folder (just a readable/writable folder, perhaps Music/ )
Next I want to play this midi file with MediaPlayer, but I cannot figure out how to load the file.
mediaPlayer = MediaPlayer.create(this, R.raw.test3);
Only loads from the read only directory /res/raw. But if I try something like:
mediaPlayer = MediaPlayer.create(this, "file://exampleout");
It does not work because create needs an integer as input. I experimented with AssetFileDescriptor, but haven't figured it out yet.
Meanwhile, I want to generate a new midi file and load it in mediaPlayer (chained) to play when the first file finishes playing.
MediaPlayer mediaPlayer = MediaPlayer.create(Activity.this,R.raw.a1);
mediaPlayer.setOnCompletionListener(new musicCompletionListener());
mediaPlayer.start();
private class musicCompletionListener implements OnCompletionListener {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.setDataSource(WHATTOPUTHERE)
mediaPlayer.release();
}
}
My Problem is really how to call the file. I cannot use strings apparantly, and the r.raw directory is not possible due to its read only nature. I feel the solution is not so difficult, but I am just easing into java from c++, any help is much appreciated!
I stored the file in the cache dir, that works!
File output = new File(getCacheDir() + "/exampleout.mid");
And then calling the file:
String filePath = null;
File file = null;
FileInputStream inputStream = null;
try {
filePath = getCacheDir() + "/exampleout.mid";
file = new File(filePath);
inputStream = new FileInputStream(file);
if(inputStream.getFD().valid())
{
System.out.println("Valid!");
}
} catch (Exception e1) {
e1.printStackTrace();
System.exit(-1);
}
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(inputStream.getFD());
inputStream.close();
} catch (Exception e1) {
e1.printStackTrace();
System.exit(-1);
}
try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
You have to nicely design the Architecture of your app then only you can achieve what you have asked.
According to me you can do the following.
Design an interface with the method midiReady(uri of midi file)
This interface is implemented by your activity which contains mediaplayer
As soon as midi file is generation is completed call the method midiReady(uri of midi file)
Now since your activity implements the interface callback is invoked on your activity and you can set the mediaplayer to play the midi file since in callback you have uri of your midi file.
The above metinoed points are just a faint idea what you can do.With above faint idea you can go forward for implementation.
Hope this will help.
Thanks.
First off, I am not trying to write to the SDCard. I want to write some information to a file that persists between uses of the app. It is essentially a file to hold favorites of the particular user. Here is what the code looks like:
try {
File file = new File("favorites.txt");
if (file.exists()) {
Log.d(TAG, "File does exist.");
fis = new FileInputStream(file);
br = new BufferedReader(new InputStreamReader(fis));
}
else {
Log.d(TAG, "File does not exist.");
return favDests;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
When running this code, we always get the "File does not exist." message in our DDMS log.
We have also tried the following code to no avail:
try {
File file = new File(GoLincoln.FAV_DEST_FILE);
fis = new FileInputStream(file);
br = new BufferedReader(new InputStreamReader(fis));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
It is this second portion of code that results in the FileNotFoundException.
I have read multiple tutorials on writing and reading files on Android and I believe I am following them pretty closely, so I am not sure why this code doesn't work successfully. I appreciate any help!
You shouldn't use the File class directly. Use Activity.getCacheDir() to get the cache dir which is specific to your application. Then use new File(cachedir, "filename.tmp") to create the file.
Preferences and SQLLite will both allow you to have persistent data without managing your own files.
To use shared preferences you grab it from your context, then you edit the values like so
mySharedPreferences = context.getSharedPreferences("DatabaseNameWhateverYouWant", 0);
mySharedPreferences.getEditor().putString("MyPreferenceName", "Value").commit();
To get a preference out
mySharedPreferences.getString("MyPreferenceName", "DefaultValue");
This is really the simplest way to do basic preferences, much easier then doing a file. More then strings are supported, most basic data types are available to be added to the Preferences class.