打开文件时出现异常

时间:2014-01-11 18:55:01

标签: java android

你好,

我正在开发一个导入pdf文件的书架应用程序,以便用户可以阅读它们。当您单击导入书籍按钮时,它表示它会导入书籍,但不会查看它们。一旦你关闭应用程序并尝试重新打开它,你就会关闭一个力量。这是logcat所说的:

Unable to decode stream: java.io.FileNotFoundException: /mnt/sdcard/shelf/preview/LittleBookOfRubypdf.png: open failed: ENOENT (No such file or directory)

Unable to decode stream: java.io.FileNotFoundException: /mnt/sdcard/shelf/preview/best_of_ruby_quizpdf.png: open failed: ENOENT (No such file or directory)

我有

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
AndroidManifest.xml中的

这是我的书架代码:

package com.sibext.android_shelf;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;

import com.d4a.tobias.R;
import com.sibext.android_shelf.adapter.ShelfAdapter;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.Toast;

public class Two extends Fragment{

    private static final String TARGET_DIRECTORY = "mnt/sdcard/shelf/";
    private ListView list;
    Context ctx;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

     @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.two, container, false);
            this.ctx = view.getContext();
            File dir = new File(TARGET_DIRECTORY);
            if(!dir.exists()){
                dir.mkdirs();
                //past here
                addBooksFromAssetsToCard();
            }else{
                String files[] = dir.list();
                if(files.length == 0){
                    //past here
                    addBooksFromAssetsToCard();
                }
            }

            list = (ListView) view.findViewById(R.id.list);

            ShelfAdapter adapter = new ShelfAdapter(view.getContext(), TARGET_DIRECTORY);
            adapter.setToListView(list);

            return view;
        }


        public void addBooksFromAssetsToCard(){
            List<String> books;
            try {
                books = getBooksFromAsset(ctx);

                for(String book : books){
                    copyFromAssets(book);
                }

            } catch (Exception e) {
            }
        }

        public List<String> getBooksFromAsset(Context ctx) throws Exception
        {
            AssetManager assetManager =ctx.getAssets();
            String[] files = assetManager.list("books");
            List<String> it=Arrays.asList(files);
            return it;
        }

        public void copyFromAssets(String book)
        {
            AssetManager assetManager = ctx.getAssets();
            String[] files = null;
            InputStream in = null;
            OutputStream out = null;
            //String filename = "filename.ext";
            try
            {
                in = assetManager.open("books/"+book);
                out = new FileOutputStream(Environment.getExternalStorageDirectory()+File.separator+"/shelf/"+book);
                Log.d("Copying...", ""+book);
                copyFile(in, out); 
                in.close();
                in = null;
                out.flush();
                out.close();
                out = null;
            }
            catch(Exception e)
            { 
                Log.e("tag", "Failed to copy asset file: " + book, e);
            }      
        }
        public void copyFile(InputStream in, OutputStream out) throws Exception
        {
            byte[] buffer = new byte[1024];
            int read;
            while((read = in.read(buffer)) != -1)
            {
                out.write(buffer, 0, read);
            }
            Log.d("Copy_State", "Done...");
        }

        /*public void onImportClicked(View v){
            Toast.makeText(v.getContext(), "Please wait...", Toast.LENGTH_LONG).show();
            Intent in = new Intent(v.getContext(), ImportBooks.class);
            startActivity(in);
        }*/
}

这是导入书籍代码:

package com.sibext.android_shelf;

import java.io.File;


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import com.d4a.tobias.R;

import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;

public class ImportBooks extends Activity {

    int index =0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.import_books);

        populateTotal();
        try {
            copybooks();
        } catch (Exception e) {
        }
    }


    public void copybooks() throws Exception{
        String rootPath = Environment.getExternalStorageDirectory().toString();
        List<String> books = fetchToneFiles(getApplicationContext(), rootPath);
        String desPath = rootPath+File.separator+"shelf"+File.separator;

        for(String book : books){
            File file = new File(desPath+fetchBookName(book));
            if(!file.exists()){
                Log.d("[BOOK_Status]", "--Not Exist in shelf-- :"+book);

                File from = new File(book);
                File to = new File(desPath+fetchBookName(book));
                copyDirectoryOneLocationToAnotherLocation(from, to);
                index++;
                new Handler().postDelayed(new Runnable() {
                    public void run() {
                        //
                        ((TextView) findViewById(R.id.total)).setText(String.valueOf(index));
                    }
                }, 2 * 1000);   
            }
        }

        if(index == 0){
            Toast.makeText(getApplicationContext(), "No new book found...", Toast.LENGTH_LONG).show();
        }else{
            Toast.makeText(getApplicationContext(), "All Books imported successfully...", Toast.LENGTH_LONG).show();
        }
        new Handler().postDelayed(new Runnable() {
            public void run() {
                //Intent in = new Intent(getApplicationContext(), MainActivity_old.class);
                //startActivity(in);
                finish();
            }
        }, 7 * 1000);
    }

    public void copyDirectoryOneLocationToAnotherLocation(File sourceLocation, File targetLocation)
            throws Exception {

        if (sourceLocation.isDirectory()) {
            if (!targetLocation.exists()) {
                targetLocation.mkdir();
            }

            String[] children = sourceLocation.list();
            for (int i = 0; i < sourceLocation.listFiles().length; i++) {

                copyDirectoryOneLocationToAnotherLocation(new File(sourceLocation, children[i]),
                        new File(targetLocation, children[i]));
            }
        } else {

            InputStream in = new FileInputStream(sourceLocation);

            OutputStream out = new FileOutputStream(targetLocation);

            // Copy the bits from instream to outstream
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            in.close();
            out.close();
        }

    }

    public void populateTotal(){
        String rootPath = Environment.getExternalStorageDirectory().toString();
        List<String> _str = fetchToneFiles(getApplicationContext(), rootPath);
        int index = 0;
        for(String str : _str){
            //Toast.makeText(getApplicationContext(), fetchBookName(str), Toast.LENGTH_LONG).show();
            index++;
        }
        ((TextView) findViewById(R.id.imported)).setText(String.valueOf(index));
    }

    public static List<String> fetchToneFiles(Context ctx, String rootPath) {
        final List<String> tFileList = new ArrayList<String>();
        String[] imageTypes = {"pdf"};
        FilenameFilter[] filter = new FilenameFilter[imageTypes.length];

        int i = 0;
        for (final String type : imageTypes) {
            filter[i] = new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.endsWith("." + type);
                }
            };
            i++;
        }

        FileUtils fileUtils = new FileUtils();
        File[] allMatchingFiles = fileUtils.listFilesAsArray(
                new File(rootPath), filter, -1);
        for (File f : allMatchingFiles) {
            tFileList.add(f.getAbsolutePath());
        }
        return tFileList;
    }

    public String fetchBookName(String basepath){
        String bookname = null;
        if(basepath.length()>6){
            int index = basepath.lastIndexOf("/");
            return basepath.substring(index+1, basepath.length());

        }else{
            return bookname;
        }
    }

    @Override
    public void onBackPressed() {
        finish();
        super.onBackPressed();
    }

}

我的货架物品代码:

package com.sibext.android_shelf.shelf;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import com.artifex.mupdfdemo.MuPDFCore;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PointF;

public class ShelfItem {

    private File file;
    private String imgPath;

    public ShelfItem(File file){
        if(file == null){
            throw new NullPointerException("Impossible init ShelfItem by null file");
        }
        this.file = file;
        imgPath = file.getName().replace(".", "") + ".png";

        createPreviewDir();
    }

    private void createPreviewDir(){
        File dir = new File(getPreviewDir());
        if(!dir.exists()){
            dir.mkdirs();
        }
    }

    public File getFile() {
        return file;
    }

    private String getPreviewPath(){
        return getPreviewDir() + imgPath;
    }

    private String getPreviewDir(){
        return file.getParent() + File.separator + "preview" + File.separator;
    }

    public void savePreview(Bitmap b){
        try {
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            b.compress(Bitmap.CompressFormat.JPEG, 40, bytes);

            File f = new File(getPreviewPath());


            f.createNewFile();
            FileOutputStream fo = new FileOutputStream(f);
            fo.write(bytes.toByteArray());

            fo.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Bitmap getPreview(int rowHeight){
        MuPDFCore core = null;
        try {
            core = new MuPDFCore(getFile().getAbsolutePath());
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(core == null){
            return null;
        }
        core.countPages();
        PointF size = core.getPageSize(0);
        int h = rowHeight;
        int w = (int)(h * (size.x/size.y));
        return core.drawPage(0, w, h, 0, 0, w, h);
    }

    public Bitmap getPreviewFromSD(){
        return BitmapFactory.decodeFile(getPreviewPath());
    }

}

任何帮助都会很棒 提前致谢

此致

克里斯

1 个答案:

答案 0 :(得分:2)

你永远不应该“硬编码”SD路径,因为你可能知道android设备有几个制造商。这些制造商可以自由地定义SD卡的路径(简而言之:/ mnt / sdcard不是每个Android设备上的SD卡路径)

使用内置函数“Environment.getExternalStorageState()”来获取路径。来自android开发者文档:

  

Environment.getExternalStorageState()返回内部SD挂载点的路径,如“/ mnt / sdcard”