feat(android app): add 'choose file' button to auto upload media to catbox in the background

more free and open web hosting services can be added later
This commit is contained in:
Tom (plebeius.eth)
2024-11-02 18:42:52 +01:00
parent 3f4f0229ba
commit f40c2c2f88
11 changed files with 258 additions and 10 deletions
+1
View File
@@ -38,6 +38,7 @@ dependencies {
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
implementation project(':capacitor-android')
implementation project(':capacitor-cordova-android-plugins')
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
testImplementation "junit:junit:$junitVersion"
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
+3 -4
View File
@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
@@ -33,8 +36,4 @@
android:resource="@xml/file_paths"></meta-data>
</provider>
</application>
<!-- Permissions -->
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
@@ -6,6 +6,12 @@
"plugins": {
"CapacitorHttp": {
"enabled": true
},
"FileUploader": {
"enabled": true
}
},
"server": {
"androidScheme": "https"
}
}
@@ -0,0 +1,110 @@
package plebchan.android;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;
import com.getcapacitor.JSObject;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.CapacitorPlugin;
import com.getcapacitor.annotation.ActivityCallback;
import com.getcapacitor.PluginCall;
import androidx.activity.result.ActivityResult;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
@CapacitorPlugin(name = "FileUploader")
public class FileUploaderPlugin extends Plugin {
private static final String TAG = "FileUploaderPlugin";
@PluginMethod
public void pickAndUploadMedia(PluginCall call) {
Log.d(TAG, "pickAndUploadMedia called");
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
String[] mimeTypes = {"image/jpeg", "image/png", "video/mp4", "video/webm"};
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
startActivityForResult(call, intent, "pickFileResult");
}
@ActivityCallback
private void pickFileResult(PluginCall call, ActivityResult result) {
Log.d(TAG, "pickFileResult callback received");
if (call == null) {
return;
}
if (result.getResultCode() == Activity.RESULT_OK) {
Intent data = result.getData();
if (data != null) {
Uri uri = data.getData();
uploadToCatbox(uri, call);
} else {
call.reject("No data received");
}
} else {
call.reject("File selection cancelled");
}
}
private void uploadToCatbox(Uri fileUri, PluginCall call) {
new Thread(() -> {
try {
Log.d(TAG, "Starting file conversion from URI");
File file = FileUtils.getFileFromUri(getContext(), fileUri);
Log.d(TAG, "File name: " + file.getName());
JSObject statusUpdate = new JSObject();
statusUpdate.put("status", "Uploading to catbox.moe...");
notifyListeners("uploadStatus", statusUpdate);
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("reqtype", "fileupload")
.addFormDataPart("fileToUpload", file.getName(),
RequestBody.create(MediaType.parse("application/octet-stream"), file))
.build();
Request request = new Request.Builder()
.url("https://catbox.moe/user/api.php")
.post(requestBody)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("Unexpected response " + response);
String url = response.body().string();
Log.d(TAG, "Upload successful. URL: " + url);
JSObject ret = new JSObject();
ret.put("url", url);
ret.put("fileName", file.getName());
ret.put("status", "Upload complete!");
call.resolve(ret);
}
} catch (Exception e) {
Log.e(TAG, "Upload failed", e);
call.reject("Upload failed: " + e.getMessage());
}
}).start();
}
}
@@ -0,0 +1,50 @@
package plebchan.android;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
public class FileUtils {
public static File getFileFromUri(Context context, Uri uri) throws Exception {
String fileName = getFileName(context, uri);
File file = new File(context.getCacheDir(), fileName);
try (InputStream inputStream = context.getContentResolver().openInputStream(uri);
FileOutputStream outputStream = new FileOutputStream(file)) {
byte[] buffer = new byte[4096];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
outputStream.flush();
return file;
}
}
private static String getFileName(Context context, Uri uri) {
String result = null;
if (uri.getScheme().equals("content")) {
try (Cursor cursor = context.getContentResolver().query(uri, null, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
if (columnIndex != -1) {
result = cursor.getString(columnIndex);
}
}
}
}
if (result == null) {
result = uri.getPath();
int cut = result.lastIndexOf('/');
if (cut != -1) {
result = result.substring(cut + 1);
}
}
return result;
}
}
@@ -1,5 +1,12 @@
package plebchan.android;
import android.os.Bundle;
import com.getcapacitor.BridgeActivity;
public class MainActivity extends BridgeActivity {}
public class MainActivity extends BridgeActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
registerPlugin(FileUploaderPlugin.class);
super.onCreate(savedInstanceState);
}
}