Javascript 利用摄像头和GPS的Android WebView

Javascript 利用摄像头和GPS的Android WebView,javascript,android,android-webview,Javascript,Android,Android Webview,我正在安卓浏览器中玩WebView,但我想知道是否有人将该浏览器与html5一起用于使用本地设备的摄像头和gps? 或者,我需要为此与Java源代码建立Javascript连接吗 这在IOS中也适用吗 这就是,不使用PhoneGap 最好的, 亨里克可能有点晚了,但以防万一,我会给你举个例子。 (照相机) 1///将此添加到webChromeClient myWebView.setWebChromeClient(new WebChromeClient() { public void o

我正在安卓浏览器中玩WebView,但我想知道是否有人将该浏览器与html5一起用于使用本地设备的摄像头和gps? 或者,我需要为此与Java源代码建立Javascript连接吗

这在IOS中也适用吗

这就是,不使用PhoneGap

最好的,
亨里克

可能有点晚了,但以防万一,我会给你举个例子。 (照相机)

1///将此添加到webChromeClient

myWebView.setWebChromeClient(new WebChromeClient() 
{
    public void openFileChooser( ValueCallback<Uri> uploadMsg, String acceptType ) 
    { 
        mUploadMessage = uploadMsg;
        Intent cameraIntent = new Intent("android.media.action.IMAGE_CAPTURE");
        Calendar cal = Calendar.getInstance();
        cal.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("HHmmss");
        File photo = new File(Environment.getExternalStorageDirectory(), sdf.format(cal.getTime()) +".jpg");
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
        picUri = Uri.fromFile(photo);
        startActivityForResult(cameraIntent, TAKE_PICTURE);                 
    }
}); 
3//HTML如下所示

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

以上代码将打开本机相机应用程序


另外,这是来自不同来源的代码的混合。

值得指出此处显示的代码应该存在于何处,因为这对于新手来说并不明显-它出现在您的活动类中,即

public class MyActivity extends Activity {

    @Override  
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        ...
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {

        ...

        myWebView.setWebChromeClient(new WebChromeClient()
        {
            public void openFileChooser(ValueCallback<Uri> uploadMsg) {  
                ...
            }
        });
    }
}
公共类MyActivity扩展活动{
@凌驾
受保护的void onActivityResult(int请求代码、int结果代码、意图数据){
...
}
@凌驾
创建时的公共void(Bundle savedInstanceState){
...
myWebView.setWebChromeClient(新WebChromeClient()
{
public void openFileChooser(ValueCallback uploadMsg){
...
}
});
}
}

在我的例子中,我重写了
makeWebViewEngine
方法,以便能够修改
CordovaWebViewEngine
强制转换为
SystemWebViewEngine
,如下所示(基于):


感谢@Will和@Christian在这个答案中指出了好的方向(顺便说一句:)

发布后,你会找到你想要的。。。有没有人知道什么时候会这样做?嗨@Christian,
urimypic=picUri行引用未在
onActivityResult
范围中定义的
picUri
变量。由于它没有
m
前缀,我不理解它不是一个类字段。那么,这是一个错误吗?它应该有什么价值?哈维尔,对不起。将该变量定义为私有字段。示例:私有Uri picUri;。谢谢@Christian,这就是我所想的:)我现在对你所说的
myWebView
有麻烦了。你在哪里买的?我试图在
public类main活动中将其声明为:
WebView WebView=newwebview(this)
但它不会启动图像捕获目的:-/另一种可能是从继承自
CordovaActivity
父对象的
appView
调用
setWebChromeClient
方法,但是它是一个
CordovaWebView
并且它没有
setWebChromeClient
方法:我已经找到了解决方案。为了显示完整的代码,我发布了这个问题的答案。谢谢你的回答@Christian!很抱歉我迟了回复@JavierCane。感谢您更新解决方案。干杯
public class MyActivity extends Activity {

    @Override  
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        ...
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {

        ...

        myWebView.setWebChromeClient(new WebChromeClient()
        {
            public void openFileChooser(ValueCallback<Uri> uploadMsg) {  
                ...
            }
        });
    }
}
public class MainActivity extends CordovaActivity {

    private static final int FILECHOOSER_RESULTCODE = 12345;

    private ValueCallback<Uri> mUploadMessage;

    private Uri mPicUri;

    private ValueCallback<Uri[]> mFilePathCallback;

    private String mCameraPhotoPath;

    @Override
    protected CordovaWebViewEngine makeWebViewEngine() {
        SystemWebViewEngine systemWebViewEngine = (SystemWebViewEngine) super.makeWebViewEngine();

        SystemWebView systemWebView = (SystemWebView) systemWebViewEngine.getView();

        systemWebView.setWebChromeClient(new SystemWebChromeClient(systemWebViewEngine) {
            // For Android 4.1
            public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
                mUploadMessage = uploadMsg;
                Intent cameraIntent = new Intent("android.media.action.IMAGE_CAPTURE");
                Calendar cal = Calendar.getInstance();
                cal.getTime();
                SimpleDateFormat sdf = new SimpleDateFormat("HHmmss");
                File photo = new File(Environment.getExternalStorageDirectory(), sdf.format(cal.getTime()) + ".jpg");
                cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
                mPicUri = Uri.fromFile(photo);

                startActivityForResult(cameraIntent, FILECHOOSER_RESULTCODE);
            }

            // For Android 5.0+
            public boolean onShowFileChooser(
                    WebView webView, ValueCallback<Uri[]> filePathCallback,
                    WebChromeClient.FileChooserParams fileChooserParams) {

                // Double check that we don't have any existing callbacks
                if (mFilePathCallback != null) {
                    mFilePathCallback.onReceiveValue(null);
                }
                mFilePathCallback = filePathCallback;

                // Set up the take picture intent
                Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                if (takePictureIntent.resolveActivity(MainActivity.this.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;
                    }
                }

                // Set up the intent to get an existing image
                Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
                contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
                contentSelectionIntent.setType("image/*");

                // Set up the intents for the Intent chooser
                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, MainActivity.FILECHOOSER_RESULTCODE);

                return true;
            }
        });

        return systemWebViewEngine;
    }

    // …

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Set by <content src="index.html" /> in config.xml
        loadUrl(launchUrl);
    }
}
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (Build.VERSION.SDK_INT >= 21) {

            if (requestCode != FILECHOOSER_RESULTCODE || mFilePathCallback == null) {
                super.onActivityResult(requestCode, resultCode, intent);
                return;
            }

            Uri[] results = null;

            // Check that the response is a good one
            if (resultCode == Activity.RESULT_OK) {

                String dataString = intent.getDataString();
                if (dataString != null) {
                    results = new Uri[]{Uri.parse(dataString)};
                } else {
                    // If there is not data, then we may have taken a photo
                    if (mCameraPhotoPath != null) {
                        results = new Uri[]{Uri.parse(mCameraPhotoPath)};
                    }
                }
            }

            mFilePathCallback.onReceiveValue(results);
            mFilePathCallback = null;
        } else {
            if (requestCode == FILECHOOSER_RESULTCODE) {
                if (null == this.mUploadMessage) {
                    return;
                }

                Uri result;
                if (resultCode != RESULT_OK) {
                    result = null;
                } else {
                    result = intent == null ? this.mPicUri : intent.getData(); // retrieve from the private variable if the intent is null
                }

                this.mUploadMessage.onReceiveValue(result);
                this.mUploadMessage = null;
            }
        }
    }