mirror of
https://github.com/tateisu/SubwayTooter
synced 2025-01-28 17:49:27 +01:00
カラム背景画像の保存フォルダにgetExternalFilesDirを使う。回転が必要な画像や画面の長辺の1.5倍以上の画像は変換する。
This commit is contained in:
parent
bd03761042
commit
b5a6712402
@ -1,6 +1,5 @@
|
||||
package jp.juggler.subwaytooter
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
@ -18,6 +17,10 @@ import android.widget.TextView
|
||||
|
||||
import com.jrummyapps.android.colorpicker.ColorPickerDialog
|
||||
import com.jrummyapps.android.colorpicker.ColorPickerDialogListener
|
||||
import jp.juggler.subwaytooter.api.TootApiClient
|
||||
import jp.juggler.subwaytooter.api.TootApiResult
|
||||
import jp.juggler.subwaytooter.api.TootTask
|
||||
import jp.juggler.subwaytooter.api.TootTaskRunner
|
||||
import jp.juggler.subwaytooter.util.*
|
||||
import org.apache.commons.io.IOUtils
|
||||
import java.io.File
|
||||
@ -25,6 +28,7 @@ import java.io.FileOutputStream
|
||||
|
||||
import java.text.NumberFormat
|
||||
import java.util.Locale
|
||||
import kotlin.math.max
|
||||
|
||||
class ActColumnCustomize : AppCompatActivity(), View.OnClickListener, ColorPickerDialogListener {
|
||||
|
||||
@ -183,7 +187,7 @@ class ActColumnCustomize : AppCompatActivity(), View.OnClickListener, ColorPicke
|
||||
}
|
||||
|
||||
R.id.btnColumnBackgroundImage -> {
|
||||
val intent = intentOpenDocument("image/*")
|
||||
val intent = intentGetContent(false, getString(R.string.pick_image), "image/*")
|
||||
startActivityForResult(intent, REQUEST_CODE_PICK_BACKGROUND)
|
||||
}
|
||||
|
||||
@ -221,24 +225,76 @@ class ActColumnCustomize : AppCompatActivity(), View.OnClickListener, ColorPicke
|
||||
|
||||
override fun onActivityResult(requestCode : Int, resultCode : Int, data : Intent?) {
|
||||
if(requestCode == REQUEST_CODE_PICK_BACKGROUND && data != null && resultCode == RESULT_OK) {
|
||||
data.handleGetContentResult(contentResolver).firstOrNull()?.let { pair->
|
||||
try{
|
||||
val backgroundDir = getDir(Column.DIR_BACKGROUND_IMAGE, Context.MODE_PRIVATE)
|
||||
val file = File(backgroundDir,column.column_id)
|
||||
FileOutputStream(file).use{ outStream->
|
||||
contentResolver.openInputStream(pair.first).use{ inStream->
|
||||
IOUtils.copy(inStream,outStream)
|
||||
}
|
||||
}
|
||||
column.column_bg_image = Uri.fromFile(file).toString()
|
||||
show()
|
||||
}catch(ex:Throwable){
|
||||
showToast(this@ActColumnCustomize,true,ex.withCaption("can't update background image."))
|
||||
}
|
||||
data.handleGetContentResult(contentResolver).firstOrNull()?.let { pair ->
|
||||
updateBackground(pair.first)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateBackground(uriArg : Uri) {
|
||||
TootTaskRunner(this).run(object : TootTask {
|
||||
override fun background(client : TootApiClient) : TootApiResult? {
|
||||
try {
|
||||
val backgroundDir = Column.getBackgroundImageDir(this@ActColumnCustomize)
|
||||
val file =
|
||||
File(backgroundDir, "${column.column_id}:${System.currentTimeMillis()}")
|
||||
val fileUri = Uri.fromFile(file)
|
||||
|
||||
client.publishApiProgress("loading image from ${uriArg}")
|
||||
contentResolver.openInputStream(uriArg).use { inStream ->
|
||||
FileOutputStream(file).use { outStream ->
|
||||
IOUtils.copy(inStream, outStream)
|
||||
}
|
||||
}
|
||||
|
||||
// リサイズや回転が必要ならする
|
||||
client.publishApiProgress("check resize/rotation…")
|
||||
|
||||
val size = (max(
|
||||
resources.displayMetrics.widthPixels,
|
||||
resources.displayMetrics.heightPixels
|
||||
) * 1.5f ).toInt()
|
||||
|
||||
val bitmap = createResizedBitmap(
|
||||
this@ActColumnCustomize,
|
||||
fileUri,
|
||||
size,
|
||||
skipIfNoNeedToResizeAndRotate = true
|
||||
)
|
||||
if(bitmap != null) {
|
||||
try {
|
||||
client.publishApiProgress("save resized(${bitmap.width}x${bitmap.height}) image to ${file}")
|
||||
FileOutputStream(file).use { os ->
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, os)
|
||||
}
|
||||
}finally{
|
||||
bitmap.recycle()
|
||||
}
|
||||
}
|
||||
|
||||
val result = TootApiResult()
|
||||
result.data = fileUri.toString()
|
||||
return result
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
return TootApiResult(ex.withCaption("can't update background image."))
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleResult(result : TootApiResult?) {
|
||||
when {
|
||||
result == null -> return
|
||||
result.error != null -> showToast(this@ActColumnCustomize, true, result.error)
|
||||
|
||||
else -> {
|
||||
column.column_bg_image = result.data as String
|
||||
show()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun initUI() {
|
||||
setContentView(R.layout.act_column_customize)
|
||||
|
||||
@ -443,7 +499,7 @@ class ActColumnCustomize : AppCompatActivity(), View.OnClickListener, ColorPicke
|
||||
// 画像をロードして、成功したら表示してURLを覚える
|
||||
val resize_max = (0.5f + 64f * density).toInt()
|
||||
val uri = Uri.parse(url)
|
||||
last_image_bitmap = createResizedBitmap( this, uri, resize_max )
|
||||
last_image_bitmap = createResizedBitmap(this, uri, resize_max)
|
||||
if(last_image_bitmap != null) {
|
||||
ivColumnBackground.setImageBitmap(last_image_bitmap)
|
||||
last_image_uri = url
|
||||
|
@ -225,7 +225,7 @@ class AppState(internal val context : Context, internal val pref : SharedPrefere
|
||||
|
||||
}
|
||||
|
||||
internal fun restartTTS() {
|
||||
fun restartTTS() {
|
||||
log.d("restart TextToSpeech")
|
||||
tts?.shutdown()
|
||||
tts = null
|
||||
@ -280,11 +280,13 @@ class AppState(internal val context : Context, internal val pref : SharedPrefere
|
||||
enableSpeech()
|
||||
|
||||
// 背景フォルダの掃除
|
||||
val backgroundDir = context.getDir(Column.DIR_BACKGROUND_IMAGE,Context.MODE_PRIVATE)
|
||||
backgroundDir.list().forEach {name->
|
||||
val file = File(backgroundDir,name)
|
||||
val backgroundImageDir = Column.getBackgroundImageDir(context)
|
||||
backgroundImageDir.list().forEach {name->
|
||||
val file = File(backgroundImageDir,name)
|
||||
if( file.isFile ){
|
||||
val column = Column.findColumnById( name )
|
||||
val delm = name.indexOf(':')
|
||||
val id = if(delm!=-1) name.substring(0, delm) else name
|
||||
val column = Column.findColumnById( id )
|
||||
if( column == null) file.delete()
|
||||
}
|
||||
}
|
||||
@ -330,7 +332,7 @@ class AppState(internal val context : Context, internal val pref : SharedPrefere
|
||||
log.d("initializing TextToSpeech…")
|
||||
|
||||
object : AsyncTask<Void, Void, TextToSpeech?>() {
|
||||
internal var tmp_tts : TextToSpeech? = null
|
||||
var tmp_tts : TextToSpeech? = null
|
||||
|
||||
override fun doInBackground(vararg params : Void) : TextToSpeech {
|
||||
val tts = TextToSpeech(context, tts_init_listener)
|
||||
@ -338,7 +340,7 @@ class AppState(internal val context : Context, internal val pref : SharedPrefere
|
||||
return tts
|
||||
}
|
||||
|
||||
internal val tts_init_listener : TextToSpeech.OnInitListener =
|
||||
val tts_init_listener : TextToSpeech.OnInitListener =
|
||||
TextToSpeech.OnInitListener { status ->
|
||||
|
||||
val tts = this.tmp_tts
|
||||
|
@ -4,6 +4,7 @@ import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.AsyncTask
|
||||
import android.os.Environment
|
||||
import android.os.SystemClock
|
||||
import android.view.Gravity
|
||||
import jp.juggler.subwaytooter.api.*
|
||||
@ -13,6 +14,7 @@ import jp.juggler.subwaytooter.util.*
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
import java.lang.ref.WeakReference
|
||||
import java.nio.ByteBuffer
|
||||
import java.text.SimpleDateFormat
|
||||
@ -55,7 +57,7 @@ class Column(
|
||||
companion object {
|
||||
private val log = LogCategory("Column")
|
||||
|
||||
const val DIR_BACKGROUND_IMAGE = "columnBackground"
|
||||
private const val DIR_BACKGROUND_IMAGE = "columnBackground"
|
||||
|
||||
private const val READ_LIMIT = 80 // API側の上限が80です。ただし指定しても40しか返ってこないことが多い
|
||||
private const val LOOP_TIMEOUT = 10000L
|
||||
@ -403,6 +405,28 @@ class Column(
|
||||
return columnIdMap[id]?.get()
|
||||
}
|
||||
}
|
||||
|
||||
fun getBackgroundImageDir(context : Context) : File {
|
||||
val externalDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
|
||||
if( externalDir == null) {
|
||||
log.e("getExternalFilesDir is null.")
|
||||
}else{
|
||||
val state = Environment.getExternalStorageState()
|
||||
if( state != Environment.MEDIA_MOUNTED ){
|
||||
log.e("getExternalStorageState: ${state}")
|
||||
}else {
|
||||
log.i("externalDir: ${externalDir}")
|
||||
externalDir.mkdir()
|
||||
val backgroundDir = File(externalDir,DIR_BACKGROUND_IMAGE)
|
||||
backgroundDir.mkdir()
|
||||
log.i("backgroundDir: ${backgroundDir} exists=${backgroundDir.exists()}")
|
||||
return backgroundDir
|
||||
}
|
||||
}
|
||||
val backgroundDir = context.getDir(Column.DIR_BACKGROUND_IMAGE,Context.MODE_PRIVATE)
|
||||
log.i("backgroundDir: ${backgroundDir} exists=${backgroundDir.exists()}")
|
||||
return backgroundDir
|
||||
}
|
||||
}
|
||||
|
||||
private var callback_ref : WeakReference<Callback>? = null
|
||||
@ -2196,15 +2220,15 @@ class Column(
|
||||
|
||||
TYPE_DOMAIN_BLOCKS -> return parseDomainList(client, PATH_DOMAIN_BLOCK)
|
||||
|
||||
TYPE_LIST_LIST -> if(isMisskey){
|
||||
TYPE_LIST_LIST -> return if(isMisskey){
|
||||
val params = makeMisskeyBaseParameter(parser)
|
||||
return parseListList(
|
||||
parseListList(
|
||||
client,
|
||||
"/api/users/lists/list",
|
||||
misskeyParams = params
|
||||
)
|
||||
}else{
|
||||
return parseListList(client, PATH_LIST_LIST)
|
||||
parseListList(client, PATH_LIST_LIST)
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user