草庐IT

android - ExifInterface 构造函数抛出 IOExxception

coder 2023-12-15 原文

在尝试使用文件路径初始化 exif 接口(interface)实例时,我无法找出 ExifInterface 构造函数抛出的异常。

已更新 请按要求查看下面的详细代码。

文件下载功能

public void downloadAndSaveFile(String url, String directoryId, String fileName) {
    HttpURLConnection conn = null;
    try {
        Log.d(TAG, "DownloadFileTask url : " + url);
        conn = getGETConnection(url);
        conn.setRequestProperty("Accept", "application/json");
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestProperty("Authorization", "Bearer " + MY_AUTH_TOKEN);
        conn.connect();
        File file = new File(FileTools.getCacheFileLocation(fileName, directoryId));
        FileOutputStream fileOutput = new FileOutputStream(file);
        InputStream inputStream = (InputStream) conn.getInputStream();
        byte[] buffer = new byte[1024 * 1024];
        int bufferLength = 0;
        while ((bufferLength = inputStream.read(buffer)) > 0) {
            fileOutput.write(buffer, 0, bufferLength);
        }
        fileOutput.close();
        inputStream.close();
        Log.d(TAG, "Download successful. Downloaded File : " + file.getAbsolutePath());
        // Generate thumbnail and encrypt the file and thumbnail
        ***String thumbnailPath = FileTools.cacheThumbnail(file, file.getName(), directoryId);***
        if (thumbnailPath != null && !thumbnailPath.isEmpty()) {
            // Encrypt the file
            try {
                FileTools.SaveFileEncrypted(file, directoryId);
            } catch (Exception e) {
                e.printStackTrace();
                // Delete the file
                file.delete();
            }
        } else {
            // Delete the file
            file.delete();
        }
    } catch (Exception e) {
        Log.d(TAG, "Exception while downloading file");
        e.printStackTrace();
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
}

FileTools.cacheThumbnail 函数

public static String cacheThumbnail(File file, String fileName, String chatId) {
    Log.d(TAG, "cacheThumbnail original File path : " + file.getAbsolutePath());
    Log.d(TAG, "cacheThumbnail original File exists : " + file.exists());
    Log.d(TAG, "cacheThumbnail original file size : " + file.length());
    String thumbName = String.format("thumb-%s.jpg", fileName);
    File fileThumb = new File(FileTools.getMediaCachePath(chatId), thumbName);
    ByteArrayOutputStream out = null;
    try {
        out = new ByteArrayOutputStream();
        BitmapFactory.Options options = new BitmapFactory.Options();
        Bitmap image = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(file.toURI().getPath(), options), 256, 256, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
        // Thumbnail generation for the image failed. It is a video file. Generate
        // thumbnail for the video file
        if (image == null) {
            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            try {
                retriever.setDataSource(FileTools.getFileInputStreamFromStorage(file).getFD());
                // Generate thumbnail from a frame that is 5% deep into the video
                String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
                long timeInMillisec = Long.parseLong(time);
                long durationMicroSec = timeInMillisec * 1000;
                long thumbnailDepth = (long) (durationMicroSec * (0.15f));
                image = retriever.getFrameAtTime(thumbnailDepth, MediaMetadataRetriever.OPTION_CLOSEST);
                image = ThumbnailUtils.extractThumbnail(image, 256, 256, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
            } catch (IllegalArgumentException ex) {
                Log.e(TAG, ex.getMessage());
                image = null;
            } catch (RuntimeException ex) {
                Log.e(TAG, ex.getMessage());
                image = null;
            } catch (IOException e) {
                image = null;
                Log.e(TAG, e.getMessage());
            }
        }
        // Could not generate a thumbnail. Probably a corrupt/bad file
        if (image == null) {
            return null;
        }
        ***image = Utilities.orientBitmap(file.getAbsolutePath(), image);***
        image.compress(Bitmap.CompressFormat.JPEG, 80, out);
        out.close();
        FileTools.SaveFileEncrypted(fileThumb, out.toByteArray());
        return fileThumb.toURI().getPath();
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        try {
            if (out != null) {
                out.close();
            }
        } catch (Exception ignore) {
        }
    }
}

orientBitmap 和rotateBitmap 函数功能

public static Bitmap orientBitmap(String filePath, Bitmap bitmap) throws IOException {
    Log.d(TAG, "orientBitmap FilePath : " + filePath);
    File file = new File(filePath);
    Log.d(TAG, "orientBitmap File exists : " + file.exists());

    ExifInterface exifInterface = new ExifInterface(filePath);
    Log.d(TAG, "After exception");
    int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

    Log.d(TAG, "Thumb orientation : " + orientation);

    switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            bitmap = rotateBitmap(bitmap, 90);
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            bitmap = rotateBitmap(bitmap, 180);
            break;
        case ExifInterface.ORIENTATION_ROTATE_270:
            bitmap = rotateBitmap(bitmap, 270);
            break;
    }
    return bitmap;
}

public static Bitmap rotateBitmap(Bitmap source, float angle) {
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}

我在尝试生成 mp4 文件和 png 文件的缩略图时通过发布堆栈跟踪来更新堆栈跟踪。

mp4 文件的堆栈跟踪。

D/DownloadFileClass: downloadAndSaveFile url : example.com/media/download/568405
D/DownloadFileClass: Download successful. Downloaded File : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/MP4_20161017_134641.mp4
D/FileTools: cacheThumbnail original File path : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/MP4_20161017_134641.mp4
D/FileTools: cacheThumbnail original File exists : true
D/FileTools: cacheThumbnail original file size : 6434816
D/skia: --- SkImageDecoder::Factory returned null
D/Utilities: orientBitmap FilePath : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/MP4_20161017_134641.mp4
D/Utilities: orientBitmap File exists : true
W/ExifInterface: Invalid image.
    java.io.IOException: Invalid marker: 0
    at android.media.ExifInterface.getJpegAttributes(ExifInterface.java:1600)
           at android.media.ExifInterface.loadAttributes(ExifInterface.java:1339)
           at android.media.ExifInterface.<init>(ExifInterface.java:1057)
           at com.mypackage.helpers.Utilities.orientBitmap(Utilities.java:85)
           at com.mypackage.fileio.FileTools.cacheThumbnail(FileTools.java:700)
           at com.mypackage.coreapi.DownloadFileClass$downloadAndSaveFile(DownloadFileClass.java:215)
           at com.mypackage.coreapi.DownloadFileClass$downloadAndSaveFile(DownloadFileClass.java:113)
           at android.os.AsyncTask$2.call(AsyncTask.java:295)
           at java.util.concurrent.FutureTask.run(FutureTask.java:237)
           at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
           at java.lang.Thread.run(Thread.java:818)
D/Utilities: After exception
D/Utilities: Thumb orientation : 0
D/FileTools: Save file to : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/MP4_20161017_134641.mp4
D/EncryptedFileTools: ......Final saved file path...... : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/encryptPlaceHolder

png 文件的堆栈跟踪

D/DownloadFileClass: downloadAndSaveFile url : example.com/media/download/568406
D/DownloadFileClass: Download successful. Downloaded File : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/PNG_20161017_134748.png
D/FileTools: cacheThumbnail original File path : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/PNG_20161017_134748.png
D/FileTools: cacheThumbnail original File exists : true
D/FileTools: cacheThumbnail original file size : 92160
D/Utilities: orientBitmap FilePath : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/PNG_20161017_134748.png
D/Utilities: orientBitmap File exists : true
W/ExifInterface: Invalid image.
    java.io.IOException: Invalid marker: 89
           at android.media.ExifInterface.getJpegAttributes(ExifInterface.java:1600)
           at android.media.ExifInterface.loadAttributes(ExifInterface.java:1339)
           at android.media.ExifInterface.<init>(ExifInterface.java:1057)
           at com.mypackage.helpers.Utilities.orientBitmap(Utilities.java:85)
           at com.mypackage.fileio.FileTools.cacheThumbnail(FileTools.java:700)
           at com.mypackage.coreapi.DownloadFileClass$downloadAndSaveFile(DownloadFileClass.java:215)
           at com.mypackage.coreapi.DownloadFileClass$downloadAndSaveFile(DownloadFileClass.java:113)
           at android.os.AsyncTask$2.call(AsyncTask.java:295)
           at java.util.concurrent.FutureTask.run(FutureTask.java:237)
           at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
           at java.lang.Thread.run(Thread.java:818)
D/Utilities: After exception
D/Utilities: Thumb orientation : 0
D/FileTools: Save file to : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/PNG_20161017_134748.png
D/EncryptedFileTools: ......Final saved file path...... : /data/user/0/com.mypackage.myapp/cache/userhash/79640/media/encryptPlaceHolder

令人困惑的是,当我在装有 android 4.4.4 的 Samsung Galaxy S4 上运行该应用程序时,我没有遇到此异常,但是当我在装有 android 6.0.1 的 Samsung Galaxy S5 上运行它时,我总是遇到此异常。我在 Android 7.0 的模拟器上也遇到了这个错误。我不确定如何解决这个问题。

请参阅随附的权限屏幕截图。 Enabled Permissions

我已经添加了请求的信息。如果需要更多信息,请告诉我。我之前没有使用过 ExifTags,所以请多多包涵。 再次感谢。

最佳答案

我在上面的代码中发现了问题。显然我试图直接从 mp4 和 png 文件中读取 EXIF 标签。在搜索更多有关 EXIF 标签的信息后,我发现 EXIF 标签仅适用于 JPEG 文件。因此,解决我的问题的方法是首先创建 mp4/png 文件的 JPEG 图像,然后尝试从该 JPEF 文件中读取 EXIF 标签。这样做解决了问题,我不再遇到异常。

感谢大家指导我找到解决方案。

关于android - ExifInterface 构造函数抛出 IOExxception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40066054/

有关android - ExifInterface 构造函数抛出 IOExxception的更多相关文章

  1. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  2. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  3. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  4. ruby - 在 Ruby 中重新分配常量时抛出异常? - 2

    我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案

  5. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  6. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  7. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  8. ruby-on-rails - 将字符串转换为 ruby​​-on-rails 中的函数 - 2

    我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。

  9. ruby - 在 ruby​​ 中使用 .try 函数和 .map 函数 - 2

    我需要从json记录中获取一些值并像下面这样提取curr_json_doc['title']['genre'].map{|s|s['name']}.join(',')但对于某些记录,curr_json_doc['title']['genre']可以为空。所以我想对map和join()使用try函数。我试过如下curr_json_doc['title']['genre'].try(:map,{|s|s['name']}).try(:join,(','))但是没用。 最佳答案 你没有正确传递block。block被传递给参数括号外的方法

  10. ruby - 是否可以从也在该模块中的类内部调用模块函数 - 2

    在这段Ruby代码中:ModuleMClassC当我尝试运行时出现“'M:Module'的未定义方法'helper'”错误c=M::C.new("world")c.work但直接从另一个类调用M::helper("world")工作正常。类不能调用在定义它们的同一模块中定义的模块函数吗?除了将类移出模块外,还有其他解决方法吗? 最佳答案 为了调用M::helper,你需要将它定义为defself.helper;结束为了进行比较,请查看以下修改后的代码段中的helper和helper2moduleMclassC

随机推荐