Android Studio Webview 不调用照片库 [英] Android Studio Webview not calling photo gallery

查看:32
本文介绍了Android Studio Webview 不调用照片库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 Web 应用程序中,我正在加载一个页面,该页面中有一个调用相册/照片库的按钮,但它根本不起作用.请帮忙,这是我目前的代码.

in my Web application i am loading a page in which page there is a button which calls a album/photo gallery but its not working at all. please help, here is my code so far.

webView = (WebView) findViewById(R.id.webview);
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webView.setWebViewClient(new WebViewClient());
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setLoadWithOverviewMode(true);
        webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
        webView.setScrollbarFadingEnabled(false);
        webView.getSettings().setBuiltInZoomControls(true);
        webView.getSettings().setPluginState(WebSettings.PluginState.ON);
        webView.getSettings().setAllowFileAccess(true);
        webView.getSettings().setSupportZoom(true);
        webView.addJavascriptInterface(new MyJavascriptInterface(this), "Android");
        webView.loadUrl("https://URL/");

和外部 onCreate

and outsite onCreate

class MyJavascriptInterface
{

    Context mContext;

    /** Instantiate the interface and set the context */
    MyJavascriptInterface(Context c)
    {
        mContext = c;
    }

    /** Show a toast from the web page */
    @JavascriptInterface
    public void showToast(String toast)
    {
        Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
    }

    @JavascriptInterface
    public String choosePhoto()
    {
        // TODO Auto-generated method stub
        String file = "test";
        Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
        photoPickerIntent.setType("image/*");
        startActivityForResult(photoPickerIntent, SELECT_PHOTO);
        return file;
    }

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent)
{
    switch (requestCode)
    {
        case SELECT_PHOTO:
            if (resultCode == RESULT_OK)
            {
                Uri selectedImage = intent.getData();
                webView.loadUrl("javascript:setFileUri('" + selectedImage.toString() + "')");
                String path = getRealPathFromURI(this, selectedImage);
                webView.loadUrl("javascript:setFilePath('" + path + "')");
            }
    }

}

public String getRealPathFromURI(Context context, Uri contentUri)
{
    Cursor cursor = null;
    try
    {
        String[] proj = { MediaStore.Images.Media.DATA };
        cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }
    finally
    {
        if (cursor != null)
        {
            cursor.close();
        }
    }
}

在 Manifest 文件中

and inside Manifest file

<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />

我需要访问照片/相机以使用简单的 WebView 从图库中选择图像.请原谅我的英语和我的代码,因为我仍然是一个学习者,并且是 android 开发的新手.

i need to access photos/camera to select images from gallery using a simple WebView. please forgive my English and my code because i am a still a learner and new to android development.

推荐答案

我认为你最好在 WebChromeClient$onShowFileChooser 中这样做.

I think you'd better do this in WebChromeClient$onShowFileChooser.

在您的代码中,您应该在主线程中执行此操作.尝试在您的 choosePhoto 方法中添加 runOnUIThread.

In your code, you should do this in mainthread. Try add runOnUIThread in your choosePhoto method.

在此处添加演示(LOLLIPOP 下面的 Build.VERSION_CODES 使用不同的方法):

Add demo here (Build.VERSION_CODES below LOLLIPOP use different method):

public class MyChromeCientWithFileChooser extends WebChromeClient implements ActivityResultCaseDelegate {

private int FILE_CHOOSER_REQUEST_CODE = 1001;

private Activity activity;
private ValueCallback<Uri[]> filePathCallback;
private Uri mediaUri;

public MyChromeCientWithFileChooser(Activity activity) {
    this.activity = activity;
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
    String type;
    if (fileChooserParams != null && fileChooserParams.getAcceptTypes() != null && fileChooserParams.getAcceptTypes().length > 0) {
        type = !TextUtils.isEmpty(fileChooserParams.getAcceptTypes()[0]) ? fileChooserParams.getAcceptTypes()[0] : "*/*" ;
        this.filePathCallback = filePathCallback;
    } else {
        return false;
    }
    proceedOnType(type, fileChooserParams.isCaptureEnabled());
    return true;
}

private void proceedOnType(String type, final boolean isCaptureEnabled) {
    if (type.toLowerCase().contains("image")) {
        pickImage(isCaptureEnabled); // need to make sure you have "android.permission.CAMERA", "android.permission.WRITE_EXTERNAL_STORAGE" permission
    } else if (type.toLowerCase().contains("video")) {
        makeVideo(); // need to make sure you have "android.permission.CAMERA", "android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.RECORD_AUDIO" permission
    } else {
        openDefaultChooser(type); // need to make sure you have "android.permission.WRITE_EXTERNAL_STORAGE" permission
    }
}

private void openDefaultChooser(String type) {
    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
    i.addCategory(Intent.CATEGORY_OPENABLE);
    i.setType(type);
    activity.startActivityForResult(Intent.createChooser(i, "File Chooser"), FILE_CHOOSER_REQUEST_CODE);
}

private void pickImage(boolean captureOnly) {
    if (captureOnly) {
        Intent iImageCapture = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        mediaUri = Uri.fromFile(new File(getImageCaptureCachePath()));
        iImageCapture.putExtra("output", mediaUri);
        activity.startActivityForResult(Intent.createChooser(iImageCapture, "Image Chooser"), FILE_CHOOSER_REQUEST_CODE);
    } else {
        Intent iChooseImage = new Intent(Intent.ACTION_GET_CONTENT);
        iChooseImage.addCategory(Intent.CATEGORY_OPENABLE);
        iChooseImage.setType("image/*");

        Intent iImageCapture = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        mediaUri = Uri.fromFile(new File(getImageCaptureCachePath()));
        iImageCapture.putExtra("output", mediaUri);

        Intent iChooser = Intent.createChooser(iChooseImage, "Pick a photo");
        iChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{iImageCapture});

        activity.startActivityForResult(Intent.createChooser(iChooser, "Image Chooser"), FILE_CHOOSER_REQUEST_CODE);
    }
}

private void makeVideo() {
    Intent iImageCapture = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
    mediaUri = Uri.fromFile(new File(getVideoCaptureCachePath()));
    iImageCapture.putExtra("output", mediaUri);
    activity.startActivityForResult(Intent.createChooser(iImageCapture, "Image Chooser"), FILE_CHOOSER_REQUEST_CODE);
}

private String getImageCaptureCachePath() {
    return "cahced_photo_" + System.currentTimeMillis() + ".jpg";
}

private String getVideoCaptureCachePath() {
    return "cahced_video_" + System.currentTimeMillis() + ".mp4"; 
}

private void cleanCacheUri() {
    filePathCallback = null;
    mediaUri = null;
}

@Override
public int caseRequestCode() {
    return FILE_CHOOSER_REQUEST_CODE;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (filePathCallback == null) {
        return;
    }
    if (resultCode != RESULT_OK) {
        filePathCallback.onReceiveValue(null);
        cleanCacheUri();
        return;
    }
    Uri result = data == null ? null : data.getData();
    handleResultAboveLollipop(result);
    cleanCacheUri();
}

private void handleResultAboveLollipop(Uri result) {
    if (filePathCallback == null) {
        return;
    }
    if (result != null) {
        // handle image choose from file
        String path = WebFileChooseHelper.getPath(activity, result);
        if (TextUtils.isEmpty(path)) {
            filePathCallback.onReceiveValue(null);
            return;
        }

        Uri uri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Context appContext = TJAppScopeComponents.getAppContext();
            uri = FileProvider.getUriForFile(appContext, appContext.getPackageName() + ".provider", new File(path));
        } else {
            uri = Uri.fromFile(new File(path));
        }

        filePathCallback.onReceiveValue(new Uri[]{uri});
    } else {
        // handle capture
        filePathCallback.onReceiveValue(new Uri[]{mediaUri});
    }
}
}

和 ActivityResultCaseDelegate :

and the ActivityResultCaseDelegate :

public interface ActivityResultCaseDelegate {
int caseRequestCode();
void onActivityResult(int requestCode, int resultCode, Intent data);
}

您可以使用此添加 onActivityResult 案例.

you can add onActivityResult case using this.

在 html 中:

<input type="file" accept="image/*" capture="camera">

这篇关于Android Studio Webview 不调用照片库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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