【问题标题】:Camera Intent Not Working in Some Devices相机意图在某些设备中不起作用
【发布时间】:2019-08-25 08:22:17
【问题描述】:

在我的应用程序中,有一个按钮可以启动相机意图并将捕获的图像保存在给定路径。它在 Nexus 5X 模拟器中运行良好,但是当我在我的 S8 或 S9 中尝试它时,它不会打开相机,也不会显示任何错误。 如何在我的应用中修复相机意图

private void PictureTakerAction()
    {
        Intent takePic = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if(takePic.resolveActivity(getPackageManager()) != null)
        {
            File photoFile = null;
            photoFile = CreatePhotoFile();

            if(photoFile != null)
            {
                pathToFile = photoFile.getAbsolutePath();
                Uri photoUri = FileProvider.getUriForFile(AddItemActivity.this,"com.airtechsolutions.fileprovider",photoFile);
                takePic.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
                startActivityForResult(takePic,1);
            }
        }
    }

private File CreatePhotoFile()
    {
        String name = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        //File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File storageDir = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File image = null;

        try {
            image = File.createTempFile(name ,".jpg" , storageDir);
        } catch (Exception e) {
            Log.i("File Log", "Exception: " + e.toString());
        }

        return image;
    }

protected void onActivityResult(int requestCode,int resultCode, Intent data)
{   super.onActivityResult(requestCode,resultCode,data);

    if (requestCode == 1)
     {
       Bitmap bitmap = BitmapFactory.decodeFile(pathToFile);
       Image.setImageBitmap(bitmap);
     }
}

【问题讨论】:

  • 什么是photoFile?在您定义的地方发布
  • 我已经用我用于相机意图的代码更新了问题
  • 是否需要将捕获的Bitmap 存储在临时文件中?
  • 我不明白这个问题,但如果你的意思是我需要一个文件来存储图像然后“是的,我需要它显示在我的应用程序中”
  • 检查我的答案。

标签: java android


【解决方案1】:

您的应用中有错误。也就是说,您正在 public 目录中编写临时文件。

存储权限

来自文档:

每个 Android 应用都在访问受限的沙盒中运行。如果应用程序需要使用其自己的沙箱之外的资源或信息,则该应用程序必须请求适当的权限。您通过在app manifest 中列出权限来声明您的应用需要权限,然后请求用户在运行时批准每个权限(在 Android 6.0 及更高版本上)。

甚至不需要使用互联网等权限,因为它们不被认为是危险的。然而,使用相机、存储等的权限是危险的,如果未经用户许可,应用程序可能会侵犯用户的隐私。

您正在做的是在公共目录中创建一个临时文件,这需要写入/读取权限。在 Android 6.0 之前,您无需请求读/写权限即可进行读/写。但是,如果您阅读以上内容,就会发现 Android 6.0 及更高版本需要请求危险权限,这解释了为什么您的代码可以在某些设备上运行。

不要将其存储在特定目录中,如果您正在创建的临时文件只有您可以看到,请执行此操作:

String name = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
//File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
//File storageDir = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);

try {
    return File.createTempFile(name ,".jpg");
} catch (Exception e) {
    Log.i("File Log", "Exception: " + e.toString());
    return null;
}

另外,尝试这样做:

takePic.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

这将在私有目录中创建文件,这意味着您不需要请求存储权限。您现在可以继续编写代码了。

【讨论】:

  • 感谢 Gaurav,但它仍然没有帮助,相同的应用程序在 Google Pixel 中运行良好,但在三星中无法打开相机。文件存储没有问题,因为我面临的问题是我什至无法打开相机来捕获文件。
  • 不走运,现在当我尝试你的代码时它开始崩溃
  • 存储权限没有错误,问题是相机应用程序的意图没有在某些三星设备中打开(似乎没有像空按钮那样发生任何事情)和同一个按钮正在为其他一些设备工作
  • 这可能只是设备问题。
  • 这是我不使用 Storage Dir 时的错误........ 引起:com.android.internal.os.RuntimeInit$MethodAndArgsCaller 的 java.lang.reflect.InvocationTargetException .run(RuntimeInit.java:493) 原因:java.lang.IllegalArgumentException:无法在 android.support.v4.content 中找到包含 /data/data/com.airtechsolutions.logicTraders/cache/20190827_0933031813119456681852017.jpg 的已配置根。 FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:739) at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:418)
【解决方案2】:

我已经解决了这个问题:) 分两步完成

第 1 步:-

在我的 Java 文件中,我将存储过程从

File storageDir = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); 
File image = null;
image = File.createTempFile(name ,".jpg", storageDir);

File outputDir = getApplicationContext().getCacheDir();
File image = null;
image = File.createTempFile(name ,".jpg", outputDir);

第 2 步是我更改了我的文件路径 (res/xml/file_paths)

来自

<Paths >
<external-path
    name = "logixtraders_images"
    path = "Pictures"/> 
</Paths>

<paths>
  <external-path
    name="external"
    path="." />
  <external-files-path
    name="external_files"
    path="." />
  <cache-path
    name="cache"
    path="." />
  <external-cache-path
    name="external_cache"
    path="." />
  <files-path
    name="files"
    path="." />
</paths>

对我来说效果很好

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多