图片自动更新成U盘里指定的图片

                                              图片自动更新成U盘里指定的图片

背景:

        UI上经常会有一些默认的图片,比如广告图片、加载网络图片时预显示的图片等。对于演示的软件,我们希望这些图片在不修改软件的情况下是可以变化的。如果不这样做,那就必须用新的图片重新编译软件,不灵活。

实现方法:

        1、显示图片时,先从data/data/..../files目录下查找指定的图片,有就显示它,没有就使用默认的图片。

        2、在u盘里创建一个目录,存放一些指定的png图片,盒子插上U盘后,就会把这些图片拷贝到files下指定的目录,然后刷新UI,图片就被更新成了新的图片。

具体实现:

        假如UI上有一个ImageView imgView,没有要求自动更新之前,我们的代码可能为:

        imgView.setImageResource(R.mipmap.ic_water_logo_neutral);

        这里的参数是资源id,编译时就生成好了。现在我们要用本地的PNG原始图片,显然就不能使用setImageResource了,我们必须使用setImageDrawable。

        1、把本地PNG图片转成Drawable。

    /**
     * 将USB里的PNG图片转化成Drawable对象
     * @param: 图片的路径
     * @return
     */
    public static Drawable externalStorageImageToDrawable(String path) {
        try {
            Drawable drawable = BitmapDrawable.createFromPath(path);
            return drawable;
        } catch (Exception e) {
            LogUtil.d("error msg:" + e.getMessage());
        }
        
        return null;
    }

        2、插上U盘后把图片拷贝到files目录下。

      插上U盘系统会发送Intent.ACTION_MEDIA_MOUNTED广播,我们在接收这个广播的地方把图片拷贝到files目录。

public void onReceive(Context context, Intent intent) {
        Uri uri = intent.getData();
        if (uri != null) {
            path = uri.getPath();
        }

        if ((intent.getAction().equals("com.droidvold.action.MEDIA_UNMOUNTED") || intent.getAction().equals("com.droidvold.action.MEDIA_EJECT")) && !path.equals("/dev/null")) {
            EventBus.getDefault().post(new UsbEvent(UsbEvent.UNMOUNTED, path));
        } else if (intent.getAction().equals(Intent.ACTION_MEDIA_MOUNTED) || intent.getAction().equals("com.droidvold.action.MEDIA_MOUNTED")) {
            copyLogosToFilesDir(context, path);
        }
    }
private void copyLogosToFilesDir(Context context, String usbPath) {
        String filesDir = context.getFilesDir().getAbsolutePath() + File.separator + "logos";

        String usbLogoDir = usbPath + File.separator + "logos";

        File usbFile = new File(usbLogoDir);
        if (usbFile.exists()) {
            FileUtils.copyFolder(usbLogoDir, filesDir);
        }
    }

 

 public static void copyFolder(String srcDir, String destDir) {
        try {
            Log.d(TAG, "copyFolder: srcDir = " + srcDir);
            Log.d(TAG, "copyFolder: destDir = " + destDir);

            File destFile = new File(destDir);
            if (destFile.exists()) {
                deleteFolderFile(destDir, true);
            }

            destFile.mkdir();

            File srcFile = new File(srcDir);
            String[] files = srcFile.list();
            File temp;

            for (String file : files) {
                Log.d(TAG, "copyFolder: file = " + file);
                if (srcDir.endsWith(File.separator)) {
                    temp = new File(srcDir + file);
                } else {
                    temp = new File(srcDir + File.separator + file);
                }

                if (temp.isDirectory()) {   //如果是子文件夹
                    copyFolder(srcDir + File.separator + file, destDir + File.separator + file);
                } else if (!temp.exists()) {
                    Log.e(TAG, "copyFolder: oldFile not exist.");
                    return;
                } else if (!temp.isFile()) {
                    Log.e(TAG, "copyFolder: oldFile not file.");
                    return;
                } else if (!temp.canRead()) {
                    Log.e(TAG, "copyFolder: oldFile cannot read.");
                    return;
                } else {
                    FileInputStream fileInputStream = new FileInputStream(temp);
                    FileOutputStream fileOutputStream = new FileOutputStream(destDir + File.separator + temp.getName());
                    byte[] buffer = new byte[1024];
                    int byteRead;

                    while ((byteRead = fileInputStream.read(buffer)) != -1) {
                        fileOutputStream.write(buffer, 0, byteRead);
                    }

                    fileInputStream.close();
                    fileOutputStream.flush();
                    fileOutputStream.close();
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "error msg: " + e.getMessage());
        } finally {

        }
    }
/**
     * 删除目录及目录下所有的文件
     * @param filePath
     * @param deleteThisPath
     */
    public static void deleteFolderFile(String filePath, boolean deleteThisPath) {
        Log.d("wujiang", "deleteFolderFile: call this fun");
        if (!TextUtils.isEmpty(filePath)) {
            try {
                File file = new File(filePath);
                if (file.isDirectory()) {
                    File files[] = file.listFiles();
                    for (int i = 0; i < files.length; i++) {
                        deleteFolderFile(files[i].getAbsolutePath(), true);
                    }
                }

                if (deleteThisPath) {
                    if (!file.isDirectory()) { //如果是文件,删除
                        file.delete();
                    } else { //目录
                        if (file.listFiles().length == 0) { //目录下没有文件或者目录,删除
                            file.delete();
                        }
                    }
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

3、更新imgView。

      新的图片已经拷贝到了files目录,我们就可以更新imgView了。根据前面的思路,设置imgView图片方法如下:

imgView.setImageDrawable(getDrawable());
public Drawable getDrawable() {
        Drawable drawable;

        String logosPath = BaseApplication.get().getFilesDir().getAbsolutePath() + File.separator + "logos";

        File file = new File(logosPath);
        if (file.exists()) {
            String imagePath = logosPath + File.separator + "customer_water_logo.png";
            File file1 = new File(imagePath);
            if (file1.exists()) {
                drawable = Utils.externalStorageImageToDrawable(imagePath);
            } else {
                drawable = BaseApplication.get().getResources().getDrawable(R.drawable.ic_water_logo_sei, null);
            }
        } else {
            drawable = BaseApplication.get().getResources().getDrawable(R.drawable.ic_water_logo_sei, null);
        }

        return drawable;
    }

改进 :

        如果我现在拔掉U盘再插上,imgView将会被再次更新,但是U盘的图片并没有改变,相当于做了无用功。怎么避免这种情况呢?就是说要做到图片没变的情况下,插上U盘不要去更新imgView。

        首先,怎么判断图片内容是否变化了呢?我们可以得到图片的MD5数据,比较U盘里的图片和files目录下图片的MD5值是否相等,相等就是同样的图片,反之是不同的图片。

        获取MD5的方法如下:

    /**
     * 得到指定目录文件的MD5值
     * @param :文件的绝对目录
     * @return
     * @throws IOException
     */
    public static String getMd5(String fname) throws IOException {
        MessageDigest mDigest = MessageDigest.getInstance("MD5");

        if (mDigest == null) {
            return "";
        }

        FileInputStream fins = new FileInputStream(fname);
        byte[] data = new byte[1024];

        int nread = 0;
        while ((nread = fins.read(data)) != -1) {
            mDigest.update(data, 0, nread);
        }

        byte[] md5data = mDigest.digest();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < md5data.length; i++) {
            sb.append(Integer.toString((md5data[i] & 0xff) + 0x100, 16).substring(1));
        }

        fins.close();

        return sb.toString();
    }

         然后我们改进copyLogosToFilesDir方法,该方法有返回值,返回true表示有把U盘的图片拷贝到files目录下,不需要更新UI;返回false表示没有进行拷贝动作,这个时候就不需要更新UI了。

    /**
     * 拷贝文件到 files 目录
     * @param context
     * @param usbPath
     * @return true: 拷贝了; false: 没有拷贝
     */
    private boolean copyLogosToFilesDir(Context context, String usbPath) {
        Map<String, String> usbPathFilesHashMap = new HashMap<>();
        Map<String, String> filesPathFilesHashMap = new HashMap<>();

        String filesDir = context.getFilesDir().getAbsolutePath() + File.separator + "logos";

        String usbLogoDir = usbPath + File.separator + "logos";

        usbPathFilesHashMap.clear();
        filesPathFilesHashMap.clear();

        try {
            File usbFile = new File(usbLogoDir);

            if (usbFile.exists()) {
                Log.d("wujiang", "copyLogosToFilesDir: usbFile exists");

                String[] usbPathFiles = usbFile.list();
                File usb_temp;

                //得到U盘里所有图片的MD5值, 以文件名作为key, MD5值为value
                for (String file : usbPathFiles) {
                    usb_temp = new File(usbLogoDir + File.separator + file);
                    String md5 = Md5Helper.getMd5(usb_temp.getAbsolutePath());
                    usbPathFilesHashMap.put(usb_temp.getName(), md5);
                }
            } else {
                return false;
            }

            File filesFile = new File(filesDir);
            if (filesFile.exists()) {
                Log.d("wujiang", "copyLogosToFilesDir: filesFile exists");

                String[] filesPathFiles = filesFile.list();
                File files_temp;

                //得到files目录下所有图片的MD5值, 以文件名作为key, MD5值为value
                for (String file : filesPathFiles) {
                    files_temp = new File(filesDir + File.separator + file);
                    String md5 = Md5Helper.getMd5(files_temp.getAbsolutePath());

                    filesPathFilesHashMap.put(files_temp.getName(), md5);
                }

                //查看files里的图片在usb里有无完全相同的图片
                for (Map.Entry<String, String> entry : filesPathFilesHashMap.entrySet()) {
                    String fileName = entry.getKey();
                    String md5Value = entry.getValue();

                    String usbMd5Value = usbPathFilesHashMap.get(fileName);

                    if (!md5Value.equals(usbMd5Value)) {
                        FileUtils.copyFolder(usbLogoDir, filesDir);
                        return true;
                    }
                }
            } else {
                FileUtils.copyFolder(usbLogoDir, filesDir);
                return true;
            }
        } catch (Exception e) {
            Log.d("wujiang", "copyLogosToFilesDir: error = " + e.getMessage());
        }

        Log.d("wujiang", "copyLogosToFilesDir: no need copy usb files to files path");
        return false;
    }

                                                         THE        END

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值