• 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
        }
    



  • 相关阅读:
    CF1354D
    Keiichi Tsuchiya the Drift King
    二分查找[搬运链接]
    树状数组的修炼 疑惑篇
    离线
    关于二维差分和二维前缀和的注意事项
    QWORD PTR [rcx],0x0 ??
    字典树
    数据库题
    需要掌握的技能汇总
  • 原文地址:https://www.cnblogs.com/happyxiaoyu02/p/6818975.html
Copyright © 2020-2023  润新知