minio/app/src/main/java/de/clkl/android/miniofotoapp/MainActivity.java

206 lines
6.7 KiB
Java

package de.clkl.android.miniofotoapp;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.io.File;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import io.minio.BucketExistsArgs;
import io.minio.ListObjectsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.Result;
import io.minio.UploadObjectArgs;
import io.minio.errors.ErrorResponseException;
import io.minio.errors.InsufficientDataException;
import io.minio.errors.InternalException;
import io.minio.errors.InvalidResponseException;
import io.minio.errors.MinioException;
import io.minio.errors.ServerException;
import io.minio.errors.XmlParserException;
import io.minio.messages.Item;
public class MainActivity extends AppCompatActivity {
static final int REQUEST_IMAGE_CAPTURE = 1;
public static final String TAG = "DEMO";
private ImageView thumb;
private String currentPhotoPath;
private MinioClient minio;
private String bucket;
private ActivityResultLauncher<Intent> photoLauncher;
private RecyclerView objectList;
private ArrayList<String> objectNames;
private ObjectListAdapter objectListAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
thumb = findViewById(R.id.imageView);
// list of all objects in bucket
objectList = findViewById(R.id.objectList);
objectNames = new ArrayList<>();
objectListAdapter = new ObjectListAdapter(objectNames);
objectList.setAdapter(objectListAdapter);
objectList.setLayoutManager(new LinearLayoutManager(this));
minio = MinioClient.builder()
.endpoint(getString(R.string.minio_host))
.credentials(getString(R.string.minio_access_key), getString(R.string.minio_secret_key))
.build();
bucket = getString(R.string.minio_bucket);
checkOrCreateBucket(minio, bucket);
photoLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> { // new ActivityResultCallback<ActivityResult>() {
if (result.getResultCode() == RESULT_OK) {
handlePhotoCallback();
}
});
listObjects();
}
private void listObjects() {
Runnable listObjects = new Runnable() {
@Override
public void run() {
Iterable<Result<Item>> objects = minio.listObjects(ListObjectsArgs.builder().bucket(bucket).prefix("Photos/").build());
objectNames.clear();
for (Result<Item> object : objects) {
try {
Item item = object.get();
objectNames.add(item.objectName());
Log.i(TAG, "list: '" + item.objectName() + "' is dir?: "+ item.isDir());
} catch (InvalidKeyException | IOException | NoSuchAlgorithmException | MinioException e) {
e.printStackTrace();
Log.e(TAG, "something went wrong with minio", e);
}
}
runOnUiThread(() -> {
objectListAdapter.notifyDataSetChanged();
});
}
};
new Thread(listObjects).start();
}
private static void checkOrCreateBucket(MinioClient client, String bucket) {
Runnable check = () -> { // lambda syntax: short for `new Runnable{}`
// network IO is not allowed in UI-Thread, needs to be run separately
try {
boolean isPresent = client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
if (!isPresent) {
System.out.println("Create Bucket '" + bucket + "'");
client.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
} else {
System.out.println("Bucket '" + bucket + "' already present");
}
} catch (InvalidKeyException | IOException | NoSuchAlgorithmException | MinioException e) {
e.printStackTrace();
Log.e(TAG, "something went wrong with minio", e);
}
};
// here, we just start a new Thread. Better: use a service with an interface for separation of concerns
new Thread(check).start();
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "error creating photo file", e);
}
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(
this,
"de.clkl.android.MinioPhotoApp.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
photoLauncher.launch(takePictureIntent);
}
}
}
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat(
"yyyy-MM-dd_HH-mm-ss",
Locale.getDefault()
).format(new Date());
String fileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
fileName,
".jpg",
storageDir
);
currentPhotoPath = image.getAbsolutePath();
Toast.makeText(this, currentPhotoPath, Toast.LENGTH_LONG).show();
return image;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode != REQUEST_IMAGE_CAPTURE) {
super.onActivityResult(requestCode, resultCode, data);
}
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
handlePhotoCallback();
}
}
private void handlePhotoCallback() {
thumb.setImageURI(Uri.fromFile(new File(currentPhotoPath)));
Runnable upload = () -> {
try {
String filename = "Photos/" + currentPhotoPath.substring(currentPhotoPath.lastIndexOf("/"));
minio.uploadObject(UploadObjectArgs.builder().bucket(bucket).object(filename).filename(currentPhotoPath).build());
} catch (InvalidKeyException | IOException | NoSuchAlgorithmException | MinioException e) {
e.printStackTrace();
Log.e(TAG, "something went wrong with minio", e);
}
};
new Thread(upload).start();
listObjects();
}
public void onButtonClick(View view) {
Log.d(TAG, "button has been clicked");
dispatchTakePictureIntent();
}
}