【问题标题】:Android App- Popup Menu with the Camera AppAndroid 应用程序 - 带有相机应用程序的弹出菜单
【发布时间】:2017-01-30 17:21:53
【问题描述】:

我一直在努力让我的第一个 Android 应用程序运行起来。我有一个使用 webview 的活动,我用它来打开上面有 html 表单的网页。

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

我的实际问题是,当单击文件输入按钮时,我没有让用户使用我想要的设备相机的选项。起初我认为这可能与必须为应用程序请求相机许可有关,但我实现了它,但我错了。这里的问题是我不熟悉 Intents 来获取弹出菜单,例如:

 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)上打开我的应用程序。使用我的三星 Galaxy Tab,运行 Android 4.4.4。在 Google Chrome 上打开一个包含 html 表单的页面时,点击 Choose File 按钮,I get this menu

这就是我想在我的应用中拥有的东西

使用相同的 URL 获取并显示它在我的应用程序中(在 4.4.4 上),使用我的 web 视图,当点击 Choose File 按钮时,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;
        }

【问题讨论】:

    标签: java android android-intent webview android-camera


    【解决方案1】:

    这是一个提供相机和媒体选择器选择器意图的辅助函数。我认为您是在专门询问 ACTION_IMAGE_CAPTURE,即此示例代码 sn-p 的第一部分。

    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 = 活动上下文。 mPhoto 是 Uri 类型的类变量,用于在 onActivityResult 处理程序中访问从相机获取的图片。

    希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      看看this answer by Mario Velasco 是否对您有帮助。

      【讨论】:

        【解决方案3】:

        好的,在此期间我已经解决了部分问题。

        我已经在清单中说明了所需的权限,例如:

        <uses-permission android:name="android.permission.CAMERA"/>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        

        但是,我犯了一个初学者的错误,没有明确要求访问设备的相机和存储,如下所示:

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
                }
            }
        
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                }
            }
        

        适用于 Android 5.0+ 的部分可以正常工作(代码可以开始使用),并且有一个菜单,您可以在其中选择相机或图库中的图片。

        无论哪种方式,我还测试了用户 CSmith 对 5.0+ 的建议,并确认它也有效,所以如果有人遇到这种情况,你可以尝试这是一个可行的替代方案。

        对于早于 5 的 Android 版本,我设法通过单击“选择文件”(但没有图库选项)按钮打开相机应用,并进行了一些更改,如下所示:

        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
                    mUM = uploadMsg;
                    Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    startActivityForResult(i, 1);
                }
        

        我现在正在为 3 和 4 使用这个“修复”。

        【讨论】:

          猜你喜欢
          • 2016-02-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-06-19
          • 2016-03-17
          • 2012-02-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多