openFileChooser Android 4.4.4缺少文件名 [英] Filename are missing for openFileChooser Android 4.4.4

查看:80
本文介绍了openFileChooser Android 4.4.4缺少文件名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标:能够将任何类型的文件附加到Android 4.1+webview中的<input type="file" />. (Android 5+可以)

Goal: to be able to attach a file of any type to a <input type="file" /> in a webview in Android 4.1+. (Android 5+ is fine)

我根据发现的一些示例,认为合适的方式设置了openFileChooser.它适用于4.1,但不适用于4.4.4,其中未正确设置附件的文件名.
而是将intent.mData的最后路径返回到onActivityResult设置为文件名,例如,对于mDatacontent://com.android.providers.downloads.documents/document/2,文件名将为2-当然没有扩展名-而名称应是image.png.

I set openFileChooser as I saw fit based on few examples I have found. It works on 4.1 but not on 4.4.4 where the files attached do not have their filename correctly set.
Instead is set as filename the last path of the intent.mData return to onActivityResult, .e.g, for a mData value of content://com.android.providers.downloads.documents/document/2, the filename will be 2―without extension of course―while the name should be image.png.

该如何解决?我的代码有什么问题吗?

What can I do to fix it? Would there be any problem in my code?

我在以下模拟器上进行测试:Galaxy Nexus,API 19,目标:默认
请参见下面的代码.

webView.setWebChromeClient(new WebChromeClient() {
    public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
        if (UseWebViewActivity.this.valueCallback != null) {
            UseWebViewActivity.this.valueCallback.onReceiveValue(null);
        }
        UseWebViewActivity.this.valueCallback = valueCallback;

        Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
        contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
        contentSelectionIntent.setType("*/*");
        startActivityForResult(Intent.createChooser(contentSelectionIntent,
            getString(R.string.file_chooser_title)), INPUT_FILE_REQUEST_CODE);
    }
});

// ...

protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    if (requestCode == INPUT_FILE_REQUEST_CODE && valueCallback != null) {
        Uri result = null;
        if (resultCode == Activity.RESULT_OK) {
            result = intent.getData();
        }
        valueCallback.onReceiveValue(result);
        valueCallback = null;
    }
}

推荐答案

问题出在KitKat的onActivityResult()方法中,该方法返回URI.您需要获取图像文件的真实路径.

The problem is in the onActivityResult() method for KitKat which returns the URI. You need to get the realpath of the imagefile.

请注意我如何通过致电获得IMG的真实路径:

Notice how i get the Real Path of the IMG by calling :

KitkatPath = Uri.parse("file://" + getPath(MobilestyxAppActivity.this,result));在onActivityResult()中.

KitkatPath = Uri.parse("file://"+getPath(MobilestyxAppActivity.this, result)); in the onActivityResult().

您必须添加字符串"file://"才能使其正常工作.

You must add the string "file://" for it to work.

PS:我已经从各种来源收集了代码并对其进行了修改.

PS : I have gathered the code from various sources and modified it.

看一下下面的代码,该代码适用于Kitkat& Lolipop和其他较低版本的Android.

Look at my code below which works for Kitkat & Lolipop and other low versions of Android.

/** CODE FOR FILE UPLOAD*/  
private static final int INPUT_FILE_REQUEST_CODE = 1;
private static final int FILECHOOSER_RESULTCODE = 1;
private ValueCallback<Uri> mUploadMessage;
private Uri mCapturedImageURI = null;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
Uri KitkatPath ;   

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {



    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        if (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) {
            super.onActivityResult(requestCode, resultCode, data);
            return;
        }
        Uri[] results = null;
        // Check that the response is a good one
        if (resultCode == Activity.RESULT_OK) {
            if (data == null) {
                // If there is not data, then we may have taken a photo
                if (mCameraPhotoPath != null) {
                    results = new Uri[]{Uri.parse(mCameraPhotoPath)};
                }
            } else {
                String dataString = data.getDataString();
                if (dataString != null) {
                    results = new Uri[]{Uri.parse(dataString)};
                }
            }
        }
        mFilePathCallback.onReceiveValue(results);
        mFilePathCallback = null;
    } 




    else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
        System.out.println("In KitKat Condition");

        if (requestCode != FILECHOOSER_RESULTCODE || mUploadMessage == null) {
            System.out.println("In != Null");
            super.onActivityResult(requestCode, resultCode, data);
            return;
        }
        if (requestCode == FILECHOOSER_RESULTCODE) {

            System.out.println("requestCode == FileChooser ResultCode");
            if (null == this.mUploadMessage) {
                System.out.println("In null == this.mUploadMessage");
                return;
            }
            Uri result = null;
            try {
                if (resultCode != RESULT_OK) {

                    result = null;
                } else {

                    //newcode

                    // retrieve from the private variable if the intent is null
                    result = data == null ? mCapturedImageURI : data.getData();

                    KitkatPath = Uri.parse("file://"+getPath(MobilestyxAppActivity.this, result));
                    System.out.println("KitkatPath== "+KitkatPath);
                    System.out.println("result = "+result);
                }
            } catch (Exception e) {
               // Toast.makeText(getApplicationContext(), "activity :" + e,                            Toast.LENGTH_LONG).show();
                e.printStackTrace();
            }
           // mUploadMessage.onReceiveValue(result);
            mUploadMessage.onReceiveValue(KitkatPath);
            System.out.println("mUploadMessage = "+mUploadMessage);
            mUploadMessage = null;
        }
    }
    return;
}



 /** CODE FOR FILE UPLOAD*/ 



public static String getPath(final Context context, final Uri uri) {

    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) {
                return Environment.getExternalStorageDirectory() + "/" + split[1];
            }

            // TODO handle non-primary volumes
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {

            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

            return getDataColumn(context, contentUri, null, null);
        }
        // MediaProvider
        else if (isMediaDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            Uri contentUri = null;
            if ("image".equals(type)) {
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if ("video".equals(type)) {
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else if ("audio".equals(type)) {
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            }

            final String selection = "_id=?";
            final String[] selectionArgs = new String[] {
                    split[1]
            };

            return getDataColumn(context, contentUri, selection, selectionArgs);
        }
    }
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) {

        // Return the remote address
        if (isGooglePhotosUri(uri))
            return uri.getLastPathSegment();

        return getDataColumn(context, uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    }

    return null;
}

/**
 * Get the value of the data column for this Uri. This is useful for
 * MediaStore Uris, and other file-based ContentProviders.
 *
 * @param context The context.
 * @param uri The Uri to query.
 * @param selection (Optional) Filter used in the query.
 * @param selectionArgs (Optional) Selection arguments used in the query.
 * @return The value of the _data column, which is typically a file path.
 */
public static String getDataColumn(Context context, Uri uri, String selection,
        String[] selectionArgs) {

    Cursor cursor = null;
    final String column = "_data";
    final String[] projection = {
            column
    };

    try {
        cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                null);
        if (cursor != null && cursor.moveToFirst()) {
            final int index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}


/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is ExternalStorageProvider.
 */
public static boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is DownloadsProvider.
 */
public static boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is MediaProvider.
 */
public static boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is Google Photos.
 */
public static boolean isGooglePhotosUri(Uri uri) {
    return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date(heightDiff));
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    File imageFile = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );
    return imageFile;
}

&现在在WebViewChromeClient中---

& now in the WebViewChromeClient ---

browser.setWebChromeClient(new WebChromeClient() {

browser.setWebChromeClient(new WebChromeClient() {

                // For Android 5.0
                public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
                    System.out.println("in 5.0");

                    // Double check that we don't have any existing callbacks
                    if (mFilePathCallback != null) {
                        mFilePathCallback.onReceiveValue(null);
                    }
                    mFilePathCallback = filePath;
                    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                        // Create the File where the photo should go
                        File photoFile = null;
                        try {
                            photoFile = createImageFile();
                            takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
                        } catch (IOException ex) {
                            // Error occurred while creating the File
                          //  Log.e(TAG, "Unable to create Image File", ex);
                        }
                        // Continue only if the File was successfully created
                        if (photoFile != null) {
                            mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
                            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                                    Uri.fromFile(photoFile));
                        } else {
                            takePictureIntent = null;
                        }
                    }
                    Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
                    contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
                    contentSelectionIntent.setType("image/*");
                    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, "Image Chooser");
                    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
                    startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
                    return true;
                }
                // openFileChooser for Android 3.0+
                public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
                    System.out.println("in 3.0+");
                    mUploadMessage = uploadMsg;
                    // Create AndroidExampleFolder at sdcard
                    // Create AndroidExampleFolder at sdcard
                    File imageStorageDir = new File(
                            Environment.getExternalStoragePublicDirectory(
                                    Environment.DIRECTORY_PICTURES)
                            , "AndroidExampleFolder");
                    if (!imageStorageDir.exists()) {
                        // Create AndroidExampleFolder at sdcard
                        imageStorageDir.mkdirs();
                    }
                    // Create camera captured image file path and name
                    File file = new File(
                            imageStorageDir + File.separator + "IMG_"
                                    + String.valueOf(System.currentTimeMillis())
                                    + ".jpg");
                    mCapturedImageURI = Uri.fromFile(file);


                    //

                    // Camera capture image intent
                    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/*");
                    // Create file chooser intent
                    Intent chooserIntent = Intent.createChooser(i, "Image Chooser");
                    // Set camera intent to file chooser
                    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS
                            , new Parcelable[] { captureIntent });
                    // On select image call onActivityResult method of activity






                    startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
                }
                // openFileChooser for Android < 3.0
                public void openFileChooser(ValueCallback<Uri> uploadMsg) {
                    System.out.println("in <3.0");
                    openFileChooser(uploadMsg, "");
                }

                // openFileChooser for other Android versions
                public void openFileChooser(ValueCallback<Uri> uploadMsg,
                        String acceptType, String capture) {
                    System.out.println("in OTHER");
                    openFileChooser(uploadMsg, acceptType);

                }

这篇关于openFileChooser Android 4.4.4缺少文件名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆