Результат от OpenFileChooser в Android Webview вызывает приложение не отвечает

Я занимаюсь разработкой гибридного приложения в Android. В этом приложении я пытаюсь получить изображение (из камеры или из галереи) как изображение профиля пользователя. Вот код, который я использую, чтобы получить изображение.

    @Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    webView = (WebView) findViewById(R.id.webview);

    try {
        WebSettings webSettings = webView.getSettings();
        webSettings.setDatabaseEnabled(true);
        webSettings.setDatabasePath("/data/data/"
                + getApplicationContext().getPackageName() + "/databases");

        webSettings.setJavaScriptEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setAllowFileAccess(true);
        webSettings.setLoadsImagesAutomatically(true);

        webSettings.setRenderPriority(RenderPriority.HIGH);
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);

        webSettings.setSupportZoom(false);
        webSettings.setBuiltInZoomControls(false);
        webSettings.setDisplayZoomControls(false);
        webSettings.setLoadWithOverviewMode(true);
        webSettings.setUseWideViewPort(false);

        webView.addJavascriptInterface(_jsInterface, "JSInterface");
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageStarted(WebView view, String url,
                    Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
            }
        });
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onJsAlert(WebView view, String url,
                    String message, JsResult result) {
                return super.onJsAlert(view, url, message, result);
            }

            @SuppressWarnings("unused")
            public void openFileChooser(ValueCallback<Uri> uploadMsg,
                    String acceptType, String capture) {
                openFileChooser(uploadMsg, acceptType);
            }

            private void openFileChooser(ValueCallback<Uri> uploadMsg,
                    String acceptType) {
                mUploadMessage = uploadMsg;
                try {
                    File imageStorageDir = new File(
                            Environment
                                    .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                            "AndroidImageFolder");
                    if (!imageStorageDir.exists()) {
                        imageStorageDir.mkdirs();
                    }
                    File file = new File(imageStorageDir + File.separator
                            + "CAPTURE_"
                            + String.valueOf(System.currentTimeMillis())
                            + ".jpg");
                    mCapturedImageURI = Uri.fromFile(file);
                    final Intent captureIntent = new Intent(
                            android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                    captureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                            mCapturedImageURI);

                    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                    i.addCategory(Intent.CATEGORY_OPENABLE);
                    i.setType("image/*");
                    Intent chooserIntent = Intent.createChooser(i,
                            "Pick your avatar");
                    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
                            new Parcelable[] { captureIntent });
                    startActivityForResult(chooserIntent,
                            REQUEST_CODE_FILE_CHOOSER);

                } catch (Exception e) {
                }

            }
        });

        if (savedInstanceState == null) {
            webView.loadUrl("file:///android_asset/index.html");
        }
    } catch (Exception ex) {
        Log.d(TAG, ex.getCause().toString());
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    webView.saveState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    webView.restoreState(savedInstanceState);
}

@Override
protected void onResume() {
    super.onResume();
}

@Override
protected void onStart() {
    super.onStart();
}

@Override
public void onStop() {
    super.onStop();
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    try {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_CANCELED) {
            //Intent returnIntent = new Intent();
            //setResult(RESULT_CANCELED, returnIntent);
        } else if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
            case REQUEST_CODE_FILE_CHOOSER:
                if (null == mUploadMessage)
                    return;
                Uri result = (data == null || resultCode != RESULT_OK) ? mCapturedImageURI
                        : data.getData();
                mUploadMessage.onReceiveValue(result);
                mUploadMessage = null;

                if (result != null) {
                    String imagePath = "";
                    String[] imgData = { MediaStore.Images.Media.DATA };
                    @SuppressWarnings("deprecation")
                    Cursor imgCursor = managedQuery(result, imgData, null,
                            null, null);
                    if (imgCursor != null) {
                        int index = imgCursor
                                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                        imgCursor.moveToFirst();
                        imagePath = imgCursor.getString(index);
                    } else {
                        imagePath = result.getPath();
                    }
                    Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
                    bitmap = ExifUtil.rotateBitmap(imagePath, bitmap);
                    // Here goes the bitmap to base64 conversion
                    try {
                        handler.post(new Runnable() {
                            public void run() {
                                webView.loadUrl("javascript:myJSFunction()"); // Here I return the base64 code (after bitmap conversion)
                            }
                        });
                    } catch (Exception Ex) {
                    }
                }
                break;
            }
        }
    } catch (Exception ex) {
    }
}

Он успешно открывает окно "FileChooser" с опцией "Камера и галерея". Если я выбираю изображение, то приложение работает отлично. Проблема в том, что когда я возвращаюсь к приложению без выбора какого-либо файла (с помощью нажатия на кнопку назад или щелкаю экран приложения), приложение застревает (невозможно щелкнуть любую ссылку в веб-просмотре).

В целях тестирования (находится ли активность веб-просмотра в активном состоянии) я попытался вызвать функцию JS в состоянии RESULT_CANCELED. Вот мой тестовый код

  if(resultCode == Activity.RESULT_CANCELED){
      try {
           handler.post(new Runnable() {
              public void run() {
                webView.loadUrl("javascript:myJSFunction()");
              }
           });
        } catch (Exception Ex) {
        }
  }
  else if(resultCode == Activity.RESULT_OK){
    ..... // Rest of the code
  }

Эта функция также не вызывается. (но функция вызывается, когда resultCode равен RESULT_OK)

Тестовая версия ОС устройства: Android JB 4.3

Я застрял в этой ситуации. Ребята, не могли бы вы помочь мне разобраться с ситуацией RESULT_CANCELED и отметить, что эта проблема решена. Заранее спасибо.

1 ответ

Решение

Вам все еще нужно вызвать mUploadMessage.onReceiveValue, когда вы получите RESULT_CANCELLED.

Я думаю, что вы можете передать NULL в этом случае.

Другие вопросы по тегам