I'm developing an app that has to take pictures from the camera and upload them to a FireBase database. However, when I create a temporary file and try to get the image from the storage to the ImageView I get the error:
2022-05-18 11:14:18.596 24790-24790/com.example.apptonia D/Exception: /storage/emulated/0/Pictures/.temp/picture8489350187277543939.jpg: open failed: EACCES (Permission denied)
I have been trying to solve the issue adding several permissions to the manifest as suggested in other similar questions, also adding code to the Activity. However, it doesnt work.
Here's my code for the activity:
...
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.OnProgressListener;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import java.io.ByteArrayOutputStream;
import java.io.File;
public class TakePhotoActivity extends AppCompatActivity {
private ImageView image;
private Button takePhotoButton, guardarButton;
private Bitmap photoTaken;
private Uri mImageUri;
static final int REQUEST_IMAGE_CAPTURE = 1;
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_take_photo);
guardarButton = findViewById(R.id.buttonGuardar);
image = findViewById(R.id.image);
takePhotoButton = findViewById(R.id.takePhotoButton);
takePhotoButton.setOnClickListener(v -> {
Log.d("LOG", "CLICK BUTTON");
dispatchTakePictureIntent();
});
FirebaseStorage storage = FirebaseStorage.getInstance();
guardarButton.setOnClickListener(v -> {
StorageReference storageRef = storage.getReference("/" + StaticUser.mail + "/" +
StaticUser.year + "/" + StaticUser.getTrimestre() + "/" + StaticUser.tipo + "/" +
StaticUser.getFecha() + StaticUser.getRandomString(40));
//image.setDrawingCacheEnabled(true);
//image.buildDrawingCache();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
photoTaken.compress(Bitmap.CompressFormat.JPEG, 80, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = storageRef.putBytes(data);
uploadTask.addOnFailureListener(exception -> Toast.makeText(getApplicationContext(),
"Subida incorrecta", Toast.LENGTH_LONG).show());
uploadTask.addOnSuccessListener(taskSnapshot -> {
// taskSnapshot.getMetadata() contains file metadata such as size, content-type, etc.
// ...
Toast.makeText(getApplicationContext(),
"Subida correcta!", Toast.LENGTH_LONG).show();
Intent intent = new Intent(this, WelcomeActivity.class);
startActivity(intent);
finish();
});
uploadTask.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
@Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
Toast.makeText(getApplicationContext(),
"Subiendo foto... " + progress + "%", Toast.LENGTH_SHORT).show();
}
});
});
}
private void dispatchTakePictureIntent() {
/*
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
*/
try
{
verifyStoragePermissions(this);
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
// place where to store camera taken picture
Log.d("LOG", "CREATING PHOTO INTENT");
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photo;
Log.d("LOG", "CREATING TEMPORARY FILE");
photo = this.createTemporaryFile("picture", ".jpg");
Log.d("LOG", "DELETING TEMPORARY FILE");
photo.delete();
mImageUri = Uri.fromFile(photo);
Log.d("LOG", "PUTTING EXTRA IN MEDIASTORE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}
}
catch(Exception e)
{
Log.d("Error", e.getMessage());
Toast.makeText(getApplicationContext(), "Please check SD card! Image shot is impossible!",
Toast.LENGTH_SHORT);
}
}
private File createTemporaryFile(String part, String ext) throws Exception
{
Log.d("LOG", "getting tempDir");
File tempDir= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
tempDir = new File(tempDir.getAbsolutePath()+"/.temp/");
Log.d("LOG", tempDir.getAbsolutePath()+"/.temp/");
if(!tempDir.exists())
{
Log.d("LOG", "creating dir");
tempDir.mkdirs();
}
Log.d("LOG", "returning new file created");
return File.createTempFile(part, ext, tempDir);
}
public void grabImage(ImageView imageView) {
this.getContentResolver().notifyChange(mImageUri, null);
ContentResolver cr = this.getContentResolver();
Bitmap bitmap;
try {
bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, mImageUri);
imageView.setImageBitmap(bitmap);
} catch (Exception e) {
Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT).show();
Log.d("Exception", e.getMessage());
}
}
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
try {
ContentResolver cr = this.getContentResolver();
Bitmap imageBitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, mImageUri);
this.grabImage(image);
photoTaken = imageBitmap;
image.setImageBitmap(imageBitmap);
}
catch (Exception e) {
Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT).show();
Log.d("Exception", e.getMessage());
}
}
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.apptonia">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="Manifest.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="Manifest.permission.READ_EXTERNAL_STORAGE" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:preserveLegacyExternalStorage="true"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppTonia"
android:usesCleartextTraffic="true"
tools:targetApi="m">
<activity
android:name=".TakePhotoActivity"
android:exported="false" />
<activity
android:name=".SelectFamilyActivity"
android:exported="false" />
<activity
android:name=".MainActivity$SelectFamilyActivity"
android:exported="false" />
<activity
android:name=".WelcomeActivity"
android:exported="false"
android:label="@string/title_activity_welcome"
android:theme="@style/Theme.AppTonia.NoActionBar" />
<activity
android:name=".RegistroActivity"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
from Take a photo and saving it in full size
No comments:
Post a Comment