Reputation: 13
I am writing an app that on hitting the share options on the tool bar with ShareActionProvider it will allow the user to send it songs through email . but I keep getting an exception of FileNotFoundException here is the code and the exception is this
java.io.FileNotFoundException: song.mp3: open failed: ENOENT (No such file or directory)
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// TODO: Implement this method
menu.clear();
MenuInflater inflator = getMenuInflater();
inflator.inflate(R.menu.sidebar_menu, menu);
SubMenu subMenu = menu.addSubMenu("Themes");
subMenu.add(0 , blue , 0 , "Blue");
subMenu.add(0, pink , 1, "Pink");
items = subMenu.getItem().getItemId();
// tool bar menu
ArrayList<Uri> al = new ArrayList<Uri>();
ArrayList<Uri> emailAl = new ArrayList<Uri>();
ListView lv = (ListView)findViewById(R.id.downloads);
MenuItem mi = menu.findItem(R.id.searchable);
MenuItem share = menu.findItem(R.id.share);
mi.setIcon(android.R.drawable.ic_search_category_default);
SearchView searchView = (SearchView) menu.findItem(R.id.searchable).getActionView();
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
ShareActionProvider sap =(ShareActionProvider) MenuItemCompat.getActionProvider(share);
Intent intentShare = new Intent(Intent.ACTION_SEND_MULTIPLE);
Intent intentEmail = new Intent(Intent.ACTION_SEND_MULTIPLE);
intentShare.setType("audio/mp3");
intentEmail.setType("audio/mp3");
Uri uri = null;
Uri uriEmail = null;
try{
for(String file : mp3Files ){
File filein = new File(file);
uri = Uri.fromFile(filein);
FileInputStream in = new FileInputStream(filein.getName());
File outFile = new File(filein.getPath(), filein.getName()); // IMPORTANT! You need to create your file object separately, so you can then pass it to intent as well..
OutputStream out = new FileOutputStream(outFile);
byte[] buf = new byte[1024];
int len; while ( (len = in.read(buf, 0, buf.length)) != -1){
out.write(buf, 0, len);
}
in.close();
out.close();
uriEmail = Uri.fromFile(outFile); // Here you passed the parent directory file.. Pass newly created file object ..
al.add(uri);
emailAl.add(uriEmail);
}
} catch(IOException e){
e.printStackTrace();
}
String text = "";
intentShare.putParcelableArrayListExtra(Intent.EXTRA_STREAM,al );
intentEmail.putParcelableArrayListExtra(Intent.EXTRA_STREAM,emailAl);
intentEmail.putExtra(Intent.EXTRA_SUBJECT , "Subject");
intentEmail.putExtra(Intent.EXTRA_TEXT , text);
sap.setShareIntent(intentShare);
sap.setShareIntent(intentEmail);
MenuItemCompat.OnActionExpandListener el = new MenuItemCompat.OnActionExpandListener(){
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Do something when action item collapses
return true; // Return true to collapse action view
}
Here is the mp3files part where mp3files is declared globally
private void ShowLists(){
files = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_DOWNLOADS).toString());
downloads = files.listFiles(new FileFilter(){
@Override
public boolean accept(File file){
String ext = file.getName();
if(ext.endsWith(".mp3")){
return true;
}
return false;
}
});
mp3Files = new String[downloads.length];
for(int i = 0; i < mp3Files.length; i++){
mp3Files[i] = downloads[i].getName();
}
adapter = new ArrayAdapter<String>(this,R.layout.downloads, R.id.textviewone , mp3Files);
ListView downloadsList = (ListView) findViewById(R.id.downloads);
downloadsList.setAdapter(adapter);
if(adapter.isEmpty()){
downloadsList.setAdapter(null);
} else {
downloadsList.setAdapter(adapter);
}
}
I have also tried using several different ways of getting the downloads directory including the Environment way but it still don't work please help
EDITED UPDATED
So I changed my code to this and still not working
try{
for(File file : mp3Files){
File filein = new File(file.toString());
uri = Uri.fromFile(filein);
FileInputStream in = new FileInputStream(filein);
File outFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), filein.getName()); // IMPORTANT! You need to create your file object separately, so you can then pass it to intent as well..
OutputStream out = new FileOutputStream(outFile);
byte[] buf = new byte[1024];
int len; while ( (len = in.read(buf, 0, buf.length)) != -1){
out.write(buf, 0, len);
}
in.close();
out.close();
uriEmail = Uri.fromFile(outFile); // Here you passed the parent directory file.. Pass newly created file object ..
al.add(uri);
emailAl.add(uriEmail);
}
} catch(IOException e){
e.printStackTrace();
}
Upvotes: 0
Views: 589
Reputation: 191743
mp3Files
is just the file names, not the full path to the file on disk.
mp3Files[i] = downloads[i].getName();
You are getting FileNotFound because you can't new File()
with just the name and expect it to know where to look for that file.
Needs to be this, but as you can see, mp3Files
is not necessary to use.
mp3Files[i] = downloads[i];
In other words, mp3Files = files.listFiles(...)
Then, this loop could just be for (File file : mp3Files)
for(String file : mp3Files ){
File filein = new File(file);
uri = Uri.fromFile(filein);
If you really want the adapter to show only the names of the files, then you can implement your own ArrayAdapter class to accept a File[]
, then display only the getName()
of that File
in the getView()
method.
Also, checking adapter.isEmpty()
and setting a null adapter is not really necessary. If the adapter is empty, no data is shown. If you want to display an empty view, then ListView class has a setEmptyView
method.
Upvotes: 1