From f4093abba9cf0b2a71efacab2dbfda1cbce581c2 Mon Sep 17 00:00:00 2001 From: tateisu Date: Wed, 3 Jan 2024 00:18:09 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=B3=E3=83=BC=E3=83=89=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/gradle.xml | 16 ++- app/src/main/AndroidManifest.xml | 1 + .../jp/juggler/subwaytooter/ActCallback.kt | 132 +++++++++--------- .../java/jp/juggler/subwaytooter/ActMain.kt | 4 +- .../jp/juggler/subwaytooter/ActMediaViewer.kt | 12 +- .../java/jp/juggler/subwaytooter/AppState.kt | 10 +- .../subwaytooter/actpost/ActPostAttachment.kt | 4 +- .../dialog/DlgAttachmentRearrange.kt | 2 +- app/src/main/res/xml/backup_spec.xml | 4 +- .../main/res/xml/data_extraction_rules.xml | 13 ++ 10 files changed, 117 insertions(+), 81 deletions(-) create mode 100644 app/src/main/res/xml/data_extraction_rules.xml diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 060755b1..d7b67786 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -4,10 +4,19 @@ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2b0aec11..ef15f5e4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -87,6 +87,7 @@ (null) - internal val sent_intent = AtomicReference(null) + internal val lastUri = AtomicReference(null) + internal val sharedIntent = AtomicReference(null) private fun String?.isMediaMimeType() = when { this == null -> false @@ -47,10 +47,10 @@ class ActCallback : AppCompatActivity() { } override fun onCreate(savedInstanceState: Bundle?) { - log.d("onCreate flags=0x${intent.flags.toString(radix = 16)}") + var intent = this.intent + log.d("onCreate flags=0x${intent?.flags?.toString(radix = 16)}") super.onCreate(savedInstanceState) - var intent: Intent? = intent when { intent == null -> { // 多分起きないと思う @@ -65,29 +65,31 @@ class ActCallback : AppCompatActivity() { val type = intent.type // ACTION_SEND か ACTION_SEND_MULTIPLE // ACTION_VIEW かつ type が 画像かビデオか音声 - if ( + when { Intent.ACTION_SEND == action || - Intent.ACTION_SEND_MULTIPLE == action || - (Intent.ACTION_VIEW == action && type.isMediaMimeType()) - ) { + Intent.ACTION_SEND_MULTIPLE == action || + (Intent.ACTION_VIEW == action && type.isMediaMimeType()) -> { - // Google Photo などから送られるIntentに含まれるuriの有効期間はActivityが閉じられるまで - // http://qiita.com/pside/items/a821e2fe9ae6b7c1a98c + // Google Photo などから送られるIntentに含まれるuriの有効期間はActivityが閉じられるまで + // http://qiita.com/pside/items/a821e2fe9ae6b7c1a98c - // 有効期間を延長する - intent = remake(intent) - if (intent != null) { - sent_intent.set(intent) + // 有効期間を延長する + intent = remake(intent) + if (intent != null) { + sharedIntent.set(intent) + } } - } else if (forbidUriFromApp(intent)) { - // last_uriをクリアする - last_uri.set(null) - // ダイアログを閉じるまで画面遷移しない - return - } else { - val uri = intent.data - if (uri != null) { - last_uri.set(uri) + forbidUriFromApp(intent) -> { + // last_uriをクリアする + lastUri.set(null) + // ダイアログを閉じるまで画面遷移しない + return + } + else -> { + val uri = intent.data + if (uri != null) { + lastUri.set(uri) + } } } } @@ -105,13 +107,11 @@ class ActCallback : AppCompatActivity() { } private fun copyExtraTexts(dst: Intent, src: Intent) { - var sv: String? + src.string(Intent.EXTRA_TEXT) + ?.let { dst.putExtra(Intent.EXTRA_TEXT, it) } // - sv = src.string(Intent.EXTRA_TEXT) - if (sv != null) dst.putExtra(Intent.EXTRA_TEXT, sv) - // - sv = src.string(Intent.EXTRA_SUBJECT) - if (sv != null) dst.putExtra(Intent.EXTRA_SUBJECT, sv) + src.string(Intent.EXTRA_SUBJECT) + ?.let { dst.putExtra(Intent.EXTRA_SUBJECT, it) } } private fun remake(src: Intent): Intent? { @@ -123,52 +123,56 @@ class ActCallback : AppCompatActivity() { val type = src.type if (type.isMediaMimeType()) { - if (Intent.ACTION_VIEW == action) { - src.data?.let { uriOriginal -> + when (action){ + Intent.ACTION_VIEW -> { + src.data?.let { uriOriginal -> + try { + val uri = saveToCache(uriOriginal) + val dst = Intent(action) + dst.setDataAndType(uri, type) + copyExtraTexts(dst, src) + return dst + } catch (ex: Throwable) { + log.e(ex, "remake failed. src=$src") + } + } + } + Intent.ACTION_SEND -> { + var uri = src.getStreamUriExtra() + ?: return src // text/plainの場合 try { - val uri = saveToCache(uriOriginal) + uri = saveToCache(uri) + val dst = Intent(action) - dst.setDataAndType(uri, type) + dst.type = type + dst.putExtra(Intent.EXTRA_STREAM, uri) copyExtraTexts(dst, src) return dst } catch (ex: Throwable) { log.e(ex, "remake failed. src=$src") } } - } else if (Intent.ACTION_SEND == action) { - var uri = src.getStreamUriExtra() - ?: return src // text/plainの場合 - try { - uri = saveToCache(uri) - - val dst = Intent(action) - dst.type = type - dst.putExtra(Intent.EXTRA_STREAM, uri) - copyExtraTexts(dst, src) - return dst - } catch (ex: Throwable) { - log.e(ex, "remake failed. src=$src") - } - } else if (Intent.ACTION_SEND_MULTIPLE == action) { - val listUri = src.getStreamUriListExtra() - ?: return null - val listDst = ArrayList() - for (uriOriginal in listUri) { - if (uriOriginal != null) { - try { - val uri = saveToCache(uriOriginal) - listDst.add(uri) - } catch (ex: Throwable) { - log.e(ex, "remake failed. src=$src") + Intent.ACTION_SEND_MULTIPLE -> { + val listUri = src.getStreamUriListExtra() + ?: return null + val listDst = ArrayList() + for (uriOriginal in listUri) { + if (uriOriginal != null) { + try { + val uri = saveToCache(uriOriginal) + listDst.add(uri) + } catch (ex: Throwable) { + log.e(ex, "remake failed. src=$src") + } } } + if (listDst.isEmpty()) return null + val dst = Intent(action) + dst.type = type + dst.putParcelableArrayListExtra(Intent.EXTRA_STREAM, listDst) + copyExtraTexts(dst, src) + return dst } - if (listDst.isEmpty()) return null - val dst = Intent(action) - dst.type = type - dst.putParcelableArrayListExtra(Intent.EXTRA_STREAM, listDst) - copyExtraTexts(dst, src) - return dst } } else if (Intent.ACTION_SEND == action) { diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActMain.kt b/app/src/main/java/jp/juggler/subwaytooter/ActMain.kt index 21712168..ce7d1159 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ActMain.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/ActMain.kt @@ -657,13 +657,13 @@ class ActMain : AppCompatActivity(), } // 外部から受け取ったUriの処理 - val uri = ActCallback.last_uri.getAndSet(null) + val uri = ActCallback.lastUri.getAndSet(null) if (uri != null) { handleIntentUri(uri) } // 外部から受け取ったUriの処理 - val intent = ActCallback.sent_intent.getAndSet(null) + val intent = ActCallback.sharedIntent.getAndSet(null) if (intent != null) { handleSharedIntent(intent) } diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActMediaViewer.kt b/app/src/main/java/jp/juggler/subwaytooter/ActMediaViewer.kt index c04a17ed..ffe0dcc5 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ActMediaViewer.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/ActMediaViewer.kt @@ -13,6 +13,7 @@ import android.os.Environment import android.os.SystemClock import android.view.View import android.view.Window +import androidx.annotation.OptIn import androidx.appcompat.app.AppCompatActivity import androidx.core.net.toUri import androidx.media3.common.MediaItem @@ -20,6 +21,7 @@ import androidx.media3.common.PlaybackException import androidx.media3.common.Player import androidx.media3.common.Timeline import androidx.media3.common.util.RepeatModeUtil +import androidx.media3.common.util.UnstableApi import androidx.media3.exoplayer.ExoPlayer import androidx.media3.exoplayer.source.LoadEventInfo import androidx.media3.exoplayer.source.MediaLoadData @@ -60,7 +62,6 @@ import javax.net.ssl.HttpsURLConnection import kotlin.math.max import kotlin.math.min -@androidx.annotation.OptIn(markerClass = [androidx.media3.common.util.UnstableApi::class]) class ActMediaViewer : AppCompatActivity(), View.OnClickListener { companion object { @@ -226,6 +227,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener { } } + @UnstableApi private val mediaSourceEventListener = object : MediaSourceEventListener { override fun onLoadStarted( windowIndex: Int, @@ -306,7 +308,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener { this.showDescription = intent.getBooleanExtra(EXTRA_SHOW_DESCRIPTION, showDescription) - this.serviceType = ServiceType.values()[ + this.serviceType = ServiceType.entries[ savedInstanceState?.int(EXTRA_SERVICE_TYPE) ?: intent.int(EXTRA_SERVICE_TYPE) ?: 0 ] @@ -349,7 +351,8 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener { ) } - internal fun initUI() { + @OptIn(UnstableApi::class) + private fun initUI() { setContentView(views.root) views.pbvImage.background = MediaBackgroundDrawable( @@ -409,6 +412,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener { exoPlayer = ExoPlayer.Builder(this).build() exoPlayer.addListener(playerListener) + views.pvVideo.run { player = exoPlayer controllerAutoShow = false @@ -916,7 +920,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener { private fun mediaBackgroundDialog() { launchAndShowError { actionsDialog(getString(R.string.background_pattern)) { - for (k in MediaBackgroundDrawable.Kind.values()) { + for (k in MediaBackgroundDrawable.Kind.entries) { if (!k.isMediaBackground) continue action(k.name) { val idx = k.toIndex() diff --git a/app/src/main/java/jp/juggler/subwaytooter/AppState.kt b/app/src/main/java/jp/juggler/subwaytooter/AppState.kt index 4d9028bb..630fd8d7 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/AppState.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/AppState.kt @@ -10,6 +10,7 @@ import android.os.SystemClock import android.speech.tts.TextToSpeech import android.speech.tts.Voice import android.text.Spannable +import androidx.core.content.ContextCompat import jp.juggler.subwaytooter.api.entity.TootStatus import jp.juggler.subwaytooter.column.Column import jp.juggler.subwaytooter.column.ColumnEncoder @@ -411,7 +412,7 @@ class AppState( } catch (ignored: Throwable) { null } - if (voiceSet == null || voiceSet.isEmpty()) { + if (voiceSet.isNullOrEmpty()) { log.d("TextToSpeech.getVoices returns null or empty set.") } else { val lang = defaultLocale(context).toLanguageTag() @@ -427,9 +428,10 @@ class AppState( handler.post(procFlushSpeechQueue) - context.registerReceiver( - ttsReceiver, - IntentFilter(TextToSpeech.ACTION_TTS_QUEUE_PROCESSING_COMPLETED) + ContextCompat.registerReceiver( + context, + IntentFilter(TextToSpeech.ACTION_TTS_QUEUE_PROCESSING_COMPLETED), + ContextCompat.RECEIVER_NOT_EXPORTED, ) // tts.setOnUtteranceProgressListener( new UtteranceProgressListener() { diff --git a/app/src/main/java/jp/juggler/subwaytooter/actpost/ActPostAttachment.kt b/app/src/main/java/jp/juggler/subwaytooter/actpost/ActPostAttachment.kt index 9cb56f85..c905bc27 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/actpost/ActPostAttachment.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/actpost/ActPostAttachment.kt @@ -21,7 +21,7 @@ import jp.juggler.subwaytooter.calcIconRound import jp.juggler.subwaytooter.defaultColorIcon import jp.juggler.subwaytooter.dialog.actionsDialog import jp.juggler.subwaytooter.dialog.decodeAttachmentBitmap -import jp.juggler.subwaytooter.dialog.dialogArrachmentRearrange +import jp.juggler.subwaytooter.dialog.dialogAttachmentRearrange import jp.juggler.subwaytooter.dialog.focusPointDialog import jp.juggler.subwaytooter.dialog.showTextInputDialog import jp.juggler.subwaytooter.pref.PrefB @@ -454,7 +454,7 @@ fun ActPost.onPickCustomThumbnailImpl(pa: PostAttachment, src: GetContentResultE fun ActPost.rearrangeAttachments() = lifecycleScope.launch { try { - val rearranged = dialogArrachmentRearrange(attachmentList) + val rearranged = dialogAttachmentRearrange(attachmentList) // 入れ替え中にアップロード失敗などで要素が消えることがあるので // 最新のattachmentListを指定順に並べ替える val remain = ArrayList(attachmentList) diff --git a/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgAttachmentRearrange.kt b/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgAttachmentRearrange.kt index 2a1d9903..68e184b4 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgAttachmentRearrange.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgAttachmentRearrange.kt @@ -31,7 +31,7 @@ private val log = LogCategory("DlgAttachmentRearrange") * 投稿画面で添付メディアを並べ替えるダイアログを開き、OKボタンが押されるまで非同期待機する。 * OK以外の方法で閉じたらCancellationExceptionを投げる。 */ -suspend fun AppCompatActivity.dialogArrachmentRearrange( +suspend fun AppCompatActivity.dialogAttachmentRearrange( initialList: List, ): List = suspendCancellableCoroutine { cont -> val views = AttachmentRearrangeDialogBinding.inflate(layoutInflater) diff --git a/app/src/main/res/xml/backup_spec.xml b/app/src/main/res/xml/backup_spec.xml index 1b3de7a5..52a06cac 100644 --- a/app/src/main/res/xml/backup_spec.xml +++ b/app/src/main/res/xml/backup_spec.xml @@ -1,4 +1,6 @@ - + diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml new file mode 100644 index 00000000..f463f518 --- /dev/null +++ b/app/src/main/res/xml/data_extraction_rules.xml @@ -0,0 +1,13 @@ + + + + + + + + +