Andriod全盘扫描指定文件并动态显示到列表上

这两天做的一个炒菜机的项目,其中有个需求是要从本地导入菜单。其实这个菜单就是个txt文件.
那么,需求就来了,我需要把本机的txt文件都扫描出来,并且动态的显示到列表上,再对选择的txt文件进行筛选,判断是不是菜单,是的话,存到本地的数据库。
好了,基本的步骤就出来了。
下面,我们来实现一下扫描并动态显示到列表上。所谓的动态显示就是我每扫描出一个txt就添加到列表上。类似于这样。

这里写图片描述

如上图所示,需要注意以下几点:
1)扫描是耗时操作,要放到子线程中执行,在主线程中去更新ui
2)我们可以通过监听扫描线程的状态来判断扫描是否完成。
3)扫描完成后注意要及时释放取消定时任务

项目中用了两个开源库
BaseRecyclerViewAdapterHelper
butterknife

下面我们来看看代码:

首先记得要给权限

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
package com.yzq.scanlocaldemo;

import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.AppCompatTextView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;

import java.io.File;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import butterknife.BindView;
import butterknife.ButterKnife;

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.toolbar)
    Toolbar toolbar;
    @BindView(R.id.scanTv)
    AppCompatTextView scanTv;
    @BindView(R.id.scanProgressbar)
    ProgressBar scanProgressbar;
    @BindView(R.id.recy)
    RecyclerView recy;


    private ArrayList<File> scanedFiles = new ArrayList<>();

    /*扫描线程*/
    private Thread scanThread;
    /*定时器  用于定时检测扫描线程的状态*/
    private Timer scanTimer;

    /*检测扫描线程的任务*/
    private TimerTask scanTask;
    private FileAdapter adapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        initWidget();

        startScan();
    }


    /*初始化控件*/
    private void initWidget() {

        recy.setLayoutManager(new LinearLayoutManager(this));

        toolbar.setTitle("扫描文件");
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);


        adapter = new FileAdapter(R.layout.scan_file_list_item, scanedFiles);
        recy.setAdapter(adapter);

    }

    /*开始扫描*/
    private void startScan() {


        /*根目录*/
        final String rootPath = Environment.getExternalStorageDirectory().getAbsolutePath();


        /*要扫描的文件后缀名*/
        final String endFilter = ".txt";

        final File dir = new File(rootPath);


        scanThread = new Thread(new Runnable() {
            @Override
            public void run() {
                scanFile(dir, endFilter);
            }
        });


        /*判断扫描是否完成 其实就是个定时任务 时间可以自己设置  每2s获取一下扫描线程的状态  如果线程状态为结束就说明扫描完成*/
        scanTimer = new Timer();
        scanTask = new TimerTask() {
            @Override
            public void run() {
                Log.i("线程状态",scanThread.getState().toString());

                if (scanThread.getState() == Thread.State.TERMINATED) {
                    /*说明扫描线程结束 扫描完成  更新ui*/
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Log.i("线程结束","扫描完成");
                            scanTv.setText("扫描完成,共扫描出" + scanedFiles.size() + "个txt文件");
                            scanProgressbar.setVisibility(View.GONE);
                            cancelTask();

                        }
                    });
                }
            }
        };

        scanTimer.schedule(scanTask, 0,1000);

        /*开始扫描*/
        scanThread.start();


    }




    /*扫描*/
    private void scanFile(File dir, String endFilter) {

        File[] files = dir.listFiles();

        if (files != null && files.length > 0) {

            for (final File file : files) {
                if (file.getName().toUpperCase().endsWith(endFilter.toUpperCase())) {
                    /*是符合后缀名的文件  添加到列表中*/


                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            /*刷新界面  要在主线程运行*/
                            adapter.addData(file);
                            scanTv.setText("已扫描出" + scanedFiles.size() + "个txt文件");

                        }
                    });
                }
                /*是目录*/
                if (file.isDirectory()) {
                    /*递归扫描*/
                    scanFile(file, endFilter);
                }
            }

        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        cancelTask();

    }

    private void cancelTask() {

        Log.i("cancelTask","结束任务");
        if (scanTask!=null){
            scanTask.cancel();
        }

        if (scanTimer!=null){
         scanTimer.purge();
         scanTimer.cancel();;
        }
    }
}


ok,大功告成。下面是demo,希望能对你有帮助。


demo


如果你觉得本文对你有帮助,麻烦动动手指顶一下,算是对本文的一个认可,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!

©️2020 CSDN 皮肤主题: 书香水墨 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值