[+] Drop images
This commit is contained in:
@@ -26,6 +26,11 @@
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="image/*" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package aza.instant
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Picture
|
||||
import android.media.MediaScannerConnection
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.OpenableColumns
|
||||
import android.util.Log
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
@@ -51,20 +54,38 @@ import java.io.File
|
||||
import java.io.InputStreamReader
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
private var sharedImageUri by mutableStateOf<Uri?>(null)
|
||||
private var isUriHandled = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
handleIntent(intent)
|
||||
|
||||
setContent {
|
||||
ProjectInstantTheme {
|
||||
Scaffold(modifier = Modifier.fillMaxSize()) {
|
||||
FileListerScreen(modifier = Modifier.padding(it))
|
||||
FileListerScreen(modifier = Modifier.padding(it), sharedImageUri = if (isUriHandled) null else sharedImageUri, onSharedImageHandled = { isUriHandled = true })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
setIntent(intent)
|
||||
isUriHandled = false
|
||||
handleIntent(intent)
|
||||
}
|
||||
|
||||
private fun handleIntent(intent: Intent?) {
|
||||
if (intent?.action == Intent.ACTION_SEND && intent.type?.startsWith("image/") == true) {
|
||||
sharedImageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun FileListerScreen(modifier: Modifier = Modifier) {
|
||||
fun FileListerScreen(modifier: Modifier = Modifier, sharedImageUri: Uri?, onSharedImageHandled: () -> Unit) {
|
||||
var feedbackText by remember { mutableStateOf("Click a button to see the output here.") }
|
||||
var picture by remember { mutableStateOf<Picture?>(null) }
|
||||
val scrollState = rememberScrollState()
|
||||
@@ -81,10 +102,66 @@ fun FileListerScreen(modifier: Modifier = Modifier) {
|
||||
.toTypedArray().ifEmpty { null }?.let { askPerm.launch(it) }
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
val renderAndUpload = { imagePath: String, originalFileName: String ->
|
||||
coroutineScope.launch {
|
||||
try {
|
||||
feedbackText = "Rendering..."
|
||||
val outDir = File("/storage/emulated/0/DCIM/CA_IMAGES_OUT/")
|
||||
val templateStream = context.resources.openRawResource(R.raw.postcard4)
|
||||
val template = BufferedReader(InputStreamReader(templateStream)).readText()
|
||||
val (svg, exif) = genSvg(template, imagePath)
|
||||
val (pic, bytes) = renderSvgBytes(context, svg, exif) ?: return@launch
|
||||
picture = pic
|
||||
|
||||
// Save picture to file
|
||||
outDir.mkdirs()
|
||||
val out = File(outDir, "${File(originalFileName).nameWithoutExtension}-framed.jpg")
|
||||
.apply { writeBytes(bytes) }
|
||||
|
||||
MediaScannerConnection.scanFile(context, arrayOf(out.absolutePath), null, null)
|
||||
|
||||
feedbackText = "Rendered ${originalFileName}, now uploading..."
|
||||
|
||||
val uploadWorkRequest = OneTimeWorkRequestBuilder<UploadWorker>()
|
||||
.setInputData(workDataOf(
|
||||
"originalPhotoPath" to imagePath,
|
||||
"editedPhotoPath" to out.absolutePath,
|
||||
"urlName" to exif.urlName
|
||||
))
|
||||
.build()
|
||||
WorkManager.getInstance(context).enqueue(uploadWorkRequest)
|
||||
|
||||
// Launch Canon app
|
||||
context.startActivity(Intent().apply {
|
||||
setClassName("jp.co.canon.ic.photolayout", "jp.co.canon.ic.photolayout.MainActivity")
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
})
|
||||
} catch (e: Exception) {
|
||||
feedbackText = "Error during operation: ${e.message}"
|
||||
Log.e("MainActivity", "Error during render or upload", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(sharedImageUri) {
|
||||
if (sharedImageUri == null) return@LaunchedEffect
|
||||
|
||||
feedbackText = "Handling shared image..."
|
||||
val fileName = getFileName(context, sharedImageUri) ?: "shared_image_${System.currentTimeMillis()}.jpg"
|
||||
val tempFile = File(context.cacheDir, fileName)
|
||||
try {
|
||||
context.contentResolver.openInputStream(sharedImageUri)?.use { input ->
|
||||
tempFile.outputStream().use { output -> input.copyTo(output) }
|
||||
}
|
||||
renderAndUpload(tempFile.absolutePath, fileName)
|
||||
onSharedImageHandled()
|
||||
} catch (e: Exception) {
|
||||
feedbackText = "Failed to handle shared image: ${e.message}"
|
||||
Log.e("MainActivity", "Error handling shared image", e)
|
||||
}
|
||||
}
|
||||
|
||||
Column(modifier = modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Column(modifier = Modifier.weight(1f), horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
picture?.let { p ->
|
||||
Canvas(modifier = Modifier.fillMaxWidth().weight(1f).drawWithCache {
|
||||
@@ -102,61 +179,37 @@ fun FileListerScreen(modifier: Modifier = Modifier) {
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Button(onClick = {
|
||||
coroutineScope.launch {
|
||||
feedbackText = "Rendering..."
|
||||
val imageDir = File("/storage/emulated/0/DCIM/CA_IMAGES/")
|
||||
val outDir = File("/storage/emulated/0/DCIM/CA_IMAGES_OUT/")
|
||||
val latestImg = imageDir.listFiles()
|
||||
?.filter { !it.name.contains("-framed") and !it.name.contains(".trashed") }
|
||||
?.filter { !it.name.contains("-framed") && !it.name.contains(".trashed") }
|
||||
?.maxByOrNull { it.lastModified() }
|
||||
if (latestImg == null) {
|
||||
feedbackText = "No images found in CA_IMAGES"
|
||||
return@launch
|
||||
}
|
||||
try {
|
||||
val templateStream = context.resources.openRawResource(R.raw.postcard4)
|
||||
val template = BufferedReader(InputStreamReader(templateStream)).readText()
|
||||
val (svg, exif) = genSvg(template, latestImg.absolutePath)
|
||||
val (pic, bytes) = renderSvgBytes(context, svg, exif) ?: return@launch
|
||||
picture = pic
|
||||
|
||||
// Save picture to file
|
||||
outDir.mkdirs()
|
||||
val out = File(outDir, "${latestImg.nameWithoutExtension}-framed.jpg")
|
||||
.apply { writeBytes(bytes) }
|
||||
|
||||
MediaScannerConnection.scanFile(context, arrayOf(out.absolutePath), null, null)
|
||||
|
||||
feedbackText = "Rendered ${latestImg.name}, now uploading..."
|
||||
|
||||
val uploadWorkRequest = OneTimeWorkRequestBuilder<UploadWorker>()
|
||||
.setInputData(workDataOf(
|
||||
"originalPhotoPath" to latestImg.absolutePath,
|
||||
"editedPhotoPath" to out.absolutePath,
|
||||
"urlName" to exif.urlName
|
||||
))
|
||||
.build()
|
||||
WorkManager.getInstance(context).enqueue(uploadWorkRequest)
|
||||
|
||||
// Launch Canon app
|
||||
context.startActivity(Intent().apply {
|
||||
setClassName("jp.co.canon.ic.photolayout", "jp.co.canon.ic.photolayout.MainActivity")
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
})
|
||||
} catch (e: Exception) {
|
||||
feedbackText = "Error during operation: ${e.message}"
|
||||
Log.e("MainActivity", "Error during render or upload", e)
|
||||
}
|
||||
renderAndUpload(latestImg.absolutePath, latestImg.name)
|
||||
}
|
||||
}) { Text(text = "Render Latest") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFileName(context: Context, uri: Uri): String? {
|
||||
context.contentResolver.query(uri, null, null, null, null)?.use { cursor ->
|
||||
if (cursor.moveToFirst()) {
|
||||
val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
||||
if (nameIndex != -1) return cursor.getString(nameIndex)
|
||||
}
|
||||
}
|
||||
return uri.path?.substringAfterLast('/')
|
||||
}
|
||||
|
||||
|
||||
private fun listFilesFromDcim(): String {
|
||||
val d = File("/storage/emulated/0/DCIM/CA_IMAGES/")
|
||||
if (!d.exists() || !d.isDirectory) return "Directory not found or is not a directory: ${d.absolutePath}"
|
||||
return d.listFiles()?.let {
|
||||
it.ifEmpty { null }?.sortedBy { it.lastModified() }?.joinToString("\n") { it.name }
|
||||
return d.listFiles()?.let { files ->
|
||||
files.ifEmpty { null }?.sortedBy { it.lastModified() }?.joinToString("\n") { it.name }
|
||||
?: "No files found in ${d.absolutePath}"
|
||||
} ?: "Failed to list files in ${d.absolutePath}. listFiles() returned null."
|
||||
}
|
||||
@@ -165,6 +218,6 @@ private fun listFilesFromDcim(): String {
|
||||
@Composable
|
||||
fun FileListerScreenPreview() {
|
||||
ProjectInstantTheme {
|
||||
FileListerScreen()
|
||||
FileListerScreen(sharedImageUri = null, onSharedImageHandled = {})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user