简体   繁体   中英

I am getting a File not found exception and I don't know why the path is correct

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM