0

I designed one app, when I click on it, the camera will open. I can capture a photo but I am unable to see it. It is not saving. I am a beginner and started learning android now. Can anyone help me here..?

Added flags to grant permission but that is also not working.

MainActivity code

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

Manifest file

<?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>

Error Log

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)

1 Answers1

0

Changed the full code by referring to android documentation.

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>
  • Still no good. If the user cancels the operation (does not take a picture) you are left withy an empty file. Please check that. `File image = File.createTempFile(`. Dont crreate the file ! The only thing you need is a FIle instance with the rigth path. – blackapps Nov 10 '19 at 10:22
  • Better `File image = new File(storageDir, imageFileName + ".jpg");` – blackapps Nov 10 '19 at 10:24
  • `} catch (IOException ex){ ex.printStackTrace(); }` You should at least display a toast to the user to inform about the exception. On Android Q this code will allways fail so its important to inforn the user and probably yourself. – blackapps Nov 10 '19 at 10:28
  • @blackapps I tried what you said (i opened and closed my app without taking any picture) but there is no file created, I checked. Kindly check the link [link](https://stackoverflow.com/questions/17150597/file-createtempfile-vs-new-file) – ghost deathrider Nov 10 '19 at 12:40
  • I dont know what you want to see me in that link but i repeat: `File.createTempFile( imageFileName, /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ );` That creates an empty file already. Opening and closing your app is not enough of course. You should start the camera app and then not take a picture. You are left with an empty file. Problem has been reported a hundred times. – blackapps Nov 10 '19 at 12:45