4

我制作了一个相对简单的 phonegap 应用程序,能够捕获图像和视频并将它们上传到服务器。

图像工作正常,但是当我调用捕获视频时,会出现相机 UI,并且当我接受视频时,应用程序崩溃并在 logcat 中出现此错误:

java.lang.RuntimeException: Failure delivering result ResultInfo(who=null, request=2, result=-1, data=Intent { dat=content://media/external/video/media/46536 }} to activity {myApp.test.app}: java.lang.IllegalStateException:Do not perform IO operations on the UI thread. Use CordovaInterface.getThreadPool() instead

我正在使用 phonegap 3.0.0,我已经通过命令行界面安装了正确的插件,并且我的 AndroidManifest 很好。

我正在使用 phonegap API 中的演示代码,所以问题也不存在。

4

2 回答 2

11

此问题的解决方法是编辑 [yourApp]\plugins\org.apache.cordova.media-capture\src\android\Capture.java

从第 377 行开始,更改此代码

private JSONObject createMediaFile(Uri data) {
    File fp = webView.getResourceApi().mapUriToFile(data);
    JSONObject obj = new JSONObject();

到下面的代码

private JSONObject createMediaFile(Uri data) {
    // is thread checking enabled?
    boolean thC = webView.getResourceApi().isThreadCheckingEnabled();       
    // set thread checking to disabled (this works around mapUriToFile failing with IllegalStateException: Do not perform IO operations on the UI thread.
    webView.getResourceApi().setThreadCheckingEnabled(false);       
    File fp = webView.getResourceApi().mapUriToFile(data);
    // set thread checking back to whatever it was before the call above.
    webView.getResourceApi().setThreadCheckingEnabled(thC);
    JSONObject obj = new JSONObject();

这对我们有用,希望它会很快得到适当的修复。

于 2013-10-09T17:11:39.880 回答
4

我认为更好的解决方案是实际阻止使用 UI 线程,而不是禁用线程检查。

我是这样解决的:

private JSONObject createMediaFile(final Uri data) {
    Future<JSONObject> result = cordova.getThreadPool().submit(new Callable<JSONObject>()
    {
        @Override
        public JSONObject call() throws Exception
        {
            File fp = webView.getResourceApi().mapUriToFile(data);
            JSONObject obj = new JSONObject();

            try {
                // File properties
                obj.put("name", fp.getName());
                obj.put("fullPath", fp.toURI().toString());
                // Because of an issue with MimeTypeMap.getMimeTypeFromExtension() all .3gpp files
                // are reported as video/3gpp. I'm doing this hacky check of the URI to see if it
                // is stored in the audio or video content store.
                if (fp.getAbsoluteFile().toString().endsWith(".3gp") || fp.getAbsoluteFile().toString().endsWith(".3gpp")) {
                    if (data.toString().contains("/audio/")) {
                        obj.put("type", AUDIO_3GPP);
                    } else {
                        obj.put("type", VIDEO_3GPP);
                    }
                } else {
                    obj.put("type", FileHelper.getMimeType(Uri.fromFile(fp), cordova));
                }

                obj.put("lastModifiedDate", fp.lastModified());
                obj.put("size", fp.length());
            } catch (JSONException e) {
                // this will never happen
                e.printStackTrace();
            }

            return obj;
        }
    });


    try
    {
        return result.get();
    }
    catch (InterruptedException e)
    {
        e.printStackTrace();
    }
    catch (ExecutionException e)
    {
        e.printStackTrace();
    }

    return null;

我将默认方法包装在一个可调用的内部类中。现在它在另一个线程中执行。

于 2013-10-29T11:29:52.783 回答