206 lines
6.7 KiB
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();
|
|
}
|
|
} |