Загружать фотокамеру и файловую камеру из поля просмотра веб-просмотра INPUT

Мое приложение основано на веб-сайтах, и мне нужно загружать фотографии из полевого лагеря INPUT. У меня две ситуации, и, поскольку я не знаю другого способа сделать это, в зависимости от страницы, которую я выбираю тем или иным способом с помощью «boolean boolFileChoser» в зависимости от ходатайства URL-адреса:

а. Сборщик файлов

б. Фотосессия камеры.

Я занимался сбором файлов и полностью загружал файл, проблема с камерой. Как только я попытаюсь загрузить Pic Pic, он сработает. Насколько я знаю его, потому что URI.

A) File picker: content: // media / external / images / 1234

Б) Съемка камеры: файл: ///mnt/sdcard/Pic.jpg

Я не нашел способа изменить его.

См. Обновление

Теперь он вылетает из-за ошибки nullpointer при попытке загрузить «content: // media / external / images / 1234». (Только с камерой, а не с выбором файла.). Кроме того, если переключатель выбора / камеры закрыт (кнопка «Назад»), я не могу позвонить ему снова.

Случай a) и b) 100% работает, вот рабочий код, включая то, как я знаю, вызваны ли fileChooser или камера:

@Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { if (resultCode != RESULT_OK) { /** fixed code **/ //To be able to use the filechooser again in case of error mUploadMessage.onReceiveValue(null); /** fixed code **/ return; } if (mUploadMessage==null) { Log.d("androidruntime","no mUploadMessage"); return; } if (requestCode == FILECHOOSER_RESULTCODE) { Uri selectedImage= intent == null || resultCode != RESULT_OK ? null : intent.getData(); Log.d("androidruntime","url: "+selectedImage.toString()); }else if (requestCode == CAMERAREQUEST_RESULTCODE) { if(mCapturedImageURI==null){ Log.d("androidruntime","no mCapturedImageURI"); return; } /** fixed code **/ getContentResolver().notifyChange(mCapturedImageURI, null); ContentResolver cr = getContentResolver(); Uri uriContent= Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), photo.getAbsolutePath(), null, null)); photo = null; /** fixed code **/ } mUploadMessage.onReceiveValue(selectedImage); mUploadMessage = null; } private static final int FILECHOOSER_RESULTCODE = 2888; private static final int CAMERAREQUEST_RESULTCODE = 1888; private ValueCallback<Uri> mUploadMessage; private Uri mCapturedImageURI = null; protected class AwesomeWebChromeClient extends WebChromeClient{ // Per Android 3.0+ public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType){ /**updated, out of the IF **/ mUploadMessage = uploadMsg; /**updated, out of the IF **/ if(boolFileChooser){ //Take picture from filechooser Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType("image/*"); MainActivity.this.startActivityForResult( Intent.createChooser( i, "Escoger Archivo" ), MainActivity.FILECHOOSER_RESULTCODE ); } else { //Take photo and upload picture Intent cameraIntent = new Intent("android.media.action.IMAGE_CAPTURE"); File photo = new File(Environment.getExternalStorageDirectory(), "Pic.jpg"); cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo)); mCapturedImageURI = Uri.fromFile(photo); startActivityForResult(cameraIntent, MainActivity.CAMERA_REQUEST); } } // Per Android < 3.0 public void openFileChooser(ValueCallback<Uri> uploadMsg){ openFileChooser(uploadMsg, ""); } //Altre public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) { openFileChooser(uploadMsg, ""); } /** Added code to clarify chooser. **/ //The webPage has 2 filechoosers and will send a console message informing what action to perform, taking a photo or updating the file public boolean onConsoleMessage(ConsoleMessage cm) { onConsoleMessage(cm.message(), cm.lineNumber(), cm.sourceId()); return true; } public void onConsoleMessage(String message, int lineNumber, String sourceID) { Log.d("androidruntime", "Per cònsola: " + cm.message()); if(message.endsWith("foto")){ boolFileChooser= true; } else if(message.endsWith("pujada")){ boolFileChooser= false; } } /** Added code to clarify chooser. **/ } 

ОБНОВЛЕНИЕ 1

Я мог получить формат uri «content: // media / external / images / xxx», но приложение все еще сбой при попытке загрузить uri через «mUploadMessage.onReceiveValue (selectedImage)». Теперь я получаю исключение nullpointer.


ОБНОВЛЕНИЕ 2

Исправлено и работает.

У меня была «ValueCallback uploadMsg» в локальной переменной только в случае с файловым выбором, поэтому она всегда вызывала мне исключение, когда я пытался загрузить файл с фотографией, потому что он был нулевым. Как только я вынул из инструкции if-else, все сработало. Предыдущее обновление было самым простым методом для обработки файлов.

Я уже добавил 'mUploadMessage.onReceiveValue (null);' Если намерение Camera / filechooser отменено (вы должны иметь дело с ним на своей веб-странице), если нет, вы не сможете снова запустить поле INPUT (Intent).


ОБНОВЛЕНИЕ 3

Добавлена ​​часть кода внутри AwesomeChromeClient, чтобы различить этот параметр, сделать снимок или выбрать файл .. его МОЙ способ сделать это и добавить в петицию, я уверен, что есть много других допустимых способов сделать это,

Теперь код на 100% функционально. Если вы укажете, хотите ли вы выбрать изображение или файл

Извините, что написал в своем посте, но вот как я выполнил загрузку камеры и filechooser из поля ввода WebView:

Ниже приведен код этой важной темы, остальная часть не относящегося к делу кода удаляется.

 public class MainActivity extends Activity { private WebView webView; private String urlStart = "http://www.example.com/mobile/"; //File choser parameters private static final int FILECHOOSER_RESULTCODE = 2888; private ValueCallback<Uri> mUploadMessage; //Camera parameters private Uri mCapturedImageURI = null; @SuppressLint("SetJavaScriptEnabled") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = (WebView) findViewById(R.id.webView); webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setLoadWithOverviewMode(true); webView.getSettings().setAllowFileAccess(true); webView.loadUrl(urlStart); webView.setWebChromeClient(new WebChromeClient() { // openFileChooser for Android 3.0+ public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) { mUploadMessage = uploadMsg; try{ Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); File externalDataDir = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_DCIM); File cameraDataDir = new File(externalDataDir.getAbsolutePath() + File.separator + "browser-photos"); cameraDataDir.mkdirs(); String mCameraFilePath = cameraDataDir.getAbsolutePath() + File.separator + System.currentTimeMillis() + ".jpg"; mCapturedImageURI = Uri.fromFile(new File(mCameraFilePath)); cameraIntent.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, "Image Chooser"); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[] { cameraIntent }); startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE); } catch(Exception e){ Toast.makeText(getBaseContext(), "Camera Exception:"+e, Toast.LENGTH_LONG).show(); } } // For Android < 3.0 @SuppressWarnings("unused") public void openFileChooser(ValueCallback<Uri> uploadMsg ) { openFileChooser(uploadMsg, ""); } // For Android > 4.1.1 @SuppressWarnings("unused") public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){ openFileChooser(uploadMsg, acceptType); } public boolean onConsoleMessage(ConsoleMessage cm) { onConsoleMessage(cm.message(), cm.lineNumber(), cm.sourceId()); return true; } public void onConsoleMessage(String message, int lineNumber, String sourceID) { Log.d("androidruntime", "www.example.com: " + message); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { // TODO Auto-generated method stub if(requestCode==FILECHOOSER_RESULTCODE) { if (null == this.mUploadMessage) { return; } Uri result=null; try{ if (resultCode != RESULT_OK) { result = null; } else { // retrieve from the private variable if the intent is null result = intent == null ? mCapturedImageURI : intent.getData(); } } catch(Exception e) { Toast.makeText(getApplicationContext(), "activity :"+e, Toast.LENGTH_LONG).show(); } mUploadMessage.onReceiveValue(result); mUploadMessage = null; } } 

Надеюсь, кто-то будет полезен 🙂

Решаемые. Внутри моего вопроса есть функциональный код, если кому-то это понадобится.

Вот решение проблем:

  1. Не удалось открыть камеру / filechooser, если я ранее открывал и отменял:

     //inside onActivityResult if (resultCode != RESULT_OK) { mUploadMessage.onReceiveValue(null); return; } 
  2. Получите формат uri «content: // media / external / images / xxx», чтобы загрузить uri через «mUploadMessage.onReceiveValue (selectedImage)», избегая ошибки nullpointer

     //inside OnActivityResult getContentResolver().notifyChange(mCapturedImageURI, null); ContentResolver cr = getContentResolver(); Uri uriContent = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), photo.getAbsolutePath(), null, null)); 

Решено и работает отлично.

Просто взгляните на код класса WebChromeClient. Вы увидите, что параметры изменены ранее.

 public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) { throw new RuntimeException("Stub!"); } 

Решение:

Вы просто следуете последнему коду ChromeBrowser в этом github-link браузере Android Chrome на Github

Используйте тот же код github для вашего проекта.

Примечание. Проблема с версией KitKat для Android 4.0. Кроме android 4.4, он отлично работает для других версий Android.

Потому что это все еще открытый дефект от Google. Пожалуйста, проверьте приведенную ниже ссылку.

OpenFileChooser не вызывается при нажатии на Android-браузер 4.4.