Android sd卡状态监听,文件搜索,媒体文件刷新

整理一下关于sd卡相关知识点,主要包括sd卡状态监听,sd卡文件搜索,sd卡媒体数据库(系统支持媒体类型)刷新模块:


一:sd卡状态进行监听

有时程序进行外部数据读取和写入时,为防止异常发生需要对sd卡状态进行监听,对于sd卡的状态我们可以采用注册广播来实现

下面是文档中一个经典例子;

//监听sdcard状态广播
   BroadcastReceiver mExternalStorageReceiver;
   //sdcard可用状态
   boolean mExternalStorageAvailable = false;
   //sdcard可写状态
   boolean mExternalStorageWriteable = false;

   void updateExternalStorageState() {
	   //获取sdcard卡状态
       String state = Environment.getExternalStorageState();
       if (Environment.MEDIA_MOUNTED.equals(state)) {
           mExternalStorageAvailable = mExternalStorageWriteable = true;
       } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
           mExternalStorageAvailable = true;
           mExternalStorageWriteable = false;
       } else {
           mExternalStorageAvailable = mExternalStorageWriteable = false;
       }
       
   }
   //开始监听
   void startWatchingExternalStorage() {
       mExternalStorageReceiver = new BroadcastReceiver() {
           @Override
           public void onReceive(Context context, Intent intent) {
               Log.i("test", "Storage: " + intent.getData());
               updateExternalStorageState();
           }
       };
       IntentFilter filter = new IntentFilter();
       filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
       filter.addAction(Intent.ACTION_MEDIA_REMOVED);
       registerReceiver(mExternalStorageReceiver, filter);
       updateExternalStorageState();
   }
   //停止监听
   void stopWatchingExternalStorage() {
       unregisterReceiver(mExternalStorageReceiver);
   }

二:sdcard下搜索某一类型(通常是后缀名相同)文件,或是指定文件名的查找功能

(1)搜索指定文件

   public String searchFile(String filename){  
      
            String res="";  
            File[] files=new File("/sdcard").listFiles();  
            for(File f:files){  
                if(f.isDirectory())  
                    searchFile(f.getName());  
                else  
                if(f.getName().indexOf(filename)>=0)  
                    res+=f.getPath()+"\n";  
            }  
            if(res.equals(""))  
                res="file can't find!";  
            return res;  
  }  


(2)指定相同后缀名称文件类型

private List<String> files = new ArrayList<String>();  
      
    class FindFilter implements FilenameFilter {  
        public boolean accept(File dir, String name) {  
            return (name.endsWith(".txt"));  
        }  
    }  
      
    public void updateList() {  
         File home = new File("/sdcard/");  
      if (home.listFiles( new FindFilter()).length > 0) {  
          for (File file : home.listFiles( new FindFilter())) {  
           files.add(file.getName());  
  }  


三:媒体数据库的刷新,

当android的系统启动的时候,系统会自动扫描sdcard内的文件,并把获得的媒体文件信息保存在一个系统媒体数据库中,
程序想要访问多媒体文件,就可以直接访问媒体数据库中即可,而用直接去sdcard中取。
但是,如果系统在不重新启动情况下,媒体数据库信息是不会更新的,这里举个例子,当应用程序保存一张图片到本地后(已成功),
但打开系统图片库查看时候,你会发现图片库内并没有你刚刚保存的那张图片,原因就在于系统媒体库没有及时更新,这时就需要手动刷新文件系统了



方式一:发送一广播信息通知系统进行文件刷新

 private void scanSdCard(){  
            IntentFilter intentfilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED);  
            intentfilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);  
            intentfilter.addDataScheme("file");          
            registerReceiver(scanSdReceiver, intentfilter);  
            Intent intent = new Intent();  
            intent.setAction(Intent.ACTION_MEDIA_MOUNTED);  
            intent.setData(Uri.parse("file://" + Environment.getExternalStorageDirectory().getAbsolutePath()));  
            sendBroadcast(intent);  
              
        }  
          
        private BroadcastReceiver scanSdReceiver = new BroadcastReceiver(){  
         
            private AlertDialog.Builder builder;  
            private AlertDialog ad;  
            @Override  
            public void onReceive(Context context, Intent intent) {  
                String action = intent.getAction();  
            
                if(Intent.ACTION_MEDIA_SCANNER_STARTED.equals(action)){  
                    builder = new AlertDialog.Builder(context);  
                    builder.setMessage("正在扫描sdcard...");  
                    ad = builder.create();  
                    ad.show();  
                //    adapter.notifyDataSetChanged();  
                }else if(Intent.ACTION_MEDIA_SCANNER_FINISHED.equals(action)){  
                    ad.cancel();//重新获取文件数据信息  
                    Toast.makeText(context, "扫描完毕", Toast.LENGTH_SHORT).show();  
            }     
        }  
    };  

或者

public void fileScan(File file){    
        Uri data =  Uri.parse("file://"+ Environment.getExternalStorageDirectory())    
  sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, data));    
    }   


    void insertMeadia(ContentValues values){  
             Uri uri = getContentResolver().insert( MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);   
             sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));  
        }  


刷新所有系统文件,效率可能不高,高效方法是只刷新变化的文件

方式二:指定特定文件操作

    File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);  
           File file = new File(path, "DemoPicture.jpg");  
      
           try {  
               
               InputStream is = getResources().openRawResource(R.drawable.balloons);  
               OutputStream os = new FileOutputStream(file);  
               byte[] data = new byte[is.available()];  
               is.read(data);  
               os.write(data);  
               is.close();  
               os.close();  
      
               // Tell the media scanner about the new file so that it is  
               // immediately available to the user.  
               MediaScannerConnection.scanFile(this,  
                       new String[] { file.toString() }, null,  
                       new MediaScannerConnection.OnScanCompletedListener() {  
                   public void onScanCompleted(String path, Uri uri) {  
                       Log.i("ExternalStorage", "Scanned " + path + ":");  
                       Log.i("ExternalStorage", "-> uri=" + uri);  
                   }  
               });  
           } catch (IOException e) {  
               // Unable to create file, likely because external storage is  
               // not currently mounted.  
               Log.w("ExternalStorage", "Error writing " + file, e);  
           }  


文件大小,字符串展示:

public static String getReadableFileSize(int size) {
        final int BYTES_IN_KILOBYTES = 1024;
        final DecimalFormat dec = new DecimalFormat("###.#");
        final String KILOBYTES = " KB";
        final String MEGABYTES = " MB";
        final String GIGABYTES = " GB";
        float fileSize = 0;
        String suffix = KILOBYTES;

        if (size > BYTES_IN_KILOBYTES) {
            fileSize = size / BYTES_IN_KILOBYTES;
            if (fileSize > BYTES_IN_KILOBYTES) {
                fileSize = fileSize / BYTES_IN_KILOBYTES;
                if (fileSize > BYTES_IN_KILOBYTES) {
                    fileSize = fileSize / BYTES_IN_KILOBYTES;
                    suffix = GIGABYTES;
                } else {
                    suffix = MEGABYTES;
                }
            }
        }
        return String.valueOf(dec.format(fileSize) + suffix);
    }

获取多个sdcard:

    fun getSdcardList(): List<File> {
        val sdFile = File("/storage/")//or /mnt/
//        val result = ArrayList<File>()
//        val sdFile = Environment.getExternalStorageDirectory()
        val files = sdFile.listFiles()
        val result = files.toList()
        return result
    }



原文地址:https://www.cnblogs.com/happyxiaoyu02/p/6818975.html