コード整理
This commit is contained in:
parent
99ff481bc4
commit
f4093abba9
|
@ -4,10 +4,19 @@
|
|||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="GRADLE" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<compositeConfiguration>
|
||||
<compositeBuild compositeDefinitionSource="SCRIPT">
|
||||
<builds>
|
||||
<build path="$PROJECT_DIR$/buildSrc" name="buildSrc">
|
||||
<projects>
|
||||
<project path="$PROJECT_DIR$/buildSrc" />
|
||||
</projects>
|
||||
</build>
|
||||
</builds>
|
||||
</compositeBuild>
|
||||
</compositeConfiguration>
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="zulu-17" />
|
||||
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
|
@ -23,6 +32,7 @@
|
|||
<option value="$PROJECT_DIR$/sample_apng" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveExternalAnnotations" value="false" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
<application
|
||||
android:name=".App1"
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
android:fullBackupContent="@xml/backup_spec"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
|
|
|
@ -20,8 +20,8 @@ class ActCallback : AppCompatActivity() {
|
|||
companion object {
|
||||
private val log = LogCategory("ActCallback")
|
||||
|
||||
internal val last_uri = AtomicReference<Uri>(null)
|
||||
internal val sent_intent = AtomicReference<Intent>(null)
|
||||
internal val lastUri = AtomicReference<Uri>(null)
|
||||
internal val sharedIntent = AtomicReference<Intent>(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<Uri>()
|
||||
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<Uri>()
|
||||
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) {
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -31,7 +31,7 @@ private val log = LogCategory("DlgAttachmentRearrange")
|
|||
* 投稿画面で添付メディアを並べ替えるダイアログを開き、OKボタンが押されるまで非同期待機する。
|
||||
* OK以外の方法で閉じたらCancellationExceptionを投げる。
|
||||
*/
|
||||
suspend fun AppCompatActivity.dialogArrachmentRearrange(
|
||||
suspend fun AppCompatActivity.dialogAttachmentRearrange(
|
||||
initialList: List<PostAttachment>,
|
||||
): List<PostAttachment> = suspendCancellableCoroutine { cont ->
|
||||
val views = AttachmentRearrangeDialogBinding.inflate(layoutInflater)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<full-backup-content>
|
||||
<exclude domain="sharedpref" path="device.xml"/>
|
||||
<exclude
|
||||
domain="sharedpref"
|
||||
path="device.xml" />
|
||||
</full-backup-content>
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<data-extraction-rules>
|
||||
<cloud-backup>
|
||||
<exclude
|
||||
domain="sharedpref"
|
||||
path="device.xml" />
|
||||
</cloud-backup>
|
||||
<device-transfer>
|
||||
<exclude
|
||||
domain="sharedpref"
|
||||
path="device.xml" />
|
||||
</device-transfer>
|
||||
</data-extraction-rules>
|
Loading…
Reference in New Issue