Android 实现PDF文件的查看(本地和网络文件)

PDF文件大家应该不陌生,说的简单点,其实我认为就是一个全图片的Word,里面的每个页面都可以看做是一张带文字的图片,接下来我们看看在Android应用里如何读取和查看PDF文件内容。

1 在项目的gradle中增加如下代码:

compile 'com.joanzapata.pdfview:android-pdfview:1.0.4@aar'

先看看布局文件代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include layout="@layout/title_all" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.joanzapata.pdfview.PDFView
            android:id="@+id/pdf"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <TextView
            android:id="@+id/tv_page"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:textColor="@color/colorAccent"
            android:layout_alignParentTop="true"
            android:textSize="18sp" />
    </RelativeLayout>
</LinearLayout>

其中PDFView控件就是pdfview库里面的查看PDF的控件,接下来声明并初始化后查看本地Asserts资源下的PDF文件,代码如下

pdf.fromAsset("abcd.pdf")
        .defaultPage(1)
        .showMinimap(false)
        .enableSwipe(true)
        .onPageChange(this)
        .load();

这样就可以查看pdf文件内容了,但是如果是网上在线查看PDF文件该如何实现呢?

我的思路是这样:

第一步,把PDF文件下载下来;

第二步,把文件保存在手机存储中;

第三步,读取手机SD卡的PDF文件。

接下来就一步一步实现,当然下载、保存、读取SD卡的内容首先就得有权限,相关权限的申请就不多说了,基本功你懂得!

下载的话方式很多,你可以用任何可以下载文件的网络框架,我用的是okhttp下载的,代码如下

/**
 * 下载
 */
private void downloadFile() {
    OkHttpUtils.build().download(path, savePath, new OkHttpUtils.OnDownloadListener() {
        @Override
        public void onDownloadSuccess(File file) {
            tvPage.setText("加载完成正在打开..");
            showPdf(file.getPath());
        }
        @Override
        public void onDownloading(int progress) {
            Log.i("JAVA", "onDownloading"+progress);
            tvPage.setText("正在加载("+progress+"/100)");
        }
        @Override
        public void onDownloadFailed() {
            Log.i("JAVA", "onDownloadFailed");
            tvPage.setText("加载失败..");
        }
    });
}

下载方法中path是网络上PDF文件的额下载全路径,savePath是下载下来的文件保存的目录,onDownloadSuccess是下载完成后的回调方法,回调的是下载的文件,file.getPath()可以获取这个文件保存的路径地址,okhttp我自己封装了一个工具类,代码奉上

**
 * OkHttp3工具类
 * 2018/9/11
 */
public class OkHttpUtils {
    private static OkHttpClient client;
    private static OkHttpUtils okHttpUtils;
    private OkHttpCallback callback;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1://异常
                    IOException e = (IOException) msg.obj;
                    LogUtils.i("ruin", "e--> " + e.toString());
                    callback.onError(e);
                    break;
                case 2://成功
                    String result = (String) msg.obj;
                    callback.onResponse(result);
                    break;
            }
        }
    };

    /**
     * http请求
     */
    public static OkHttpUtils build() {
        OkHttpClient.Builder sBuilder = new OkHttpClient.Builder();
        client = sBuilder.build();
        okHttpUtils = new OkHttpUtils();
        return okHttpUtils;
    }

    //设置回调方法
    public OkHttpUtils setCallback(OkHttpCallback callback) {
        this.callback = callback;
        return okHttpUtils;
    }

    //post请求
    public OkHttpUtils postOkHttp(String url, Map<String, Object> params) {
        FormBody.Builder builder = new FormBody.Builder();
        String temp = "";
        for (String key : params.keySet()) {
            builder.add(key, String.valueOf(params.get(key)));
            temp += (key + "=" + String.valueOf(params.get(key)) + "&");
        }
        LogUtils.i("LogUtils", "url =" + url + "?" + temp);
        FormBody formBody = builder.build();
        Request request = new Request.Builder()
                .url(url)
                .post(formBody)
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Message msg = Message.obtain();
                msg.what = 1;
                msg.obj = e;
                handler.sendMessage(msg);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String result = response.body().string();
                Message msg = Message.obtain();
                msg.what = 2;
                msg.obj = result;
                handler.sendMessage(msg);
            }
        });
        return okHttpUtils;
    }


    public OkHttpUtils postAsync(String url, Map<String, Object> params) {
        RequestBody requestBody;
        if (params == null) {
            params = new HashMap<>();
        }
        /**
         * OKhttp3.0之后版本
         */
        FormBody.Builder builder = new FormBody.Builder();
        /**
         * 在这对添加的参数进行遍历,map遍历有四种方式,如果想要了解的可以网上查找
         */
        String temp = "";
        for (Map.Entry<String, Object> map : params.entrySet()) {
            String key = map.getKey();
            Object value;
            value = map.getValue() == null ? "" : map.getValue();
            builder.add(key, String.valueOf(value));
            temp += (key + "=" + String.valueOf(value));
        }
        LogUtils.i("LogUtils", "url =" + url + "?" + temp);
        requestBody = builder.build();
        final Request request = new Request.Builder().url(url).post(requestBody).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Message msg = Message.obtain();
                msg.what = 1;
                msg.obj = e;
                handler.sendMessage(msg);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String result = response.body().string();
                Message msg = Message.obtain();
                msg.what = 2;
                msg.obj = result;
                handler.sendMessage(msg);
            }
        });
        return okHttpUtils;
    }

    //请求回调接口
    public interface OkHttpCallback {
        void onError(Exception e);
        void onResponse(String result);
    }

    /**
     * 判断是否有网络连接
     */
    private boolean isNetworkConnected(@NonNull Context context) {
        ConnectivityManager mConnectivityManager =
                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
        return mNetworkInfo != null && mNetworkInfo.isAvailable();
    }

    /**
     * @param url      下载连接
     * @param saveDir  储存下载文件的SDCard目录
     * @param listener 下载监听
     */
    public void download(final String url, final String saveDir, final OnDownloadListener listener) {
        Request request = new Request.Builder().url(url).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 下载失败
                listener.onDownloadFailed();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                // 储存下载文件的目录
                String savePath = isExistDir(saveDir);
                try {
                    is = response.body().byteStream();
                    long total = response.body().contentLength();
                    File file = new File(savePath, getNameFromUrl(url));
                    fos = new FileOutputStream(file);
                    long sum = 0;
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        int progress = (int) (sum * 1.0f / total * 100); // 下载中
                        listener.onDownloading(progress);
                    }
                    fos.flush(); // 下载完成
                    listener.onDownloadSuccess(file);
                } catch (Exception e) {
                    listener.onDownloadFailed();
                } finally {
                    try {
                        if (is != null) {
                            is.close();
                        }
                    } catch (IOException e) {
                    }
                    try {
                        if (fos != null) {
                            fos.close();
                        }
                    } catch (IOException e) {
                    }
                }
            }
        });
    }

    /**
     * 判断下载目录是否存在
     */
    private String isExistDir(String saveDir) throws IOException {
        // 下载位置
        File downloadFile = new File(Environment.getExternalStorageDirectory(), saveDir);
        if (!downloadFile.mkdirs()) {
            downloadFile.createNewFile();
        }
        String savePath = downloadFile.getAbsolutePath();
        return savePath;
    }

    /**
     * 从下载连接中解析出文件名
     */
    @NonNull
    private String getNameFromUrl(String url) {
        return url.substring(url.lastIndexOf("/") + 1);
    }

    public interface OnDownloadListener {
        /**
         * 下载成功
         */
        void onDownloadSuccess(File file);
        /**
         * 下载进度
         */
        void onDownloading(int progress);
        /**
         * 下载失败
         */
        void onDownloadFailed();
    }
}

当然要用okhttp下载需要添加okhttp库文件,我用的是okhttp3

compile 'com.squareup.okhttp3:okhttp:3.9.0'

在上面下载成功的回调方法里传入下载的PDF文件路径打开文件 showPdf(file.getPath());

private void showPdf(String fileName) {
    if (TextUtils.isEmpty(fileName)) {
        Toast.makeText(this, "文件不存在", Toast.LENGTH_SHORT).show();
    } else {
        try {
            pdf.fromFile(new File(fileName))
                    .defaultPage(1)
                    .showMinimap(false)
                    .enableSwipe(true)
                    .onLoad(new OnLoadCompleteListener() {
                        @Override
                        public void loadComplete(int nbPages) {
                            float pageWidth = pdf.getOptimalPageWidth();
                            float viewWidth = pdf.getWidth();
                            pdf.zoomTo(viewWidth / pageWidth);
                            pdf.loadPages();
                        }
                    })
                    .onPageChange(this)
                    .load();
        } catch (FileNotFoundException e) {
            Toast.makeText(this, "文件不存在", Toast.LENGTH_SHORT).show();
            File file = new File(fileName);
            FileUtils.deleteFile(file);
        }
    }
}

打开之后就可以查看了,和查看Asserts资源下的PDF文件基本一样了,有一个点差点忘了就是实现OnPageChangeListener接口,然后在重写的onPageChanged方法中显示当前查看的页面是多少页和一共有多少页

@Override
public void onPageChanged(int page, int pageCount) {
    String pager = "页码(" + page + "/" + pageCount + ")";
    tvPage.setText(pager);
}

好了,pdf文件查看就这样完成了,谁有更好的方法可以互相推荐学习。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现Android应用中选取本地PDF文件并上传,可以按照以下步骤: 1. 在AndroidManifest.xml文件中添加以下权限: ```xml <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> ``` 2. 在需要上传PDF文件的Activity中添加以下代码: ```java // 定义一个变量,用于存储选中的文件路径 private String filePath; // 启动文件选择器 private void showFileChooser() { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("application/pdf"); intent.addCategory(Intent.CATEGORY_OPENABLE); startActivityForResult(Intent.createChooser(intent, "选择PDF文件"), 1); } // 处理文件选择器的返回结果 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1 && resultCode == RESULT_OK && data != null) { Uri uri = data.getData(); // 获取选中文件的路径 String[] filePathColumn = {MediaStore.Images.Media.DATA}; Cursor cursor = getContentResolver().query(uri, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); filePath = cursor.getString(columnIndex); cursor.close(); // TODO: 在这里实现上传文件的逻辑 } } ``` 3. 在上传文件的逻辑中,可以使用第三方库或自己实现上传功能,例如: ```java // 使用OkHttp库上传文件 private void uploadFile() { File file = new File(filePath); RequestBody fileBody = RequestBody.create(MediaType.parse("application/pdf"), file); RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("file", file.getName(), fileBody) .build(); Request request = new Request.Builder() .url("上传文件的URL") .post(requestBody) .build(); OkHttpClient client = new OkHttpClient(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { // TODO: 处理上传失败的情况 } @Override public void onResponse(Call call, Response response) throws IOException { // TODO: 处理上传成功的情况 } }); } ``` 注意,这里只是一个简单的示例代码,实际应用中可能需要根据具体需求进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值