Uploading Media Files via <input type="file" > Android


#1

Hi everyone,
in my recent project have to upload some mediafile to a server.
mostly photos and videos. But the user should be able to choose to open the camera instead an take an new picture, to upload those,

so when i use an
<input type="file">
in chrome it will open an dialog asking me if i want to open the camera/soundrecorder or an filepicker,

when ich use the same element in my ionic2 app it will only open the native “recent files”-dialog.

why is there an difference between chrome an the webview?

using
<input type="file" accept="images/*">
has no influence

I’m aware that there is a cordova plugin for taking pictures an uploading them. an additional challenge is that the uplaod buttons itself is not part of my app: it is loaded via an iframe from an webapp (my colleague is in charge here…)

thanks in advance.


#2

That should be <input type="file" accept="image/*">, not images/*


#3

To historical purposes…

My project was using cordova-plugin-inappbrowser.

I solve it merging solution in webview open camera from input field without filechooser (answer code) with methods onActivityResult and onShowFileChooser from class InAppBrowser in plugin source.

See the changes made in InAppBrowser class from plugin version 3.0.0

1 - include imports:

import android.app.Activity;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

2 - declare variavel;

    private String mCM;

3 - Replace onShowFileChooser code


                    // For Android 5.0+
                    public boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)
                    {
                        LOG.d(LOG_TAG, "File Chooser 5.0+");

                        // If callback exists, finish it.
                        if(mUploadCallbackLollipop != null) {
                            mUploadCallbackLollipop.onReceiveValue(null);
                        }
                        mUploadCallbackLollipop = filePathCallback;

                        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

                        if(takePictureIntent.resolveActivity(cordova.getActivity().getPackageManager()) != null) {

                            File photoFile = null;
                            try{
                                photoFile = createImageFile();
                                takePictureIntent.putExtra("PhotoPath", mCM);
                            }catch(IOException ex){
                                Log.e(LOG_TAG, "Image file creation failed", ex);
                            }
                            if(photoFile != null){
                                mCM = "file:" + photoFile.getAbsolutePath();
                                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
                            }else{
                                takePictureIntent = null;
                            }
                        }
                        // Create File Chooser Intent
                        Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
                        contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
                        contentSelectionIntent.setType("*/*");
                        Intent[] intentArray;
                        if(takePictureIntent != null){
                            intentArray = new Intent[]{takePictureIntent};
                        }else{
                            intentArray = new Intent[0];
                        }

                        Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
                        chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
                        chooserIntent.putExtra(Intent.EXTRA_TITLE, "Selecione a imagem");
                        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);

                        // Run cordova startActivityForResult
                        cordova.startActivityForResult(InAppBrowser.this, chooserIntent, FILECHOOSER_REQUESTCODE);

                        return true;
                    }

4 - create method


    private File createImageFile() throws IOException{
        @SuppressLint("SimpleDateFormat") String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "img_"+timeStamp+"_";
        File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        return File.createTempFile(imageFileName,".jpg",storageDir);
    }

5 - Replace onActivityResult


    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        // For Android >= 5.0
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

            LOG.d(LOG_TAG, "onActivityResult (For Android >= 5.0)");

            Uri[] results = null;
            //Check if response is positive
            if(resultCode== Activity.RESULT_OK){
                if(requestCode == FILECHOOSER_REQUESTCODE){
                    if(null == mUploadCallbackLollipop){
                        return;
                    }
                    if(intent == null || intent.getData() == null){
                        //Capture Photo if no image available
                        if(mCM != null){
                            results = new Uri[]{Uri.parse(mCM)};
                        }
                    }else{
                        String dataString = intent.getDataString();
                        if(dataString != null){
                            results = new Uri[]{Uri.parse(dataString)};
                        }
                    }
                }
            }
            mUploadCallbackLollipop .onReceiveValue(results);
            mUploadCallbackLollipop = null;
        }
        // For Android < 5.0
        else {
            LOG.d(LOG_TAG, "onActivityResult (For Android < 5.0)");
            // If RequestCode or Callback is Invalid
            if(requestCode != FILECHOOSER_REQUESTCODE || mUploadCallback == null) {
                super.onActivityResult(requestCode, resultCode, intent);
                return;
            }

            if (null == mUploadCallback) return;
            Uri result = intent == null || resultCode != cordova.getActivity().RESULT_OK ? null : intent.getData();

            mUploadCallback.onReceiveValue(result);
            mUploadCallback = null;
        }
    }

StackOverflow ref: https://stackoverflow.com/questions/26381050/choose-camera-in-file-upload-in-cordova-application-on-android-without-using-cor/54425770#54425770