Working on application + updating coroutines
This commit is contained in:
parent
dc4f77d6c8
commit
ce6293e88f
|
@ -29,7 +29,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.6'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7'
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
|
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||||
|
|
|
@ -35,7 +35,7 @@ android {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.6'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7'
|
||||||
|
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
package oupson.apngcreator.activities
|
package oupson.apngcreator.activities
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
|
@ -40,6 +45,8 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
private const val PICK_IMAGE = 1
|
private const val PICK_IMAGE = 1
|
||||||
private const val WRITE_REQUEST_CODE = 2
|
private const val WRITE_REQUEST_CODE = 2
|
||||||
private const val TAG = "CreatorActivity"
|
private const val TAG = "CreatorActivity"
|
||||||
|
|
||||||
|
private const val CREATION_CHANNEL_ID = "${BuildConfig.APPLICATION_ID}.notifications_channels.create"
|
||||||
}
|
}
|
||||||
|
|
||||||
private var items: ArrayList<Triple<Uri, Int, Long>> = ArrayList()
|
private var items: ArrayList<Triple<Uri, Int, Long>> = ArrayList()
|
||||||
|
@ -99,6 +106,20 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
setSupportActionBar(creatorBottomAppBar)
|
setSupportActionBar(creatorBottomAppBar)
|
||||||
imageRecyclerView.adapter = adapter
|
imageRecyclerView.adapter = adapter
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
// Create the NotificationChannel
|
||||||
|
val name = getString(R.string.create_notification_channel_name)
|
||||||
|
val descriptionText = getString(R.string.create_notification_channel_description)
|
||||||
|
val importance = NotificationManager.IMPORTANCE_LOW
|
||||||
|
val mChannel = NotificationChannel(CREATION_CHANNEL_ID, name, importance)
|
||||||
|
mChannel.description = descriptionText
|
||||||
|
// Register the channel with the system; you can't change the importance
|
||||||
|
// or other notification behaviors after this
|
||||||
|
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
||||||
|
notificationManager.createNotificationChannel(mChannel)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||||
|
@ -112,6 +133,13 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
return when (item?.itemId) {
|
return when (item?.itemId) {
|
||||||
R.id.menu_create_apng -> {
|
R.id.menu_create_apng -> {
|
||||||
if (items.size > 0) {
|
if (items.size > 0) {
|
||||||
|
val builder = NotificationCompat.Builder(this, CREATION_CHANNEL_ID).apply {
|
||||||
|
setContentTitle(getString(R.string.create_notification_title))
|
||||||
|
setContentText(this@CreatorActivity.resources.getQuantityString(R.plurals.create_notification_description, 0, 0, items.size))
|
||||||
|
setSmallIcon(R.drawable.ic_create_white_24dp)
|
||||||
|
priority = NotificationCompat.PRIORITY_LOW
|
||||||
|
}
|
||||||
|
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
val randomFileName = UUID.randomUUID().toString()
|
val randomFileName = UUID.randomUUID().toString()
|
||||||
val f = File(filesDir, "images/$randomFileName.png").apply {
|
val f = File(filesDir, "images/$randomFileName.png").apply {
|
||||||
|
@ -121,7 +149,7 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val out = FileOutputStream(f)
|
val out = FileOutputStream(f)
|
||||||
saveToOutputStream(out)
|
saveToOutputStream(items.map { Pair(it.first, it.second) }, out, builder = builder)
|
||||||
out.close()
|
out.close()
|
||||||
|
|
||||||
if (BuildConfig.DEBUG)
|
if (BuildConfig.DEBUG)
|
||||||
|
@ -152,6 +180,12 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
R.id.menu_share_apng -> {
|
R.id.menu_share_apng -> {
|
||||||
if (items.size > 0) {
|
if (items.size > 0) {
|
||||||
|
val builder = NotificationCompat.Builder(this, CREATION_CHANNEL_ID).apply {
|
||||||
|
setContentTitle(getString(R.string.create_notification_title))
|
||||||
|
setContentText(this@CreatorActivity.resources.getQuantityString(R.plurals.create_notification_description, 0, 0, items.size))
|
||||||
|
setSmallIcon(R.drawable.ic_create_white_24dp)
|
||||||
|
priority = NotificationCompat.PRIORITY_LOW
|
||||||
|
}
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
val randomFileName = UUID.randomUUID().toString()
|
val randomFileName = UUID.randomUUID().toString()
|
||||||
val f = File(filesDir, "images/$randomFileName.png").apply {
|
val f = File(filesDir, "images/$randomFileName.png").apply {
|
||||||
|
@ -161,7 +195,7 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val out = FileOutputStream(f)
|
val out = FileOutputStream(f)
|
||||||
saveToOutputStream(out)
|
saveToOutputStream(items.map { Pair(it.first, it.second) }, out, builder = builder)
|
||||||
out.close()
|
out.close()
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
@ -255,10 +289,18 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveToOutputStream(outputStream: OutputStream) {
|
private suspend fun saveToOutputStream(files : Collection<Pair<Uri, Int>>, outputStream: OutputStream, builder : NotificationCompat.Builder? = null) {
|
||||||
var maxWidth = 0
|
var maxWidth = 0
|
||||||
var maxHeight = 0
|
var maxHeight = 0
|
||||||
items.forEach {
|
var notificationManagerCompat: NotificationManagerCompat?
|
||||||
|
if (builder != null) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
notificationManagerCompat = NotificationManagerCompat.from(this@CreatorActivity)
|
||||||
|
builder.setProgress(files.size, 0, false)
|
||||||
|
notificationManagerCompat?.notify(1, builder.build())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
files.forEach {
|
||||||
val str = contentResolver.openInputStream(it.first)
|
val str = contentResolver.openInputStream(it.first)
|
||||||
if (str == null) {
|
if (str == null) {
|
||||||
Log.e(TAG, "Input Stream is null : ${it.first}")
|
Log.e(TAG, "Input Stream is null : ${it.first}")
|
||||||
|
@ -289,6 +331,14 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
.setOptimiseApng(optimise)
|
.setOptimiseApng(optimise)
|
||||||
|
|
||||||
items.forEachIndexed { i, uri ->
|
items.forEachIndexed { i, uri ->
|
||||||
|
if (builder != null) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
notificationManagerCompat = NotificationManagerCompat.from(this@CreatorActivity)
|
||||||
|
builder.setProgress(files.size, i+1, false)
|
||||||
|
.setContentText(this@CreatorActivity.resources.getQuantityString(R.plurals.create_notification_description, i +1, i + 1, files.size))
|
||||||
|
notificationManagerCompat?.notify(1, builder.build())
|
||||||
|
}
|
||||||
|
}
|
||||||
if (BuildConfig.DEBUG)
|
if (BuildConfig.DEBUG)
|
||||||
Log.v(TAG, "Encoding frame $i")
|
Log.v(TAG, "Encoding frame $i")
|
||||||
|
|
||||||
|
@ -325,9 +375,21 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runCatching {
|
||||||
encoder.writeEnd()
|
encoder.writeEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (builder != null) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
notificationManagerCompat = NotificationManagerCompat.from(this@CreatorActivity)
|
||||||
|
builder.setProgress(0, 0, false)
|
||||||
|
.setContentText(getString(R.string.create_notification_description_end))
|
||||||
|
notificationManagerCompat?.notify(1, builder.build())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
when (requestCode) {
|
when (requestCode) {
|
||||||
|
@ -350,9 +412,16 @@ class CreatorActivity : AppCompatActivity() {
|
||||||
if (BuildConfig.DEBUG)
|
if (BuildConfig.DEBUG)
|
||||||
Log.i(TAG, "Intent data : ${data.data}")
|
Log.i(TAG, "Intent data : ${data.data}")
|
||||||
|
|
||||||
|
val builder = NotificationCompat.Builder(this, CREATION_CHANNEL_ID).apply {
|
||||||
|
setContentTitle(getString(R.string.create_notification_title))
|
||||||
|
setContentText(this@CreatorActivity.resources.getQuantityString(R.plurals.create_notification_description, 0, 0, items.size))
|
||||||
|
setSmallIcon(R.drawable.ic_create_white_24dp)
|
||||||
|
priority = NotificationCompat.PRIORITY_LOW
|
||||||
|
}
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
|
|
||||||
val out = contentResolver.openOutputStream(data.data!!) ?: return@launch
|
val out = contentResolver.openOutputStream(data.data!!) ?: return@launch
|
||||||
saveToOutputStream(out)
|
saveToOutputStream(items.map { Pair(it.first, it.second) }, out, builder = builder)
|
||||||
out.close()
|
out.close()
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
app:srcCompat="@drawable/ic_add_black_24dp"
|
app:srcCompat="@drawable/ic_add_black_24dp"
|
||||||
tools:ignore="VectorDrawableCompat" />
|
tools:ignore="VectorDrawableCompat" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<com.google.android.material.bottomappbar.BottomAppBar
|
<com.google.android.material.bottomappbar.BottomAppBar
|
||||||
android:id="@+id/creatorBottomAppBar"
|
android:id="@+id/creatorBottomAppBar"
|
||||||
style="@style/Widget.MaterialComponents.BottomAppBar.Colored"
|
style="@style/Widget.MaterialComponents.BottomAppBar.Colored"
|
||||||
|
|
|
@ -20,6 +20,14 @@
|
||||||
<string name="menu_optimise">Optimise animation</string>
|
<string name="menu_optimise">Optimise animation</string>
|
||||||
<string name="add_frame">Add a frame to the animation</string>
|
<string name="add_frame">Add a frame to the animation</string>
|
||||||
<string name="create_animation">Create an animation</string>
|
<string name="create_animation">Create an animation</string>
|
||||||
|
<string name="create_notification_channel_name">Creation notifications</string>
|
||||||
|
<string name="create_notification_channel_description">A channel used to send update about creation process</string>
|
||||||
|
<string name="create_notification_title">Exporting animation</string>
|
||||||
|
<plurals name="create_notification_description">
|
||||||
|
<item quantity="one">Exporting frame %1$d out of %2$d</item>
|
||||||
|
<item quantity="other">Exporting frames %1$d out of %2$d</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="create_notification_description_end">Exporting complete</string>
|
||||||
|
|
||||||
<string name="file_size_kB">File size is %1$d kB</string>
|
<string name="file_size_kB">File size is %1$d kB</string>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue