美文网首页 Android知识进阶(遥远的重头开始)
Android-外接U盘实现数据读取操作(转载实践)

Android-外接U盘实现数据读取操作(转载实践)

作者: MonkeyLei | 来源:发表于2019-07-12 09:40 被阅读7次

    本来就没打算弄这个,之前老东家突然有个插入U盘到Android设备,然后提示安装apk的需求。有两点:

    1. 系统是自己开发的,可以检测到U盘后自动识别自家应用,进而进行提示安装或者直接默认安装(仅限自己系统)

    2. 系统不是自己的,开发一个小应用,然后启动该应用,检测U盘插入,然后读取规定好的文件(可以校验下md5或者签名), 然后拷贝到设备,然后提示进行安装(只能是提示而已,不是自己的系统肯定不能进行默认安装,没那个权限)

    小白初步分析后进行了说明,如果要做就只能开个一个小应用了。好吧。然后快速找一堆资料,尽快尝试下,也没那么多时间去看官方,研究具体使用方式了啦。。。所以这里就直接贴代码,把网上的可行,不可行等情况都尝试下...

    然后综合出一个可行的。。

    权限:

          <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

    第三方库:

         compile 'com.github.mjdev:libaums:0.5.5'
    

    UsbActivity.java

    package com.example.lieyun_android;
    
    import android.content.IntentFilter;
    import android.hardware.usb.UsbManager;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    
    import com.example.lieyun_android.myapplication.R;
    
    public class UsbActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_usb);
    
            ///< @a 这种不好使
            //        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);//插
            //        intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);//拔
            //        intentFilter.addAction(Intent.ACTION_MEDIA_REMOVED);  //完全拔出
            //        intentFilter.addDataScheme("file");//没有这行监听不起作用
            //        registerReceiver(mSdcardReceiver, intentFilter,
            //                "android.permission.READ_EXTERNAL_STORAGE",null);
    
            ///< 监听otg插入 拔出
            IntentFilter usbDeviceStateFilter = new IntentFilter();
            usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
            usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
            registerReceiver(usbBroadcastReceiver, usbDeviceStateFilter);
            //注册监听自定义广播
            IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
            registerReceiver(usbBroadcastReceiver, filter);
        }
        private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
    
        private USBBroadcastReceiver usbBroadcastReceiver = new USBBroadcastReceiver();
    
        ///< @a 这种不好使
        //    private BroadcastReceiver mSdcardReceiver = new BroadcastReceiver() {
        //        @Override
        //        public void onReceive(Context context, Intent intent) {
        //            if (intent.getAction().equals(Intent.ACTION_MEDIA_UNMOUNTED)) {
        //                Toast.makeText(context, "插入", Toast.LENGTH_SHORT).show();
        //            } else if (intent.getAction().equals(Intent.ACTION_MEDIA_REMOVED)) {
        //                Toast.makeText(context, "remove ACTION_MEDIA_REMOVED", Toast.LENGTH_SHORT).show();
        //            }
        //        }
        //    };
    }
    
    

    USBBroadcastReceiver.java

    package com.example.lieyun_android;
    
    import android.app.PendingIntent;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.hardware.usb.UsbDevice;
    import android.hardware.usb.UsbManager;
    import android.util.Log;
    import android.widget.Toast;
    
    import com.github.mjdev.libaums.UsbMassStorageDevice;
    import com.github.mjdev.libaums.fs.FileSystem;
    import com.github.mjdev.libaums.fs.UsbFile;
    import com.github.mjdev.libaums.fs.UsbFileInputStream;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    
    /*
    *@Description: U盘检测广播
    *@Author: hl
    *@Time: 2018/9/20 10:11
    */
    public class USBBroadcastReceiver extends BroadcastReceiver {
        private static final String TAG = "USBBroadcastReceiver";
    
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            switch (action) {
                case ACTION_USB_PERMISSION://接受到自定义广播
                    UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    //允许权限申请
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        if (usbDevice != null) {
                            //用户已授权,可以进行读取操作
                            readDevice(context, getUsbMass(usbDevice));
                        } else {
                            Toast.makeText(context, "没有插入U盘", Toast.LENGTH_LONG).show();
                        }
                    } else {
                        Toast.makeText(context, "未获取到U盘权限", Toast.LENGTH_LONG).show();
                    }
                    break;
                case UsbManager.ACTION_USB_DEVICE_ATTACHED://接收到U盘设备插入广播
                    UsbDevice device_add = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (device_add != null) {
                        //接收到U盘插入广播,尝试读取U盘设备数据
                        redUDiskDevsList(context);
                    }
                    break;
                case UsbManager.ACTION_USB_DEVICE_DETACHED://接收到U盘设设备拔出广播
                    Toast.makeText(context, "拔出", Toast.LENGTH_LONG).show();
                    break;
            }
    
            ///< 另外一种乱七八糟拼凑判断U盘插入的方法,不是特别好用 这个地方本来是这样:intent.getExtras().getBoolean("connected") ,但是我发现需要修改为host_connected
            ///< 这种判断方式肯定不如上面的UsbManager.ACTION_USB_DEVICE_ATTACHED
            //        if (intent.getAction().equals(ACTION_USB_PERMISSION)) {
            //            UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            //            //允许权限申请
            //            if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
            //                if (usbDevice != null) {
            //                    //用户已授权,可以进行读取操作
            //                    readDevice(context, getUsbMass(usbDevice));
            //                } else {
            //                    Toast.makeText(context, "没有插入U盘", Toast.LENGTH_LONG).show();
            //                }
            //            } else {
            //                Toast.makeText(context, "未获取到U盘权限", Toast.LENGTH_LONG).show();
            //            }
            //        } else if (intent.getAction().equals("android.hardware.usb.action.USB_STATE")) {
            //            Toast.makeText(context, "action=" + intent.getAction(), Toast.LENGTH_LONG).show();
            //            Bundle bundle = intent.getExtras();
            //            for (String key : bundle.keySet()) {
            //                Toast.makeText(context, "Key=" + key + " + content=" + bundle.get(key), Toast.LENGTH_LONG).show();
            //            }
            //            if (intent.getExtras().getBoolean("host_connected")) {
            //                // usb 插入
            //                Toast.makeText(context, "插入", Toast.LENGTH_LONG).show();
            //
            //                UsbDevice device_add = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            //                Toast.makeText(context, "device_add=" + device_add, Toast.LENGTH_LONG).show();
            //
            //                if (device_add != null) {
            //                    //接收到U盘插入广播,尝试读取U盘设备数据
            //                    redUDiskDevsList(context);
            //               }
    
            //                UsbMassStorageDevice[] devices =
            //                        UsbMassStorageDevice.getMassStorageDevices(context /* Context or Activity */);
            //                Toast.makeText(context, "devices.length=" + devices.length, Toast.LENGTH_LONG).show();
            //                for (UsbMassStorageDevice device : devices) {
            //
            //                    // before interacting with a device you  need to call init()!
            //                    try {
            //                        device.init();
            //                        // Only uses the first partition on the device
            //                        FileSystem currentFs = device.getPartitions().get(0).getFileSystem();
            //                        Log.d(TAG, "Capacity: " + currentFs.getCapacity());
            //                        Toast.makeText(context, "Capacity: " + currentFs.getCapacity(), Toast.LENGTH_LONG).show();
            //                        Log.d(TAG, "Occupied Space: " + currentFs.getOccupiedSpace());
            //                        Toast.makeText(context, "Occupied Space: " + currentFs.getOccupiedSpace(), Toast.LENGTH_LONG).show();
            //                        Log.d(TAG, "Free Space: " + currentFs.getFreeSpace());
            //                        Toast.makeText(context, "Free Space: " + currentFs.getFreeSpace(), Toast.LENGTH_LONG).show();
            //                        Log.d(TAG, "Chunk size: " + currentFs.getChunkSize());
            //                        Toast.makeText(context, "Chunk size: " + currentFs.getChunkSize(), Toast.LENGTH_LONG).show();
            //                    } catch (IOException e) {
            //                        //e.printStackTrace();
            //                        Toast.makeText(context, "IOException" + e.getMessage(), Toast.LENGTH_LONG).show();
            //                    }
            //                }
            //            } else {
            //                //   usb 拔出
            //                Toast.makeText(context, "拔出", Toast.LENGTH_LONG).show();
            //            }
            //        }
        }
    
        //当前处接U盘列表
        private UsbMassStorageDevice[] storageDevices;
        //自定义U盘读写权限
        private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
        //当前U盘所在文件目录
        private UsbFile cFolder;
        private final static String U_DISK_FILE_NAME = "u_disk.txt";
    
        /**
         * @description U盘设备读取
         * @author ldm
         * @time 2017/9/1 17:20
         */
        private void redUDiskDevsList(Context context) {
            //设备管理器
            UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
            //获取U盘存储设备
            storageDevices = UsbMassStorageDevice.getMassStorageDevices(context);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
                    new Intent(ACTION_USB_PERMISSION), 0);
            //一般手机只有1个OTG插口
            for (UsbMassStorageDevice device : storageDevices) {
                //读取设备是否有权限
                if (usbManager.hasPermission(device.getUsbDevice())) {
                    readDevice(context, device);
                } else {
                    //没有权限,进行申请
                    usbManager.requestPermission(device.getUsbDevice(), pendingIntent);
                }
            }
            if (storageDevices.length == 0) {
                Toast.makeText(context, "请插入可用的U盘", Toast.LENGTH_LONG).show();
            }
        }
    
        /**
         * 获取对应的U盘设备
         * @param usbDevice
         * @return
         */
        private UsbMassStorageDevice getUsbMass(UsbDevice usbDevice) {
            for (UsbMassStorageDevice device : storageDevices) {
                if (usbDevice.equals(device.getUsbDevice())) {
                    return device;
                }
            }
            return null;
        }
    
        /**
         * 读取U盘信息
         * @param context
         * @param device
         */
        private void readDevice(Context context, UsbMassStorageDevice device) {
            try {
                device.init();
                // Only uses the first partition on the device
                FileSystem currentFs = device.getPartitions().get(0).getFileSystem();
                //Toast.makeText(context, "getRootDirectory: " + currentFs.getRootDirectory().getName(), Toast.LENGTH_LONG).show();
                Log.d(TAG, "Capacity: " + currentFs.getCapacity());
                //Toast.makeText(context, "Capacity: " + currentFs.getCapacity(), Toast.LENGTH_LONG).show();
                Log.d(TAG, "Occupied Space: " + currentFs.getOccupiedSpace());
                //Toast.makeText(context, "Occupied Space: " + currentFs.getOccupiedSpace(), Toast.LENGTH_LONG).show();
                Log.d(TAG, "Free Space: " + currentFs.getFreeSpace());
                //Toast.makeText(context, "Free Space: " + currentFs.getFreeSpace(), Toast.LENGTH_LONG).show();
                Log.d(TAG, "Chunk size: " + currentFs.getChunkSize());
                //Toast.makeText(context, "Chunk size: " + currentFs.getChunkSize(), Toast.LENGTH_LONG).show();
                //设置当前文件对象为根目录
                cFolder = currentFs.getRootDirectory();
                ///< 读取当前目录下的文件
                readFromUDisk(context);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 获取U盘文件信息
         * @param context
         */
        private void readFromUDisk(Context context) {
            UsbFile[] usbFiles = new UsbFile[0];
            try {
                usbFiles = cFolder.listFiles();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (null != usbFiles && usbFiles.length > 0) {
                for (UsbFile usbFile : usbFiles) {
                    Toast.makeText(context, "usbFile.getName(): " + usbFile.getName(), Toast.LENGTH_LONG).show();
                    if (usbFile.getName().equals(U_DISK_FILE_NAME)) {
                        readTxtFromUDisk(usbFile);
                    }
                }
            }
        }
    
        /**
         * @description 保存数据到U盘,目前是保存到根目录的
         * @author ldm
         * @time 2017/9/1 17:17
         */
        private void saveText2UDisk(Context context, String content) {
            //项目中也把文件保存在了SD卡,其实可以直接把文本读取到U盘指定文件
            File file = null;///< FileUtil.getSaveFile(context.getPackageName() + File.separator + FileUtil.DEFAULT_BIN_DIR, U_DISK_FILE_NAME);
            try {
                FileWriter fw = new FileWriter(file);
                fw.write(content);
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (null != cFolder) {
                //FileUtil.saveSDFile2OTG(file, cFolder);
            }
        }
    
        /**
         * 读取U盘文件的内容
         * @param usbFile
         */
        private void readTxtFromUDisk(UsbFile usbFile) {
            UsbFile descFile = usbFile;
            //读取文件内容
            InputStream is = new UsbFileInputStream(descFile);
            //读取秘钥中的数据进行匹配
            StringBuilder sb = new StringBuilder();
            BufferedReader bufferedReader = null;
            try {
                bufferedReader = new BufferedReader(new InputStreamReader(is));
                String read;
                while ((read = bufferedReader.readLine()) != null) {
                    sb.append(read);
                }
                //            Message msg = mHandler.obtainMessage();
                //            msg.what = 101;
                //            msg.obj = read;
                //            mHandler.sendMessage(msg);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bufferedReader != null) {
                        bufferedReader.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    以上拿过去就可以用了。可以读取U盘所有的文件信息,然后你就可以进行相关文件操作了哈。记得给动态给读写权限...(现今存储需要动态给了,就算不是外卡也需要provider了).......里面有些尝试无法可行(最新xxx米系统上反正不行)...

    最后感谢网友.. https://blog.csdn.net/true100/article/details/77775700,记得给人家点赞转发...

    有空再看这块: https://blog.csdn.net/srw11/article/details/39154053

    相关文章

      网友评论

        本文标题:Android-外接U盘实现数据读取操作(转载实践)

        本文链接:https://www.haomeiwen.com/subject/xrwskctx.html