我的相机应用程序正在拍照但无法打开/保存。当我打开它只是空白

Posted

技术标签:

【中文标题】我的相机应用程序正在拍照但无法打开/保存。当我打开它只是空白【英文标题】:My camera app is taking pictures but unable to open/save. When i open it is just blank 【发布时间】:2020-03-05 22:14:12 【问题描述】:

我设计了一个应用程序,当我点击它时,相机会打开。我可以拍摄照片,但我无法看到它。这不是节省。我是初学者,现在开始学习android。谁能在这里帮我..?

添加了授予权限的标志,但这也不起作用。

MainActivity 代码

package com.example.mycameraapp;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;

import java.io.File;

public class MainActivity extends AppCompatActivity 

    private File output = null;
    private static final int CONTENT_REQUEST = 1745;
    private Uri photoURI;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);

        output = new File(dir, "YOUR_APP_NAME" + File.separator + "YOUR_FILE_NAME");

        photoURI = FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID + ".provider", output);

        i.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
        i.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
        startActivityForResult(i, CONTENT_REQUEST);
    

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) 
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CONTENT_REQUEST) 
            if (resultCode == RESULT_OK) 
                Intent i = new Intent(Intent.ACTION_VIEW);

                i.setDataAndType(photoURI, "image/jpeg");
                i.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                startActivity(i);
                finish();
            
        
    

清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.mycameraapp">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <provider
            android:authorities="com.example.mycameraapp.provider"
            android:name="androidx.core.content.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>

    </application>

</manifest>

错误日志

E/PICTURES: com.diune.media.data.L - fail to open: content://com.example.mycameraapp.provider/external_files/DCIM/YOUR_APP_NAME/YOUR_FILE_NAME
    java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
        at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:144)
        at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:698)
        at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1458)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1295)
        at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:1148)
        at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:1102)
        at com.diune.media.data.L.<init>(SourceFile:7)
        at com.diune.media.data.M.a(SourceFile:5)
        at com.diune.media.data.g.a(SourceFile:9)
        at com.diune.media.app.k.a(SourceFile:16)
        at com.diune.media.app.BigGalleryFragment.a(SourceFile:29)
        at com.diune.pictures.ui.b.run(SourceFile:6)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:215)
        at android.app.ActivityThread.main(ActivityThread.java:6939)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:870)

【问题讨论】:

"YOUR_APP_NAME" + File.separator + "YOUR_FILE_NAME"。目录YOUR_APP_NAME 是否存在?它不会为你制作的。您首先必须自己创建它。 @blackapps 是的,我已经创建了目录,但仍然显示相同的错误 您是否检查过该文件是否存在于该文件夹中? @blackapps 是的,我已经检查过了,没有文件存在。我使用了下面的方法,现在一切正常。 【参考方案1】:

参考android文档修改了完整代码。

package com.example.mycameraapp;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import static com.example.mycameraapp.BuildConfig.APPLICATION_ID;

public class MainActivity extends AppCompatActivity 

    private File output = null;
    private static final int REQUEST_TAKE_PHOTO = 1;
    private Uri photoURI;
    private String currentPhotoPath;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if(takePictureIntent.resolveActivity(getPackageManager()) != null) 

            File photoFile = null;
            try 
                photoFile = createImageFile();
             catch (IOException ex)
                ex.printStackTrace();
            
            if(photoFile != null) 
                photoURI = FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID + ".provider", photoFile);
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
            
        

    

    private File createImageFile() throws IOException 
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        currentPhotoPath = image.getAbsolutePath();
        return image;
    

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) 
                Intent i = new Intent(Intent.ACTION_VIEW);

                i.setDataAndType(photoURI, "image/jpeg");
                i.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                startActivity(i);
                finish();
        
    

provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android = "http://schemas.android.com/apk/res/android">
    <external-path name = "my_images" path = "."/>
</paths>

【讨论】:

还是不行。如果用户取消操作(不拍照),您将留下一个空文件。请检查一下。 File image = File.createTempFile(。不要创建文件!您唯一需要的是具有正确路径的 FIle 实例。 更好File image = new File(storageDir, imageFileName + ".jpg"); catch (IOException ex) ex.printStackTrace(); 您至少应该向用户显示一个 toast 以告知异常。在 Android Q 上,此代码总是会失败,因此通知用户和您自己很重要。 @blackapps 我试过你说的(我打开并关闭了我的应用程序,没有拍任何照片)但没有创建文件,我检查了。请检查链接link 我不知道你想在那个链接中看到什么,但我重复一遍:File.createTempFile( imageFileName, /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ ); 这已经创建了一个空文件。当然,打开和关闭您的应用程序是不够的。您应该启动相机应用程序,然后不要拍照。你留下了一个空文件。问题已被报告一百次。

以上是关于我的相机应用程序正在拍照但无法打开/保存。当我打开它只是空白的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 上拍照并保存在 SQLite 数据库中

有没有办法打开相机并在屏幕上查看它并使其无法拍照或录制视频。

Cordova 相机 - 无法访问库

相机意图打开相机应用程序(仅第一次)

从我的相机应用程序拍照后,图片未保存到图库

react native如何打开相机拍照?