二维码:问题和资料

问题1:将二维码图片从手机或SD卡上删除后,在媒体库中仍然可以看到被删除图片的预览缩略图。

参考:Android: remove an image from sd card

http://stackoverflow.com/questions/6707197/android-remove-an-image-from-sd-card


问题2:

(new File(filePath)).deleteOnExit();

我一直以为deleteOnExit()是在文件存在的时候删除。大错特错,源于我对一直把这个方法当作deleteonExist(),仅仅差一个字母。终于在今天被我发现,以后不会再犯这个低级错误了吧。

正确删除文件应该这么实现:

File file = new File(filePath);
if(file.exists())
    file.delete();


代码片段:保存图片到文件系统中

private String getSaveDirectory() {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
    if(!sdCardIsExist()) {
        return context.getFilesDir().getPath() + "/" + "user";
    } else {
        return ImageManager.USER_INFO_DIRECTORY;
    }
}
private void deleteMyFile(String directory, String filename) {
    Logger.v(TAG, "invoke deleteMyFile");
    File file = new File(directory, filename);
    if(file.exists()) {
        Logger.v(TAG, "File is exist. Begin to delete it. Its path is >> " + file.getPath());
        if(file.delete()) {
            Logger.v(TAG, "Delete success.");
        } else {
            Logger.v(TAG, "Delete fail.");
        }
    } else {
        Logger.v(TAG, "File is not exist.");
    }
}
private void saveBitmapToFile(Bitmap source, String directory, String filename) {
    Logger.v(TAG, "invoke saveBitmapToFile");
    OutputStream outputStream = null;
    try {
        File dir = new File(directory);
        if (!dir.exists()) dir.mkdirs();
        File file = new File(directory, filename);
        Logger.v(TAG, "Begin to save bitmap to file which its path is >> " + file.getPath());
        outputStream = new FileOutputStream(file);
        if (source != null) {
            source.compress(CompressFormat.JPEG, 100, outputStream);
        }
    } catch (FileNotFoundException ex) {
        Log.w(TAG, ex);
    } finally {
        StreamUtil.Release(outputStream);
    }
}
private void saveZxingImage() {
    Logger.v(TAG, "invoke saveZxingImage");
    if(source == null) return;
    String filename = "user("+user.getUsername()+").png";
    String directory = getSaveDirectory();
    Logger.v(TAG, "sdCardIsExist >> " + sdCardIsExist());
    // 删除文件
    deleteMyFile(directory, filename);
    // 保存文件
    saveBitmapToFile(source, directory, filename);
    // 通知媒体库刷新
    sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
            Uri.parse("file://" + Environment.getExternalStorageDirectory())));
    UIUtils.showToast(context, "保存二维码图片成功");
}

其中常量USER_INFO_DIRECTORY为:

public static final String USER_INFO_DIRECTORY =
        Environment.getExternalStorageDirectory().toString() + "/ivideo/user";

判断SD卡是否存在代码实现

private boolean sdCardIsExist() {
    return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}

代码片段:从媒体库中获取并解析二维码图片

if (requestCode == SELECT_ZXING_PICTURE) {
    Logger.v(TAG, "return back from media store.");
    if (resultCode == RESULT_OK) {
        try {
            Uri dataUri = data.getData();
            Logger.v(TAG, "open input stream from data which its URI is >> " + dataUri.toString());
            InputStream istream = getContentResolver().openInputStream(dataUri);
            if (zxingBitmap != null) {
                Logger.v(TAG, "zxing bitmap is not null, begin to recycle it.");
                zxingBitmap.recycle();
            } else {
                Logger.v(TAG, "zxing bitmap is null.");
            }
            Logger.v(TAG, "decode stream from input stream.");
            zxingBitmap = BitmapFactory.decodeStream(istream);
            Logger.v(TAG, "get user infomation from zxing bitmap.");
            String zxingInfo = getUserFromBitmap(zxingBitmap);
            Logger.v(TAG, "login with ukey >> " + zxingInfo);
            loginFromZxingInfo(zxingInfo);
        } catch (FileNotFoundException e) {
            Logger.e(TAG, "caught exception about file not found.");
            Logger.e(TAG, e);
            showToast("文件未找到");
        } catch (OutOfMemoryError err) {
            Logger.e(TAG, "caught error about out of memory.");
            Logger.e(TAG, err);
            showToast("解析出错");
        } catch (NotFoundException e) {
            Logger.e(TAG, "caught exception about zxing not found.");
            Logger.e(TAG, e);
        } catch (ChecksumException e) {
            Logger.e(TAG, "caught exception about zxing check sum.");
            Logger.e(TAG, e);
        } catch (FormatException e) {
            Logger.e(TAG, "caught exception about zxing format.");
            Logger.e(TAG, e);
        }
        if (zxingBitmap != null) {
            Logger.v(TAG, "zxing bitmap is not null, begin to recycle it.");
            zxingBitmap.recycle();
            zxingBitmap = null;
        }
    }
    return;
}

问题:在手机没有关机的情况下,将SD卡从手机上拿走,然后也不重启手机。程序中判断SD卡是否存在,结果会显示SD卡还存在。于是导致:保存二维码图片不成功。此时重启手机,再打开程序,程序中片段SD卡是否存在,结果就会显示SD卡不存在。


问题:当SD卡不存在时,程序将二维码图片保存到手机上,再打开媒体库,结果:媒体库无法显示出手机上的图片。可能原因:保存二维码之后,仅仅通知重新扫描SD卡,没有去扫描手机。


问题:当SD卡不存在时,将二维码图片保存到手机内存卡上目录为data/data/xxx/files/user/xxx.png,然后调用chmod命令修改文件的权限,经过验证修改权限的操作已经执行成功,在File Explorer中可以看到此文件的权限是-rwxrwxrwx即777权限。但是,在手机的媒体库应用中无法预览到此png文件。


问题:当SD卡在开机状态下卸载或者挂载,并且手机没有重启,媒体库不做任何监听。所以会出现以下情况:刚开始手机没有SD卡,在开机状态下挂载上SD卡后,打开媒体库应用,媒体库应用仍然显示SD卡不存在或者SD卡不可用。


问题:检测SD卡是否可用最理想办法。使用Environment.getExternalStorageState()和Environment.getExternalStorageDirectory().canWrite()等方法检测不出实际效果。当SD卡拔掉后,canWrite()仍然返回true,且getExternalStorageState()返回值仍然是Environment.MEDIA_MOUNTED。最理想的办法是在SD上创建一个文件,如果文件能够创建成功,那就表示SD卡可用,反之不可用。

代码片段:检测SD卡是否可用

private boolean sdCardIsAvailable() {
    String fileName = new Date().getTime() + ".test";
    String filePath =  Environment.getExternalStorageDirectory() + "/" + fileName;
    File file = new File(filePath);
    try {
        if(file.createNewFile()) {
            Logger.v(TAG, "create new file success. filepath >> " + filePath);
        } else {
            Logger.v(TAG, "create new file fail. filepath >> " + filePath);
            return false;
        }
        if(file.exists()) {
            if(file.delete()) {
                Logger.v(TAG, "delete file success. filepath >> " + filePath);
            } else {
                Logger.v(TAG, "delete file fail. filepath >> " + filePath);
                return false;
            }
        }
    } catch (IOException e) {
        Logger.v(TAG, "caught " + e.getClass().getName() + " >> " + e.getMessage());
        return false;
    }
    return true;
}

代码片段:在程序中调用上述方法来检测SD卡是否可用

if(!sdCardIsAvailable()) {
    UIUtils.showToast(context, "SD卡不可用");
    Logger.v(TAG, "sd card is unavailable.");
    return;
} else {
    Logger.v(TAG, "sd card is available.");
}

调试日志:当SD卡不可用时打印出sd card is unavaliable.

11-15 18:21:32.019: V/SaveZxingActivity(15205): caught java.io.IOException >> I/O error
11-15 18:21:32.029: V/SaveZxingActivity(15205): sd card is unavailable.


参考资料:

1. android中对SD卡挂载和卸载的监听

http://blog.csdn.net/guoying_/article/details/6618277

2.android 监听SDCard安装和卸载的代码片段(测试通过)

http://www.cnblogs.com/error404/archive/2011/09/08/2170998.html

3. android sd卡状态、路径、可用空间,内存

http://blog.csdn.net/ureygo/article/details/7064030


你可能感兴趣的:(android,资料,二维码,缩略图)