Android Studio Webview没有调用照片库

时间:2018-02-06 11:12:57

标签: android webview

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

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/");

和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();
        }
    }
}

并在清单文件中

<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开发的新手。

1 个答案:

答案 0 :(得分:1)

我认为你最好在WebChromeClient $ onShowFileChooser中做到这一点。

在您的代码中,您应该在mainthread中执行此操作。尝试在choosePhoto方法中添加runOnUIThread。

在这里添加demo(LOLLIPOP下面的Build.VERSION_CODES使用不同的方法):

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:

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

你可以使用它添加onActivityResult案例。

在html中:

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