java - Android 应用程序 - 带有相机应用程序的弹出菜单

标签 java android android-intent webview android-camera

我一直在尝试让我的第一个 Android 应用程序运行起来。我有一个使用 webview 的 Activity ,我用它来打开带有 html 表单的网页。

“选择文件”按钮(用于文件输入)工作时遇到了一些麻烦,但由于此处发布的帮助,我终于解决了这个问题 File Upload in WebView 。 从那里开始,我几乎使用 Main Activity java code他们在 Github 上提供。

我的实际问题是,当单击文件输入按钮时,我没有看到用户使用设备相机的选项,而这是我想要的。起初我认为这可能与必须请求应用程序的相机权限有关,但我实现了它,但我错了。这里的问题是我对获取弹出菜单的 Intent 没有经验,例如:

 Intent i = new Intent(Intent.ACTION_GET_CONTENT);
 i.addCategory(Intent.CATEGORY_OPENABLE);
 i.setType("image/*");

关于如何找到“相机”选项的一些指导,我们将不胜感激。

让我向您展示我的意思,在 Chrome 上打开相同的 html 表单,并在 2 个不同的 Android 操作系统版本(4.4.4 和 6.0)上打开我的应用程序。使用我的 Samsung Galaxy Tab,运行 Android 4.4.4。在 Google Chrome 上打开包含 html 表单的页面时,单击选择文件按钮,I get this menu

这就是我想要在我的应用程序中拥有的内容

使用相同的 URL 获取并在单击“选择文件”按钮时使用我的 Web View 在我的应用程序(4.4.4 上)中显示它,I get this menu

(此外,我尝试在 Android 6.0 模拟器上点击我的应用程序上的“选择文件”按钮 and it goes straight to the gallery ,但那里没有“相机”选项):

这是代码的相关部分:

        //For Android 4.1+
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
            mUM = uploadMsg;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("image/*");
            MainActivity.this.startActivityForResult(Intent.createChooser(i, "Choose an Image please"), MainActivity.FCR);
        }
        //For Android 5.0+
        public boolean onShowFileChooser(
                WebView webView, ValueCallback<Uri[]> filePathCallback,
                FileChooserParams fileChooserParams){
            if(mUMA != null){
                mUMA.onReceiveValue(null);
            }
            mUMA = filePathCallback;
            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            if(takePictureIntent.resolveActivity(MainActivity.this.getPackageManager()) != null){
                File photoFile = null;
                try{
                    photoFile = createImageFile();
                    takePictureIntent.putExtra("PhotoPath", mCM);
                }catch(IOException ex){
                    Log.e(TAG, "Image file creation failed", ex);
                }
                if(photoFile != null){
                    mCM = "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, FCR);
            return true;
        }

最佳答案

这是一个辅助函数,可提供相机和媒体选择器选择器 Intent 。我认为您具体询问的是 ACTION_IMAGE_CAPTURE,即此示例代码 fragment 的第一部分。

private Intent getPhotoChooserIntent(String acceptType, String capture)
{
 try
 {
    //---------------------------------------------------------------------
    // camera Intent 
    //---------------------------------------------------------------------
    Intent intentCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    Calendar cal = Calendar.getInstance();
    SimpleDateFormat sdf = new SimpleDateFormat("HHmmss", Locale.US);

    // path to picture
    File dirPhotos = mContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File photo = new File(String.format("%s/Photo_%s.jpg", dirPhotos.getAbsolutePath(), sdf.format(cal.getTime())));
    mPhoto = Uri.fromFile(photo);
    intentCamera.putExtra (MediaStore.EXTRA_OUTPUT, mPhoto);

    // pass "camera" in this parameter for a Camera only picker 
    if (capture.equalsIgnoreCase("camera"))
    {
     if (intentCamera.resolveActivity(mContext.getPackageManager()) != null)
        return (intentCamera);
     return (null);
    }

    //---------------------------------------------------------------------
    // media picker Intent
    //---------------------------------------------------------------------
    Intent intentPicker = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

    // aggregate list of resolved intents
    List<Intent> intentsList = new ArrayList<>();

    List<ResolveInfo> resInfo = mContext.getPackageManager().queryIntentActivities(intentPicker, 0);
    for (ResolveInfo resolveInfo : resInfo)
    {
     Intent intentTarget = new Intent(intentPicker);
     intentTarget.setPackage(resolveInfo.activityInfo.packageName);
     intentsList.add(intentTarget);
    }   

    if (intentCamera.resolveActivity(mContext.getPackageManager()) != null)
     intentsList.add(intentCamera);

    if (intentsList.size() > 0)
    {
     Intent intentChooser = Intent.createChooser(intentsList.remove(intentsList.size() - 1), mContext.getResources().getString(R.string.mediapicker));
     intentChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentsList.toArray(new Parcelable[]{}));
     return (intentChooser);
    }
 }
 catch (Exception e)
 {
    e.printStackTrace();
 }
 return (null);
}

假设mContext = Activity 上下文。 mPhoto 是一个 Uri 类型的类变量,用于在 onActivityResult 处理程序中访问从相机获取的图片。

希望这有帮助!

关于java - Android 应用程序 - 带有相机应用程序的弹出菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41941789/

相关文章:

java - 我想返回类型 int this.Time 对象我该怎么做

应用程序的 Android 调试/发布版本

java - 当到达 RecyclerView 底部时从 API 接收下一页电影?

android - 闹钟管理器在 Android 6.0 上无法在后台运行

android - 从 bundle 中删除条目(即附加内容)似乎无法与后退按钮结合使用

android - 获取基本 Activity Intent 中的当前 Activity

java - 哪种递归方法更好?为什么对于整数的反转数字?

java - 创建一个新的反向 Java 数组

java - 在 hazelcast 和 Java 中以编程方式设置 Near Cache 验证 Near 缓存是否从本地缓存返回数据

Android volley 错误 : "Trust anchor for certification path not found", 仅在真实设备中,而不是模拟器