【问题标题】:Android WebView utilizing Camera and GPS使用相机和 GPS 的 Android WebView
【发布时间】:2012-12-10 14:23:44
【问题描述】:

我在Android浏览器中使用WebView,但想知道是否有人将浏览器与html5一起使用以使用本地设备的相机和gps? 或者我是否需要为此与 Java 源代码建立 Javascript 连接?

这也适用于 IOS 吗?

这是,没有使用 PhoneGap。

最好, 亨里克

【问题讨论】:

标签: javascript android android-webview


【解决方案1】:

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

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

2///添加这个函数

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    switch(requestCode)
    {
        case TAKE_PICTURE:
            if(resultCode == Activity.RESULT_OK)
            {
                Uri mypic = picUri;
                mUploadMessage.onReceiveValue(mypic);
                mUploadMessage = null;
            }
            else
            {
                mUploadMessage.onReceiveValue(null);
                mUploadMessage = null;
                return;
            }

        default:
        {
            return;
        }   
    }
}   

3// HTML 看起来像这样

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

以上代码将打开原生相机应用。

附:这是来自不同来源的代码的混合。

【讨论】:

  • 嗨@Christian,Uri mypic = picUri; 行引用了picUri 未在onActivityResult 范围内定义的变量。由于它没有 m 前缀,我不明白它不是一个类字段。那么,这是一个错误吗?它应该具有哪个值?
  • 嘿哈维尔,对不起。将该变量定义为私有字段。示例:私有 Uri picUri;.
  • 谢谢@Christian,这就是我想的:) 我现在遇到了你所说的myWebView 的问题。你从哪里得到它?我试图在public class MainActivity extends CordovaActivityonCreate 方法中将其声明为:WebView webView = new WebView(this); 但它不会启动图像捕获意图:-/ 另一种可能性是从@ 调用setWebChromeClient 方法987654333@ 继承自 CordovaActivity 父级,但它是 CordovaWebView 并且它确实具有 setWebChromeClient 方法:S
  • 我已经找到了解决方案。为了显示完整的代码,我已经发布了这个问题的答案。感谢您的回答@Christian!
  • 很抱歉我的回复晚了@JavierCane。感谢您更新解决方案。干杯!
【解决方案2】:

值得指出这里显示的代码应该放在哪里,因为它对于新手来说并不明显 - 它位于您的 Activity 类中,即

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) {  
                ...
            }
        });
    }
}

【讨论】:

    【解决方案3】:

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

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

    此外,基于this other answer,我必须为Android 4.1 指定openFileChooser 方法,而对于Android 5.0+,我必须指定onShowFileChooser 方法。

    对了,我把onActivityResult的方法修改如下:

        @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;
                }
            }
        }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-30
      • 1970-01-01
      • 1970-01-01
      • 2017-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多