add list of minio objects
parent
bed1f84a9d
commit
24c7629cc9
|
|
@ -3,7 +3,8 @@
|
|||
<component name="DesignSurface">
|
||||
<option name="filePathToZoomLevelMap">
|
||||
<map>
|
||||
<entry key="app/src/main/res/layout/activity_main.xml" value="0.1" />
|
||||
<entry key="app/src/main/res/layout/activity_main.xml" value="0.25" />
|
||||
<entry key="app/src/main/res/layout/main_object_list_entry.xml" value="0.5505208333333333" />
|
||||
<entry key="app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml" value="0.3353846153846154" />
|
||||
<entry key="app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml" value="0.3353846153846154" />
|
||||
</map>
|
||||
|
|
|
|||
|
|
@ -17,20 +17,33 @@ 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 {
|
||||
|
||||
|
|
@ -41,6 +54,9 @@ public class MainActivity extends AppCompatActivity {
|
|||
private MinioClient minio;
|
||||
private String bucket;
|
||||
private ActivityResultLauncher<Intent> photoLauncher;
|
||||
private RecyclerView objectList;
|
||||
private ArrayList<String> objectNames;
|
||||
private ObjectListAdapter objectListAdapter;
|
||||
|
||||
|
||||
@Override
|
||||
|
|
@ -48,6 +64,14 @@ public class MainActivity extends AppCompatActivity {
|
|||
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))
|
||||
|
|
@ -63,10 +87,36 @@ public class MainActivity extends AppCompatActivity {
|
|||
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) {
|
||||
|
|
@ -80,6 +130,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
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();
|
||||
}
|
||||
|
||||
|
|
@ -137,7 +188,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
Runnable upload = () -> {
|
||||
|
||||
try {
|
||||
String filename = currentPhotoPath.substring(currentPhotoPath.lastIndexOf("/"));
|
||||
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();
|
||||
|
|
@ -145,6 +196,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
}
|
||||
};
|
||||
new Thread(upload).start();
|
||||
listObjects();
|
||||
}
|
||||
|
||||
public void onButtonClick(View view) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
package de.clkl.android.miniofotoapp;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class ObjectListAdapter extends RecyclerView.Adapter<ObjectListAdapter.ViewHolder> {
|
||||
private List<String> objects;
|
||||
private static List<String> IMAGE_FILE_TYPES = Arrays.asList(".jpg", ".png");
|
||||
|
||||
private static boolean isImage(String name){
|
||||
return IMAGE_FILE_TYPES.stream().anyMatch(s -> name.toLowerCase().endsWith(s));
|
||||
}
|
||||
|
||||
public ObjectListAdapter(List<String> objects) {
|
||||
this.objects = objects;
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
Context ctx = parent.getContext();
|
||||
LayoutInflater inflater = LayoutInflater.from(ctx);
|
||||
|
||||
View objectView = inflater.inflate(R.layout.main_object_list_entry, parent, false);
|
||||
ViewHolder viewHolder = new ViewHolder(objectView);
|
||||
return viewHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
String object = objects.get(position);
|
||||
holder.name.setText(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return objects.size();
|
||||
}
|
||||
|
||||
public class ViewHolder extends RecyclerView.ViewHolder {
|
||||
private final TextView name;
|
||||
private final View thumb;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
name = itemView.findViewById(R.id.objectListContent);
|
||||
thumb = itemView.findViewById(R.id.objectListImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,38 +6,36 @@
|
|||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello World!"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="148dp"
|
||||
android:layout_marginTop="112dp"
|
||||
android:text="@string/button"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:onClick="onButtonClick"
|
||||
android:text="@string/button"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:contentDescription="@string/thumbnail"
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="40dp"
|
||||
android:layout_marginTop="56dp"
|
||||
android:layout_width="372dp"
|
||||
android:layout_height="259dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="36dp"
|
||||
android:adjustViewBounds="false"
|
||||
android:contentDescription="@string/thumbnail"
|
||||
android:scaleType="fitCenter"
|
||||
app:layout_constraintStart_toStartOf="@+id/button"
|
||||
app:layout_constraintTop_toBottomOf="@+id/button"
|
||||
app:srcCompat="@android:drawable/ic_dialog_alert"
|
||||
android:adjustViewBounds="false"
|
||||
android:scaleType="fitCenter"
|
||||
/>
|
||||
app:srcCompat="@android:drawable/ic_dialog_alert" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/objectList"
|
||||
android:layout_width="409dp"
|
||||
android:layout_height="354dp"
|
||||
android:layout_marginTop="12dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/imageView" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/objectListContent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/objectListImage"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_weight="1"
|
||||
app:srcCompat="@android:drawable/ic_dialog_info" />
|
||||
</LinearLayout>
|
||||
|
|
@ -5,7 +5,7 @@ buildscript {
|
|||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "com.android.tools.build:gradle:7.0.1"
|
||||
classpath 'com.android.tools.build:gradle:7.0.2'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
|
|
|||
Loading…
Reference in New Issue