前言:

最近在做订单结算功能,需要上传发票,发票有电子和图片发票两种,技术这边有两种方案,一种是上传图片文件,还有一种是上传PDF格式发票文件,但是结算时财务说图片文件上面没有公司盖章,是无效的,于是把方案改为电子发票PDF和纸质发票,刚开始使用的文件管理器搜索手机内的PDF文件,在4.4系统上面打开文件管理器可以过滤掉非.pdf格式文件,在6.0及以上系统没有过滤掉,用的是intent打开url的方式打开文件管理器,在返回的结果中根据URL转化为文件,然后上传。

1.先上效果图,无图无真相,图能说明一切:

2.Intent方式打开pdf格式文件:

  Intent intent = new Intent(Intent.ACTION_GET_CONTENT);intent.setType("application/pdf");try {startActivityForResult(intent, REQUEST_CODE);} catch (ActivityNotFoundException e) {//alert user that file manager not workingToastUtils.ToastShort(Utils.getContext().getResources().getString(R.string.toast_pick_file_error));}

这种方式也可以拿到.pdf格式的文件,但是在小米手机上有个最近文件记录打开时返回报错,由于时间和项目着急上线,所以没有适配6.0及以上系统的手机,采用了第2种方式----通过ContentProvider搜索手机内的.pdf格式文件

3.通过ContentProvider搜索pdf格式文件核心代码如下:

博主中搜索的是.pdf格式的文件,如果想搜索其他格式文件方法类似,改后缀名比如.txt,.doc,.png等等,小伙伴们可以自行尝试下,看看效果如何,这里就不一一尝试和介绍了.

/*** 获取手机文档数据** @param*/
public void getDocumentData() {
​String[] columns = new String[]{MediaStore.Files.FileColumns._ID, MediaStore.Files.FileColumns.MIME_TYPE, MediaStore.Files.FileColumns.SIZE, MediaStore.Files.FileColumns.DATE_MODIFIED, MediaStore.Files.FileColumns.DATA};
​String select = "(_data LIKE '%.pdf')";
​ContentResolver contentResolver = getContentResolver();Cursor cursor = contentResolver.query(MediaStore.Files.getContentUri("external"), columns, select, null, null);
​int columnIndexOrThrow_DATA = 0;if (cursor != null) {columnIndexOrThrow_DATA = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA);}
​if (cursor != null) {while (cursor.moveToNext()) {
​String path = cursor.getString(columnIndexOrThrow_DATA);
​PDFFileInfo document = PDFUtil.getFileInfoFromFile(new File(path));
​pdfData.add(document);Log.d(TAG, " pdf " + document);}}cursor.close();
}

4.PDFSearchActivity代码:

public class PDFSearchActivity extends AppCompatActivity {private RecyclerView mRecyclerView;private ProgressDialog progressDialog;private PDFAdapter pdfAdapter;private ImageView imgBack;private TextView tvTitle;private TextView tvFinish;private ArrayList<PDFFileInfo> pdfData = new ArrayList<>();private String TAG = PDFSearchActivity.class.getSimpleName();
​
​@SuppressLint("HandlerLeak")private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);if (msg.what == 1) {initRecyclerView();}}};
​
​@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_pdf_select);initViews();initListener();}
​private void initViews() {mRecyclerView = findViewById(R.id.rv_pdf);imgBack = findViewById(R.id.iv_back);tvTitle = findViewById(R.id.tv_title);tvFinish = findViewById(R.id.tv_right);tvTitle.setText("PDF文件搜索");
​imgBack.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {finish();}});
​showDialog();
​new Thread() {@Overridepublic void run() {super.run();getFolderData();}}.start();}
​private void initListener() {
​}
​private void showDialog() {progressDialog = new ProgressDialog(this, ProgressDialog.THEME_HOLO_LIGHT);progressDialog.setMessage("正在加载数据中...");progressDialog.setCanceledOnTouchOutside(false);progressDialog.show();}
​
​private void initRecyclerView() {pdfAdapter = new PDFAdapter(this);View notDataView = getLayoutInflater().inflate(R.layout.pdf_empty_view, (ViewGroup) mRecyclerView.getParent(), false);
​mRecyclerView.setLayoutManager(new LinearLayoutManager(this));mRecyclerView.setAdapter(pdfAdapter);
​pdfAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {@Overridepublic void onItemClick(BaseQuickAdapter adapter, View view, int position) {
​if (!pdfData.get(position).isSelect()) {if (getSelectNumber() >= 3) {Toast.makeText(PDFSearchActivity.this, "最多可选择3个文件", Toast.LENGTH_SHORT).show();return;}}
​for (int i = 0; i < pdfData.size(); i++) {if (i == position) {if (pdfData.get(i).isSelect()) {pdfData.get(i).setSelect(false);} else {pdfData.get(i).setSelect(true);}}}adapter.notifyDataSetChanged();
​tvFinish.setText("完成(" + getSelectNumber() + ")");
​
​}});if (pdfData != null && pdfData.size() > 0) {
​for (int i = 0; i < pdfData.size(); i++) {pdfData.get(i).setSelect(false);}pdfAdapter.setNewData(pdfData);} else {pdfAdapter.setEmptyView(notDataView);}progressDialog.dismiss();}
​
​/*** 遍历文件夹中资源*/public void getFolderData() {getDocumentData();handler.sendEmptyMessage(1);}
​/*** 获取手机文档数据** @param*/public void getDocumentData() {
​String[] columns = new String[]{MediaStore.Files.FileColumns._ID, MediaStore.Files.FileColumns.MIME_TYPE, MediaStore.Files.FileColumns.SIZE, MediaStore.Files.FileColumns.DATE_MODIFIED, MediaStore.Files.FileColumns.DATA};
​String select = "(_data LIKE '%.pdf')";
​ContentResolver contentResolver = getContentResolver();Cursor cursor = contentResolver.query(MediaStore.Files.getContentUri("external"), columns, select, null, null);
​int columnIndexOrThrow_DATA = 0;if (cursor != null) {columnIndexOrThrow_DATA = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA);}
​if (cursor != null) {while (cursor.moveToNext()) {
​String path = cursor.getString(columnIndexOrThrow_DATA);
​PDFFileInfo document = PDFUtil.getFileInfoFromFile(new File(path));
​pdfData.add(document);Log.d(TAG, " pdf " + document);}}cursor.close();}
​private int getSelectNumber() {int k = 0;for (int i = 0; i < pdfData.size(); i++) {if (pdfData.get(i).isSelect()) {k++;}}return k;}
​
}

5.activity_pdf_select.xml代码:

<?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"><includelayout="@layout/toolbar"/>
​<androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/rv_pdf"android:layout_width="match_parent"android:layout_height="match_parent">
​</androidx.recyclerview.widget.RecyclerView>
​
</LinearLayout>

6.PDFAdapter代码:

/*** @作者: njb* @时间: 2019/9/11 20:31* @描述: pdf文件适配器类*/
public class PDFAdapter extends BaseQuickAdapter<PDFFileInfo, BaseViewHolder> {
​public PDFAdapter(@Nullable List<PDFFileInfo> data) {super(R.layout.item_pdf,data);}
​
​@Overrideprotected void convert(BaseViewHolder helper, PDFFileInfo item) {if(item == null){return;}helper.setText(R.id.tv_name , item.getFileName());helper.setText(R.id.tv_size , PDFUtil.FormetFileSize(item.getFileSize()));helper.setText(R.id.tv_time , item.getTime());if (item.isSelect()){helper.getView(R.id.img_select).setBackgroundResource(R.mipmap.reward_selection_ok);}else {helper.getView(R.id.img_select).setBackgroundResource(R.mipmap.reward_selection_no);
​}}
}

7.PDFUtil

public class PDFUtil {
​/*** 读取文件的最后修改时间的方法*/public static String getFileLastModifiedTime(File f) {Calendar cal = Calendar.getInstance();long time = f.lastModified();SimpleDateFormat formatter = newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");cal.setTimeInMillis(time);return formatter.format(cal.getTime());}
​
​
​
​public static PDFFileInfo getFileInfoFromFile(File file) {PDFFileInfo fileInfo = new PDFFileInfo();fileInfo.setFileName(file.getName());fileInfo.setFilePath(file.getPath());fileInfo.setFileSize(file.length());
//        fileInfo.setDirectory(file.isDirectory());fileInfo.setTime(PDFUtil.getFileLastModifiedTime(file));int lastDotIndex = file.getName().lastIndexOf(".");if (lastDotIndex > 0) {String fileSuffix = file.getName().substring(lastDotIndex + 1);
//            fileInfo.setSuffix(fileSuffix);}return fileInfo;}
​public static String FormetFileSize(long fileS) {DecimalFormat df = new DecimalFormat("#.00");String fileSizeString = "";String wrongSize = "0B";if (fileS == 0) {return wrongSize;}if (fileS < 1024) {fileSizeString = df.format((double) fileS) + "B";} else if (fileS < 1048576) {fileSizeString = df.format((double) fileS / 1024) + "KB";} else if (fileS < 1073741824) {fileSizeString = df.format((double) fileS / 1048576) + "MB";} else {fileSizeString = df.format((double) fileS / 1073741824) + "GB";}return fileSizeString;}
​/*** 利用文件url转换出文件名** @param url* @return*/public static String parseName(String url) {String fileName = null;try {fileName = url.substring(url.lastIndexOf("/") + 1);} finally {if (TextUtils.isEmpty(fileName)) {fileName = String.valueOf(System.currentTimeMillis());}}return fileName;}
​
​/*** 将url进行encode,解决部分手机无法下载含有中文url的文件的问题(如OPPO R9)** @param url* @return* @author xch*/public static String toUtf8String(String url) {StringBuffer sb = new StringBuffer();for (int i = 0; i < url.length(); i++) {char c = url.charAt(i);if (c >= 0 && c <= 255) {sb.append(c);} else {byte[] b;try {b = String.valueOf(c).getBytes("utf-8");} catch (Exception ex) {System.out.println(ex);b = new byte[0];}for (int j = 0; j < b.length; j++) {int k = b[j];if (k < 0)k += 256;sb.append("%" + Integer.toHexString(k).toUpperCase());}}}return sb.toString();}
​public static String parseFormat(String fileName) {return fileName.substring(fileName.lastIndexOf(".") + 1);}
}

8.PDFAdapter的Item代码

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:layout_margin="@dimen/space_10">
​<ImageViewandroid:id="@+id/img"android:layout_width="60dp"android:layout_height="60dp"android:src="@mipmap/pdf" />
​<ImageViewandroid:id="@+id/img_select"android:layout_width="25dp"android:layout_height="25dp"android:background="@mipmap/reward_selection_no"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintTop_toTopOf="parent" />
​
​<TextViewandroid:id="@+id/tv_name"android:layout_width="0dp"android:layout_height="wrap_content"android:ellipsize="end"android:maxLines="1"android:text="深入浅出nodejs.pdf"android:layout_marginLeft="6dp"android:layout_marginRight="6dp"app:layout_constraintLeft_toRightOf="@+id/img"app:layout_constraintRight_toLeftOf="@+id/img_select"/>
​<TextViewandroid:id="@+id/tv_size"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="2dp"android:text="KB"android:textSize="@dimen/text_size_11"app:layout_constraintTop_toBottomOf="@+id/tv_name"app:layout_constraintLeft_toRightOf="@+id/img"android:layout_marginLeft="6dp"/>
​<TextViewandroid:id="@+id/tv_time"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="6dp"android:text="2019-09-21"android:textSize="@dimen/text_size_11"app:layout_constraintLeft_toRightOf="@+id/img"app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

9.pdf_search_shape.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"><solid android:color="@color/colorPrimary"/><corners android:radius="@dimen/space_10"/>
</shape>

10.pdf_empty_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:gravity="center"android:background="@color/white"android:orientation="vertical"android:layout_height="match_parent"><ImageViewandroid:layout_gravity="center"android:id="@+id/iv_nodata"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@mipmap/no_date_without_text"android:visibility="visible" /><TextViewandroid:id="@+id/tvTip"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/str_blank"/>
</LinearLayout>

11.Manifast加上权限申请

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

12.在MainActivity动态申请权限

public class MainActivity extends AppCompatActivity {private static final String TAG = "RxPermissionTest";private Button btnUpload;private ImageView ivBack;private TextView tvTitle;
​@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initViews();requestPermission();
​}
​private void initViews() {btnUpload = findViewById(R.id.tv_upload);ivBack = findViewById(R.id.iv_back);tvTitle = findViewById(R.id.tv_title);tvTitle.setText("PDFSearch");ivBack.setVisibility(View.GONE);btnUpload.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {startActivity(new Intent(MainActivity.this, PDFSearchActivity.class));
​}});}
​@SuppressLint("InlinedApi")private void requestPermission() {RxPermissions rxPermissions = new RxPermissions(this);rxPermissions.requestEach(Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE).subscribe(new Consumer<Permission>() {@Overridepublic void accept(Permission permission) {if (permission.granted) {// 用户已经同意该权限Log.d(TAG, permission.name + " is granted.");} else if (permission.shouldShowRequestPermissionRationale) {// 用户拒绝了该权限,没有选中『不再询问』(Never ask again),那么下次再次启动时,还会提示请求权限的对话框Log.d(TAG, permission.name + " is denied. More info should be provided.");} else {// 用户拒绝了该权限,并且选中『不再询问』Log.d(TAG, permission.name + " is denied.");}
​}});}
}

13.后面会给出源码地址,实现PDF预览功能.欢迎小伙伴们留言,有问题提出,及时改进.

csdn下载地址:PDFSearch.zip-Android文档类资源-CSDN下载,由于现在csdn默认的下载都要积分,不能修改,所以很抱歉哈~~

14.没有积分的同学也可以去码云下载源码,地址为:

PDFSearch: Android实现手机内PDF文件搜索

Android实现搜索手机内的PDF文件相关推荐

  1. Android App开发手机阅读中PDF文件渲染器的讲解及使用(附源码 简单易懂)

    需要源码和图片集请点赞关注收藏后评论区留言~~~ 一.PDF文件渲染器 Android集成了PDF的渲染操作,从很大程度上方便了开发者,这个PDF文件渲染器便是PdfRenderer.渲染器允许从存储 ...

  2. android APP内显示PDF文件

    android APP内显示PDF文件 最近公司要做一个小功能,显示在APP内部显示pdf文件,刚接到任务感觉非常简单的一小功能,做的时候才发现在真的很不好实现. 因为android的webView与 ...

  3. 音乐播放器从0到读取手机内的音乐文件——Android Studio小白实训笔记

    前言: 小白的我在经历了两周的Android Studio实训课的学习后,编辑了简易音乐播放器的半成品,通过两周的学习让我对打码又激起了兴趣,很感谢实训老师江哥(博客ID:3052world)的悉心教 ...

  4. android标记 pdf,PDF标记篇二:安卓手机怎样在pdf文件中做标记

    原标题:PDF标记篇二:安卓手机怎样在pdf文件中做标记 在日常办公中,常常需要给pdf文件添加一些标记,为的是给文本做些说明或者让重点更加明显.电脑上做标记非常简单,不用小编多说!这里小编要说的是在 ...

  5. Android 将文本和图片写入到pdf文件以及读取手机里的pdf文件

    1.首先讲一下将文本和图片写入到pdf文件这个功能实现的思路 获取PdfDocument对象-->通过page.getCanvas()获取一个Canvas对象-->在这个Canvas上进行 ...

  6. 一加6手机可以把PDF文件转Word吗?

         一加6手机大家都买了吧,手机中的PDF文件不好查看,我们可以转换Word,一加6手机可以把PDF文件转Word吗?答案是肯定的,很多人不信 1在手机上点击搜索该迅捷PDF阅读器,接着开始转换 ...

  7. 手机如何新建PDF文件?

    电脑上新建PDF文件很容易,手机如何新建PDF文件?手机跟电脑一样,都很容易新建PDF文件,如何新建?看完这篇文章你就会啦,跟着我来吧. 1你要在手机上点击搜索该迅捷PDF阅读器,下载安装至手机上,这 ...

  8. 小米8手机如何新建PDF文件?

    小米8手机很好吧,拍出的图片都很清晰,小米8手机如何新建PDF文件?我们可以利用图片生成,图片也能生成PDF文件,想知道的看过来. 1在手机上点击搜索该迅捷PDF阅读器,下载安装至手机上 2下载打开之 ...

  9. 手机里的PDF文件如何加密后再发送给别人呢?

    在日常工作或学习中,有一些比较重要的PDF文件需要发给其他人,又担心发送过程中丢失或泄露,需要给文件进行加密处理,那么有什么方法可以给手机PDF文件加密然后再发送给别人呢? 1.文件加密 手机下载和安 ...

最新文章

  1. 刀模图是什么意思_“吃鸡”光子公布神秘图,海岛图上有44个坐标,暗示信号值取消?...
  2. string.Join和Reverse的简单使用示例
  3. mysql cluster 7.1搭建
  4. /usr/bin/python^M: 解释器错误: 没有那个文件或目录
  5. 一张图全解析个性化邮件那么重要
  6. leetcode力扣105. 从前序与中序遍历序列构造二叉树
  7. Github 再现失误:部分用户密码明文暴漏
  8. EF Code First建库 增删改查
  9. 简述数学建模的过程_【数学建模的基本工作流程】作业帮
  10. ospf多区域实例配置
  11. windows server 2003 系统提权
  12. H83601D直插DIP千兆双口网络接口隔离滤波脉冲变压器
  13. Java 常见异常类
  14. Android 打造万能网络解析框架
  15. Excel数据的快速填充
  16. java表格标题栏_java使用poi自定义excel标题头并导出(springmvc+poi)
  17. Linux命令 - /etc/passwd文件详解
  18. python变量名可以用下划线开头吗_python以下划线开头的变量和函数的作用
  19. matlab常用指令
  20. MATLAB实验8:数据处理与多项式计算

热门文章

  1. javaSE基础重点知识点总结 持续更新
  2. 将xlsx文件转换成CSV文件方法
  3. python 视频加字幕_【小技巧】用Python给你的视频添加字幕
  4. 第一周前端web学习记录
  5. tex插入excel图表_Excel:以编程方式插入图表。
  6. python pcm 静音_使用静音检测分割音频文件
  7. 【Sharding-JDBC】 (五)整合mybatis-plus 解决分布式事务(基于XA)
  8. 【国庆献礼】浅谈国产数据库
  9. IEEE754详解(最详细简单有趣味的介绍)
  10. 【数模整理3】数据分析那些事儿——回归分析