I assume you want to load and save images outside the data folder.
Since the latest 10/11 android versions, this is more difficult because Android is implementing “Scoped Storage”, for security reasons.
Before you could use the method
Environment.getExternalStorageDirectory()
but it’s deprecated above Pie (version 28) It can still be used on Android 10 using
android:requestLegacyExternalStorage=“true”
in the Manifest, but above that, you need another solution. Tomorrow I will look into this. For the moment I’ll leave an updated code I recently wrote for all android versions to upload an image with your build-in android image explorer.
However, you have to set your SDK target from 17 to 29.
import android.net.Uri;
import android.database.Cursor;
import android.content.Intent;
import android.provider.MediaStore;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import android.os.Environment;
import android.graphics.BitmapFactory;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import processing.core.PConstants;
Activity activity;
Context context;
PImage img;
boolean image_loaded;
void setup() {
fullScreen();
background(#F9C454);
fill(#4A3A16);
textSize(38);
textAlign(CENTER);
text("Click to open Image Explorer", width/2, height/3);
activity = this.getActivity();
context = activity.getApplicationContext();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
requestParticularPermission();
}
}
void draw() {
if (image_loaded) {
background(255);
image(img, 0, 0);
}
}
void mousePressed() {
openImageExplorer();
}
@Override
void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1) {
if (resultCode == activity.RESULT_OK) {
if (data != null) {
Uri image_uri = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(image_uri, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String imgDecodableString = cursor.getString(columnIndex);
cursor.close();
println(imgDecodableString);
if (Build.VERSION.SDK_INT >= 28) {
try {
InputStream ips = context.getContentResolver().openInputStream(image_uri);
Bitmap bitmap = BitmapFactory.decodeStream(ips);
img = new PImage(bitmap.getWidth(), bitmap.getHeight(), PConstants.ARGB);
bitmap.getPixels(img.pixels, 0, img.width, 0, 0, img.width, img.height);
img.updatePixels();
image_loaded = true;
}
catch (Exception e) {
e.printStackTrace();
}
} else {
img = loadImage(imgDecodableString);
image_loaded = true;
}
} else {
println("No data");
}
}
}
}
private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE };
private void requestParticularPermission() {
activity.requestPermissions(PERMISSIONS_STORAGE, 2020);
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 2020:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
println("permissions granted");
} else {
println("permissions not granted");
}
break;
default:
activity.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
void openImageExplorer() {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
activity.startActivityForResult(intent, 1);
}