minSdkVersion 26
This commit is contained in:
parent
03058b25b2
commit
4001c53cba
|
@ -170,7 +170,7 @@ dependencies {
|
|||
kapt 'androidx.annotation:annotation:1.4.0'
|
||||
|
||||
// https://firebase.google.com/support/release-notes/android
|
||||
implementation "com.google.firebase:firebase-messaging:23.0.6"
|
||||
implementation "com.google.firebase:firebase-messaging:23.0.7"
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-reflect"
|
||||
testImplementation "org.jetbrains.kotlin:kotlin-test"
|
||||
|
|
|
@ -5,9 +5,7 @@ import android.app.Activity
|
|||
import android.content.ContentValues
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.media.RingtoneManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.provider.MediaStore
|
||||
|
@ -18,7 +16,6 @@ import android.view.View
|
|||
import android.widget.*
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import jp.juggler.subwaytooter.Styler.defaultColorIcon
|
||||
import jp.juggler.subwaytooter.action.accountRemove
|
||||
import jp.juggler.subwaytooter.api.TootApiClient
|
||||
|
@ -117,8 +114,6 @@ class ActAccountSetting : AppCompatActivity(),
|
|||
|
||||
private lateinit var viewBinding: ActAccountSettingBinding
|
||||
|
||||
private var notificationSoundUri: String? = null
|
||||
|
||||
private lateinit var nameInvalidator: NetworkEmojiInvalidator
|
||||
private lateinit var noteInvalidator: NetworkEmojiInvalidator
|
||||
private lateinit var defaultTextInvalidator: NetworkEmojiInvalidator
|
||||
|
@ -153,20 +148,6 @@ class ActAccountSetting : AppCompatActivity(),
|
|||
showAcctColor()
|
||||
}
|
||||
|
||||
private val arNotificationSound = ActivityResultHandler(log) { r ->
|
||||
r.decodeRingtonePickerResult()?.let { uri ->
|
||||
notificationSoundUri = uri.toString()
|
||||
saveUIToData()
|
||||
// Ringtone ringtone = RingtoneManager.getRingtone(getApplicationContext(), uri);
|
||||
// TextView ringView = (TextView) findViewById(R.id.ringtone);
|
||||
// ringView.setText(ringtone.getTitle(getApplicationContext()));
|
||||
// ringtone.setStreamType(AudioManager.STREAM_ALARM);
|
||||
// ringtone.play();
|
||||
// SystemClock.sleep(1000);
|
||||
// ringtone.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private val arAddAttachment = ActivityResultHandler(log) { r ->
|
||||
if (r.isNotOk) return@ActivityResultHandler
|
||||
r.data
|
||||
|
@ -217,7 +198,6 @@ class ActAccountSetting : AppCompatActivity(),
|
|||
prPickHeader.register(this)
|
||||
|
||||
arShowAcctColor.register(this)
|
||||
arNotificationSound.register(this)
|
||||
arAddAttachment.register(this)
|
||||
arCameraImage.register(this)
|
||||
|
||||
|
@ -438,8 +418,6 @@ class ActAccountSetting : AppCompatActivity(),
|
|||
cbConfirmReaction.isChecked = a.confirm_reaction
|
||||
cbConfirmUnbookmark.isChecked = a.confirm_unbookmark
|
||||
|
||||
notificationSoundUri = a.sound_uri
|
||||
|
||||
etDefaultText.setText(a.default_text)
|
||||
etMaxTootChars.setText(a.max_toot_chars.toString())
|
||||
|
||||
|
@ -511,17 +489,10 @@ class ActAccountSetting : AppCompatActivity(),
|
|||
cbConfirmReaction,
|
||||
).forEach { it.isEnabledAlpha = enabled }
|
||||
|
||||
val enabledOldNotification = enabled && Build.VERSION.SDK_INT < 26
|
||||
arrayOf(
|
||||
btnNotificationSoundEdit,
|
||||
btnNotificationSoundReset,
|
||||
).forEach { it.isEnabledAlpha = enabledOldNotification }
|
||||
|
||||
val enabledNewNotification = enabled && Build.VERSION.SDK_INT >= 26
|
||||
arrayOf(
|
||||
btnNotificationStyleEdit,
|
||||
btnNotificationStyleEditReply,
|
||||
).forEach { it.isEnabledAlpha = enabledNewNotification }
|
||||
).forEach { it.isEnabledAlpha = enabled }
|
||||
}
|
||||
|
||||
showVisibility()
|
||||
|
@ -574,15 +545,10 @@ class ActAccountSetting : AppCompatActivity(),
|
|||
account.confirm_reaction = cbConfirmReaction.isChecked
|
||||
account.confirm_unbookmark = cbConfirmUnbookmark.isChecked
|
||||
|
||||
account.sound_uri = notificationSoundUri ?: ""
|
||||
account.sound_uri = ""
|
||||
account.default_text = etDefaultText.text.toString()
|
||||
|
||||
val num = etMaxTootChars.parseInt()
|
||||
account.max_toot_chars = if (num != null && num >= 0) {
|
||||
num
|
||||
} else {
|
||||
0
|
||||
}
|
||||
account.max_toot_chars = etMaxTootChars.parseInt()?.takeIf { it > 0 } ?: 0
|
||||
|
||||
account.movie_max_megabytes = etMovieSizeMax.text.toString().trim()
|
||||
account.image_max_megabytes = etMediaSizeMax.text.toString().trim()
|
||||
|
@ -639,13 +605,6 @@ class ActAccountSetting : AppCompatActivity(),
|
|||
ActNickname.createIntent(this, account.acct, false),
|
||||
)
|
||||
|
||||
R.id.btnNotificationSoundEdit -> openNotificationSoundPicker()
|
||||
|
||||
R.id.btnNotificationSoundReset -> {
|
||||
notificationSoundUri = ""
|
||||
saveUIToData()
|
||||
}
|
||||
|
||||
R.id.btnProfileAvatar -> pickAvatarImage()
|
||||
|
||||
R.id.btnProfileHeader -> pickHeaderImage()
|
||||
|
@ -816,22 +775,6 @@ class ActAccountSetting : AppCompatActivity(),
|
|||
finish()
|
||||
}
|
||||
|
||||
private fun openNotificationSoundPicker() {
|
||||
val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER)
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION)
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, R.string.notification_sound)
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false)
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, false)
|
||||
|
||||
notificationSoundUri.mayUri()?.let { uri ->
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, uri)
|
||||
}
|
||||
|
||||
val chooser = Intent.createChooser(intent, getString(R.string.notification_sound))
|
||||
|
||||
arNotificationSound.launch(chooser)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private fun initializeProfile() {
|
||||
|
@ -1347,18 +1290,6 @@ class ActAccountSetting : AppCompatActivity(),
|
|||
a.show(this, null)
|
||||
}
|
||||
|
||||
private fun preparePermission(requestCode: Int) {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
// No explanation needed, we can request the permission.
|
||||
|
||||
ActivityCompat.requestPermissions(
|
||||
this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), requestCode
|
||||
)
|
||||
return
|
||||
}
|
||||
showToast(true, R.string.missing_permission_to_access_media)
|
||||
}
|
||||
|
||||
private fun performAttachment(propName: String) {
|
||||
try {
|
||||
state.propName = propName
|
||||
|
|
|
@ -3,19 +3,16 @@ package jp.juggler.subwaytooter
|
|||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.media.RingtoneManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.jrummyapps.android.colorpicker.ColorPickerDialog
|
||||
import com.jrummyapps.android.colorpicker.ColorPickerDialogListener
|
||||
import jp.juggler.subwaytooter.api.entity.Acct
|
||||
import jp.juggler.subwaytooter.databinding.ActNicknameBinding
|
||||
import jp.juggler.subwaytooter.table.AcctColor
|
||||
import jp.juggler.util.*
|
||||
import org.jetbrains.anko.backgroundColor
|
||||
|
@ -41,17 +38,9 @@ class ActNickname : AppCompatActivity(), View.OnClickListener, ColorPickerDialog
|
|||
}
|
||||
}
|
||||
|
||||
private lateinit var tvPreview: TextView
|
||||
private lateinit var tvAcct: TextView
|
||||
private lateinit var etNickname: EditText
|
||||
private lateinit var btnTextColorEdit: View
|
||||
private lateinit var btnTextColorReset: View
|
||||
private lateinit var btnBackgroundColorEdit: View
|
||||
private lateinit var btnBackgroundColorReset: View
|
||||
private lateinit var btnSave: View
|
||||
private lateinit var btnDiscard: View
|
||||
private lateinit var btnNotificationSoundEdit: Button
|
||||
private lateinit var btnNotificationSoundReset: Button
|
||||
private val views by lazy {
|
||||
ActNicknameBinding.inflate(layoutInflater)
|
||||
}
|
||||
|
||||
private var showNotificationSound = false
|
||||
private lateinit var acctAscii: String
|
||||
|
@ -95,40 +84,25 @@ class ActNickname : AppCompatActivity(), View.OnClickListener, ColorPickerDialog
|
|||
else -> R.string.nickname_and_color
|
||||
}
|
||||
)
|
||||
setContentView(R.layout.act_nickname)
|
||||
setContentView(views.root)
|
||||
App1.initEdgeToEdge(this)
|
||||
|
||||
Styler.fixHorizontalPadding(findViewById(R.id.llContent))
|
||||
|
||||
tvPreview = findViewById(R.id.tvPreview)
|
||||
tvAcct = findViewById(R.id.tvAcct)
|
||||
views.btnTextColorEdit.setOnClickListener(this)
|
||||
views.btnTextColorReset.setOnClickListener(this)
|
||||
views.btnBackgroundColorEdit.setOnClickListener(this)
|
||||
views.btnBackgroundColorReset.setOnClickListener(this)
|
||||
views.btnSave.setOnClickListener(this)
|
||||
views.btnDiscard.setOnClickListener(this)
|
||||
|
||||
etNickname = findViewById(R.id.etNickname)
|
||||
btnTextColorEdit = findViewById(R.id.btnTextColorEdit)
|
||||
btnTextColorReset = findViewById(R.id.btnTextColorReset)
|
||||
btnBackgroundColorEdit = findViewById(R.id.btnBackgroundColorEdit)
|
||||
btnBackgroundColorReset = findViewById(R.id.btnBackgroundColorReset)
|
||||
btnSave = findViewById(R.id.btnSave)
|
||||
btnDiscard = findViewById(R.id.btnDiscard)
|
||||
views.btnNotificationSoundEdit.setOnClickListener(this)
|
||||
views.btnNotificationSoundReset.setOnClickListener(this)
|
||||
|
||||
etNickname = findViewById(R.id.etNickname)
|
||||
btnTextColorEdit.setOnClickListener(this)
|
||||
btnTextColorReset.setOnClickListener(this)
|
||||
btnBackgroundColorEdit.setOnClickListener(this)
|
||||
btnBackgroundColorReset.setOnClickListener(this)
|
||||
btnSave.setOnClickListener(this)
|
||||
btnDiscard.setOnClickListener(this)
|
||||
views.btnNotificationSoundEdit.isEnabledAlpha = false
|
||||
views.btnNotificationSoundReset.isEnabledAlpha = false
|
||||
|
||||
btnNotificationSoundEdit = findViewById(R.id.btnNotificationSoundEdit)
|
||||
btnNotificationSoundReset = findViewById(R.id.btnNotificationSoundReset)
|
||||
btnNotificationSoundEdit.setOnClickListener(this)
|
||||
btnNotificationSoundReset.setOnClickListener(this)
|
||||
|
||||
val bBefore8 = Build.VERSION.SDK_INT < 26
|
||||
btnNotificationSoundEdit.isEnabledAlpha = bBefore8
|
||||
btnNotificationSoundReset.isEnabledAlpha = bBefore8
|
||||
|
||||
etNickname.addTextChangedListener(object : TextWatcher {
|
||||
views.etNickname.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(
|
||||
s: CharSequence,
|
||||
start: Int,
|
||||
|
@ -152,12 +126,12 @@ class ActNickname : AppCompatActivity(), View.OnClickListener, ColorPickerDialog
|
|||
findViewById<View>(R.id.llNotificationSound).visibility =
|
||||
if (showNotificationSound) View.VISIBLE else View.GONE
|
||||
|
||||
tvAcct.text = acctPretty
|
||||
views.tvAcct.text = acctPretty
|
||||
|
||||
val ac = AcctColor.load(acctAscii, acctPretty)
|
||||
colorBg = ac.color_bg
|
||||
colorFg = ac.color_fg
|
||||
etNickname.setText(ac.nickname)
|
||||
views.etNickname.setText(ac.nickname)
|
||||
notificationSoundUri = ac.notification_sound
|
||||
|
||||
loadingBusy = false
|
||||
|
@ -169,7 +143,7 @@ class ActNickname : AppCompatActivity(), View.OnClickListener, ColorPickerDialog
|
|||
AcctColor(
|
||||
acctAscii,
|
||||
acctPretty,
|
||||
etNickname.text.toString().trim { it <= ' ' },
|
||||
views.etNickname.text.toString().trim { it <= ' ' },
|
||||
colorFg,
|
||||
colorBg,
|
||||
notificationSoundUri
|
||||
|
@ -177,17 +151,17 @@ class ActNickname : AppCompatActivity(), View.OnClickListener, ColorPickerDialog
|
|||
}
|
||||
|
||||
private fun show() {
|
||||
val s = etNickname.text.toString().trim { it <= ' ' }
|
||||
tvPreview.text = s.notEmpty() ?: acctPretty
|
||||
tvPreview.textColor = colorFg.notZero() ?: attrColor(R.attr.colorTimeSmall)
|
||||
tvPreview.backgroundColor = colorBg
|
||||
val s = views.etNickname.text.toString().trim { it <= ' ' }
|
||||
views.tvPreview.text = s.notEmpty() ?: acctPretty
|
||||
views.tvPreview.textColor = colorFg.notZero() ?: attrColor(R.attr.colorTimeSmall)
|
||||
views.tvPreview.backgroundColor = colorBg
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
val builder: ColorPickerDialog.Builder
|
||||
when (v.id) {
|
||||
R.id.btnTextColorEdit -> {
|
||||
etNickname.hideKeyboard()
|
||||
views.etNickname.hideKeyboard()
|
||||
builder = ColorPickerDialog.newBuilder()
|
||||
.setDialogType(ColorPickerDialog.TYPE_CUSTOM)
|
||||
.setAllowPresets(true)
|
||||
|
@ -203,7 +177,7 @@ class ActNickname : AppCompatActivity(), View.OnClickListener, ColorPickerDialog
|
|||
}
|
||||
|
||||
R.id.btnBackgroundColorEdit -> {
|
||||
etNickname.hideKeyboard()
|
||||
views.etNickname.hideKeyboard()
|
||||
builder = ColorPickerDialog.newBuilder()
|
||||
.setDialogType(ColorPickerDialog.TYPE_CUSTOM)
|
||||
.setAllowPresets(true)
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.text.Editable
|
||||
|
@ -302,12 +301,12 @@ class ActPost : AppCompatActivity(),
|
|||
}
|
||||
|
||||
override fun resumeCustomThumbnailTarget(id: String?): PostAttachment? {
|
||||
id?: return null
|
||||
return attachmentList.find{ it.attachment?.id?.toString() == id }
|
||||
id ?: return null
|
||||
return attachmentList.find { it.attachment?.id?.toString() == id }
|
||||
}
|
||||
|
||||
override fun onPickCustomThumbnail(pa: PostAttachment,src: GetContentResultEntry) {
|
||||
onPickCustomThumbnailImpl(pa,src)
|
||||
override fun onPickCustomThumbnail(pa: PostAttachment, src: GetContentResultEntry) {
|
||||
onPickCustomThumbnailImpl(pa, src)
|
||||
}
|
||||
|
||||
fun initUI() {
|
||||
|
@ -327,7 +326,7 @@ class ActPost : AppCompatActivity(),
|
|||
}
|
||||
|
||||
views.root.callbackOnSizeChanged = { _, _, _, _ ->
|
||||
if (Build.VERSION.SDK_INT >= 24 && isMultiWindowPost) saveWindowSize()
|
||||
if (isMultiWindowPost) saveWindowSize()
|
||||
// ビューのw,hはシステムバーその他を含まないので使わない
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ class ActText : AppCompatActivity() {
|
|||
etText.setText(sv)
|
||||
|
||||
// Android 9 以降ではフォーカスがないとsetSelectionできない
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
if (Build.VERSION.SDK_INT >= 28) {
|
||||
etText.requestFocus()
|
||||
etText.hideKeyboard()
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package jp.juggler.subwaytooter.actmain
|
|||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import jp.juggler.subwaytooter.ActMain
|
||||
import jp.juggler.subwaytooter.R
|
||||
|
@ -106,15 +105,10 @@ fun ActMain.handleOtherUri(uri: Uri): Boolean {
|
|||
val errorMessage = getString(R.string.cant_handle_uri_of, url)
|
||||
|
||||
try {
|
||||
val queryFlag = if (Build.VERSION.SDK_INT >= 23) {
|
||||
// Android 6.0以降
|
||||
// MATCH_DEFAULT_ONLY だと標準の設定に指定されたアプリがあるとソレしか出てこない
|
||||
// MATCH_ALL を指定すると 以前と同じ挙動になる
|
||||
PackageManager.MATCH_ALL
|
||||
} else {
|
||||
// Android 5.xまでは MATCH_DEFAULT_ONLY でマッチするすべてのアプリを取得できる
|
||||
PackageManager.MATCH_DEFAULT_ONLY
|
||||
}
|
||||
// Android 6.0以降
|
||||
// MATCH_DEFAULT_ONLY だと標準の設定に指定されたアプリがあるとソレしか出てこない
|
||||
// MATCH_ALL を指定すると 以前と同じ挙動になる
|
||||
val queryFlag = PackageManager.MATCH_ALL
|
||||
|
||||
// queryIntentActivities に渡すURLは実在しないホストのものにする
|
||||
val intent = Intent(Intent.ACTION_VIEW, "https://dummy.subwaytooter.club/".toUri())
|
||||
|
|
|
@ -209,23 +209,6 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
|
||||
section(R.string.notifications) {
|
||||
|
||||
group(R.string.notification_style_before_oreo) {
|
||||
|
||||
checkbox(PrefB.bpNotificationSound, R.string.sound) {
|
||||
enabled = Build.VERSION.SDK_INT < 26
|
||||
}
|
||||
|
||||
checkbox(PrefB.bpNotificationVibration, R.string.vibration) {
|
||||
enabled = Build.VERSION.SDK_INT < 26
|
||||
}
|
||||
|
||||
checkbox(PrefB.bpNotificationLED, R.string.led) {
|
||||
enabled = Build.VERSION.SDK_INT < 26
|
||||
}
|
||||
|
||||
sample(R.layout.setting_sample_notification_desc)
|
||||
}
|
||||
|
||||
text(
|
||||
PrefS.spPullNotificationCheckInterval,
|
||||
R.string.pull_notification_check_interval,
|
||||
|
@ -234,13 +217,13 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
|
||||
sw(PrefB.bpShowAcctInSystemNotification, R.string.show_acct_in_system_notification)
|
||||
|
||||
sw(PrefB.bpSeparateReplyNotificationGroup, R.string.separate_notification_group_for_reply) {
|
||||
enabled = Build.VERSION.SDK_INT >= 26
|
||||
}
|
||||
sw(PrefB.bpSeparateReplyNotificationGroup, R.string.separate_notification_group_for_reply)
|
||||
|
||||
sw(PrefB.bpDivideNotification, R.string.divide_notification)
|
||||
|
||||
sw(PrefB.bpMisskeyNotificationCheck, R.string.enable_misskey_notification_check)
|
||||
|
||||
sample(R.layout.setting_sample_notification_desc)
|
||||
}
|
||||
|
||||
section(R.string.behavior) {
|
||||
|
@ -803,7 +786,8 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
|
|||
colorAlpha(PrefI.ipEventBgColorVote, R.string.vote_polls)
|
||||
colorAlpha(PrefI.ipEventBgColorStatus, R.string.status)
|
||||
colorAlpha(PrefI.ipEventBgColorUpdate, R.string.notification_type_update)
|
||||
colorAlpha(PrefI.ipEventBgColorStatusReference, R.string.notification_type_status_reference)
|
||||
colorAlpha(PrefI.ipEventBgColorStatusReference,
|
||||
R.string.notification_type_status_reference)
|
||||
colorAlpha(PrefI.ipEventBgColorSignUp, R.string.notification_type_signup)
|
||||
|
||||
colorAlpha(
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
package jp.juggler.subwaytooter.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Build
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import android.widget.*
|
||||
import android.app.Activity
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.util.CustomShare
|
||||
import jp.juggler.subwaytooter.util.cn
|
||||
|
@ -33,7 +32,7 @@ class DlgAppPicker(
|
|||
class ListItem(
|
||||
val icon: Drawable?,
|
||||
val text: String,
|
||||
val componentName: String
|
||||
val componentName: String,
|
||||
)
|
||||
|
||||
val list = ArrayList<ListItem>().apply {
|
||||
|
@ -41,11 +40,7 @@ class DlgAppPicker(
|
|||
val pm = activity.packageManager
|
||||
val listResolveInfo = pm.queryIntentActivities(
|
||||
intent,
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
PackageManager.MATCH_ALL
|
||||
} else {
|
||||
0
|
||||
}
|
||||
PackageManager.MATCH_ALL,
|
||||
)
|
||||
|
||||
for (it in listResolveInfo) {
|
||||
|
|
|
@ -3,7 +3,6 @@ package jp.juggler.subwaytooter.dialog
|
|||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.Dialog
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
|
@ -50,15 +49,8 @@ class DlgDateTime(
|
|||
this
|
||||
)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
timePicker.hour = c.get(Calendar.HOUR_OF_DAY)
|
||||
timePicker.minute = c.get(Calendar.MINUTE)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
timePicker.currentHour = c.get(Calendar.HOUR_OF_DAY)
|
||||
@Suppress("DEPRECATION")
|
||||
timePicker.currentMinute = c.get(Calendar.MINUTE)
|
||||
}
|
||||
timePicker.hour = c.get(Calendar.HOUR_OF_DAY)
|
||||
timePicker.minute = c.get(Calendar.MINUTE)
|
||||
|
||||
timePicker.setIs24HourView(
|
||||
when (Settings.System.getString(activity.contentResolver, Settings.System.TIME_12_24)) {
|
||||
|
@ -100,25 +92,15 @@ class DlgDateTime(
|
|||
}
|
||||
|
||||
private fun getTime(): Long {
|
||||
val y = datePicker.year
|
||||
val m = datePicker.month
|
||||
val d = datePicker.dayOfMonth
|
||||
|
||||
val h: Int
|
||||
val j: Int
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
h = timePicker.hour
|
||||
j = timePicker.minute
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
h = timePicker.currentHour
|
||||
@Suppress("DEPRECATION")
|
||||
j = timePicker.currentMinute
|
||||
}
|
||||
|
||||
val c = GregorianCalendar.getInstance(TimeZone.getDefault())
|
||||
c.set(y, m, d, h, j)
|
||||
c.set(Calendar.SECOND, 0)
|
||||
c.set(
|
||||
datePicker.year,
|
||||
datePicker.month,
|
||||
datePicker.dayOfMonth,
|
||||
timePicker.hour,
|
||||
timePicker.minute,
|
||||
0,
|
||||
)
|
||||
c.set(Calendar.MILLISECOND, 0)
|
||||
return c.timeInMillis
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.app.Notification
|
|||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
|
@ -34,21 +33,17 @@ object CheckerNotification {
|
|||
// val cancelIntent = WorkManager.getInstance(context)
|
||||
// .createCancelPendingIntent(id)
|
||||
|
||||
val builder = if (Build.VERSION.SDK_INT >= 26) {
|
||||
// Android 8 から、通知のスタイルはユーザが管理することになった
|
||||
// NotificationChannel を端末に登録しておけば、チャネルごとに管理画面が作られる
|
||||
// The user-visible description of the channel.
|
||||
val channel = NotificationHelper.createNotificationChannel(
|
||||
context,
|
||||
"PollingForegrounder",
|
||||
"real-time message notifier",
|
||||
null,
|
||||
NotificationManagerCompat.IMPORTANCE_LOW
|
||||
)
|
||||
NotificationCompat.Builder(context, channel.id)
|
||||
} else {
|
||||
NotificationCompat.Builder(context, "not_used")
|
||||
}
|
||||
// Android 8 から、通知のスタイルはユーザが管理することになった
|
||||
// NotificationChannel を端末に登録しておけば、チャネルごとに管理画面が作られる
|
||||
// The user-visible description of the channel.
|
||||
val channel = NotificationHelper.createNotificationChannel(
|
||||
context,
|
||||
"PollingForegrounder",
|
||||
"real-time message notifier",
|
||||
null,
|
||||
NotificationManagerCompat.IMPORTANCE_LOW
|
||||
)
|
||||
val builder = NotificationCompat.Builder(context, channel.id)
|
||||
|
||||
// 通知タップ時のPendingIntent
|
||||
val clickIntent = Intent(context, ActMain::class.java).apply {
|
||||
|
@ -58,10 +53,7 @@ object CheckerNotification {
|
|||
context,
|
||||
2,
|
||||
clickIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or when {
|
||||
Build.VERSION.SDK_INT >= 23 -> PendingIntent.FLAG_IMMUTABLE
|
||||
else -> 0
|
||||
}
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
// ここは常に白テーマのアイコンと色を使う
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
package jp.juggler.subwaytooter.notification
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
|
@ -14,9 +11,11 @@ import jp.juggler.subwaytooter.ActCallback
|
|||
import jp.juggler.subwaytooter.EventReceiver
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.pref.PrefB
|
||||
import jp.juggler.subwaytooter.table.AcctColor
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.util.*
|
||||
import jp.juggler.util.LogCategory
|
||||
import jp.juggler.util.encodePercent
|
||||
import jp.juggler.util.toMutableMap
|
||||
import jp.juggler.util.toUri
|
||||
|
||||
object MessageNotification {
|
||||
private val log = LogCategory("MessageNotification")
|
||||
|
@ -40,7 +39,7 @@ object MessageNotification {
|
|||
*
|
||||
*/
|
||||
fun NotificationManager.removeMessageNotification(account: SavedAccount, tag: String) {
|
||||
if (Build.VERSION.SDK_INT >= 23 && PrefB.bpDivideNotification()) {
|
||||
if (PrefB.bpDivideNotification()) {
|
||||
activeNotifications?.filterNotNull()?.filter {
|
||||
it.id == NOTIFICATION_ID_MESSAGE && it.tag.startsWith("$tag/")
|
||||
}?.forEach {
|
||||
|
@ -55,7 +54,6 @@ object MessageNotification {
|
|||
/**
|
||||
* 表示中のメッセージ通知の一覧
|
||||
*/
|
||||
@TargetApi(23)
|
||||
fun NotificationManager.getMessageNotifications(tag: String) =
|
||||
activeNotifications?.filterNotNull()?.filter {
|
||||
it.id == NOTIFICATION_ID_MESSAGE && it.tag.startsWith("$tag/")
|
||||
|
@ -72,18 +70,14 @@ object MessageNotification {
|
|||
) {
|
||||
log.d("showNotification[${account.acct.pretty}] creating notification(1)")
|
||||
|
||||
val builder = if (Build.VERSION.SDK_INT >= 26) {
|
||||
// Android 8 から、通知のスタイルはユーザが管理することになった
|
||||
// NotificationChannel を端末に登録しておけば、チャネルごとに管理画面が作られる
|
||||
val channel = createMessageNotificationChannel(
|
||||
context,
|
||||
account,
|
||||
trackingName
|
||||
)
|
||||
NotificationCompat.Builder(context, channel.id)
|
||||
} else {
|
||||
NotificationCompat.Builder(context, "not_used")
|
||||
}
|
||||
// Android 8 から、通知のスタイルはユーザが管理することになった
|
||||
// NotificationChannel を端末に登録しておけば、チャネルごとに管理画面が作られる
|
||||
val channel = createMessageNotificationChannel(
|
||||
context,
|
||||
account,
|
||||
trackingName
|
||||
)
|
||||
val builder = NotificationCompat.Builder(context, channel.id)
|
||||
|
||||
builder.apply {
|
||||
|
||||
|
@ -98,8 +92,7 @@ object MessageNotification {
|
|||
}
|
||||
}.joinToString("&")
|
||||
|
||||
val flag = PendingIntent.FLAG_UPDATE_CURRENT or
|
||||
(if (Build.VERSION.SDK_INT >= 23) PendingIntent.FLAG_IMMUTABLE else 0)
|
||||
val flag = PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
|
||||
PendingIntent.getActivity(
|
||||
context,
|
||||
|
@ -147,54 +140,7 @@ object MessageNotification {
|
|||
)
|
||||
}
|
||||
|
||||
// Android 8 未満ではチャネルではなく通知に個別にスタイルを設定する
|
||||
@TargetApi(25)
|
||||
fun setNotificationSound25(
|
||||
account: SavedAccount,
|
||||
builder: NotificationCompat.Builder,
|
||||
item: NotificationData,
|
||||
) {
|
||||
var iv = 0
|
||||
if (PrefB.bpNotificationSound()) {
|
||||
var soundUri: Uri? = null
|
||||
|
||||
try {
|
||||
val whoAcct = account.getFullAcct(item.notification.account)
|
||||
soundUri = AcctColor.getNotificationSound(whoAcct).mayUri()
|
||||
} catch (ex: Throwable) {
|
||||
PollingChecker.log.trace(ex)
|
||||
}
|
||||
if (soundUri == null) {
|
||||
soundUri = account.sound_uri.mayUri()
|
||||
}
|
||||
|
||||
var bSoundSet = false
|
||||
if (soundUri != null) {
|
||||
try {
|
||||
builder.setSound(soundUri)
|
||||
bSoundSet = true
|
||||
} catch (ex: Throwable) {
|
||||
PollingChecker.log.trace(ex)
|
||||
}
|
||||
}
|
||||
if (!bSoundSet) {
|
||||
iv = iv or NotificationCompat.DEFAULT_SOUND
|
||||
}
|
||||
}
|
||||
|
||||
if (PrefB.bpNotificationVibration()) {
|
||||
iv = iv or NotificationCompat.DEFAULT_VIBRATE
|
||||
}
|
||||
|
||||
if (PrefB.bpNotificationLED()) {
|
||||
iv = iv or NotificationCompat.DEFAULT_LIGHTS
|
||||
}
|
||||
|
||||
builder.setDefaults(iv)
|
||||
}
|
||||
|
||||
@TargetApi(26)
|
||||
fun createMessageNotificationChannel(
|
||||
private fun createMessageNotificationChannel(
|
||||
context: Context,
|
||||
account: SavedAccount,
|
||||
trackingName: String,
|
||||
|
@ -221,12 +167,10 @@ object MessageNotification {
|
|||
account: SavedAccount,
|
||||
trackingName: String,
|
||||
) {
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
val channel = createMessageNotificationChannel(context, account, trackingName)
|
||||
val intent = Intent("android.settings.CHANNEL_NOTIFICATION_SETTINGS")
|
||||
intent.putExtra(Settings.EXTRA_CHANNEL_ID, channel.id)
|
||||
intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
val channel = createMessageNotificationChannel(context, account, trackingName)
|
||||
val intent = Intent("android.settings.CHANNEL_NOTIFICATION_SETTINGS")
|
||||
intent.putExtra(Settings.EXTRA_CHANNEL_ID, channel.id)
|
||||
intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package jp.juggler.subwaytooter.notification
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import androidx.core.app.NotificationCompat
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.TootApiCallback
|
||||
|
@ -13,7 +11,6 @@ import jp.juggler.subwaytooter.global.appDispatchers
|
|||
import jp.juggler.subwaytooter.notification.CheckerWakeLocks.Companion.checkerWakeLocks
|
||||
import jp.juggler.subwaytooter.notification.MessageNotification.getMessageNotifications
|
||||
import jp.juggler.subwaytooter.notification.MessageNotification.removeMessageNotification
|
||||
import jp.juggler.subwaytooter.notification.MessageNotification.setNotificationSound25
|
||||
import jp.juggler.subwaytooter.notification.MessageNotification.showMessageNotification
|
||||
import jp.juggler.subwaytooter.pref.PrefB
|
||||
import jp.juggler.subwaytooter.table.*
|
||||
|
@ -467,7 +464,7 @@ class PollingChecker(
|
|||
first.notification.time_created_at == nt.post_time && first.notification.id == nt.post_id ->
|
||||
log.d("showNotification[${account.acct.pretty}] id=${first.notification.id} is already shown.")
|
||||
|
||||
Build.VERSION.SDK_INT >= 23 && PrefB.bpDivideNotification() -> {
|
||||
PrefB.bpDivideNotification() -> {
|
||||
updateNotificationDivided(notificationTag, nt)
|
||||
nt.updatePost(
|
||||
first.notification.id,
|
||||
|
@ -487,7 +484,6 @@ class PollingChecker(
|
|||
}
|
||||
}
|
||||
|
||||
@TargetApi(23)
|
||||
private fun updateNotificationDivided(
|
||||
notificationTag: String,
|
||||
nt: NotificationTracking,
|
||||
|
@ -538,7 +534,6 @@ class PollingChecker(
|
|||
builder.setStyle(style)
|
||||
}
|
||||
}
|
||||
if (Build.VERSION.SDK_INT < 26) setNotificationSound25(account, builder, item)
|
||||
}
|
||||
}
|
||||
// リストにない通知は消さない。ある通知をユーザが指で削除した際に他の通知が残ってほしい場合がある
|
||||
|
@ -576,7 +571,6 @@ class PollingChecker(
|
|||
|
||||
builder.setStyle(style)
|
||||
}
|
||||
if (Build.VERSION.SDK_INT < 26) setNotificationSound25(account, builder, first)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.app.NotificationManager
|
|||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import jp.juggler.subwaytooter.ActCallback
|
||||
|
@ -32,23 +31,19 @@ object ServerTimeoutNotification {
|
|||
context,
|
||||
3,
|
||||
clickIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or (if (Build.VERSION.SDK_INT >= 23) PendingIntent.FLAG_IMMUTABLE else 0)
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
|
||||
)
|
||||
|
||||
val builder = if (Build.VERSION.SDK_INT >= 26) {
|
||||
// Android 8 から、通知のスタイルはユーザが管理することになった
|
||||
// NotificationChannel を端末に登録しておけば、チャネルごとに管理画面が作られる
|
||||
val channel = NotificationHelper.createNotificationChannel(
|
||||
context,
|
||||
"ErrorNotification",
|
||||
"Error",
|
||||
null,
|
||||
2 /* NotificationManager.IMPORTANCE_LOW */
|
||||
)
|
||||
NotificationCompat.Builder(context, channel.id)
|
||||
} else {
|
||||
NotificationCompat.Builder(context, "not_used")
|
||||
}
|
||||
// Android 8 から、通知のスタイルはユーザが管理することになった
|
||||
// NotificationChannel を端末に登録しておけば、チャネルごとに管理画面が作られる
|
||||
val channel = NotificationHelper.createNotificationChannel(
|
||||
context,
|
||||
"ErrorNotification",
|
||||
"Error",
|
||||
null,
|
||||
2 /* NotificationManager.IMPORTANCE_LOW */
|
||||
)
|
||||
val builder = NotificationCompat.Builder(context, channel.id)
|
||||
|
||||
val header = context.getString(R.string.error_notification_title)
|
||||
val summary = context.getString(R.string.error_notification_summary)
|
||||
|
|
|
@ -72,20 +72,20 @@ object PrefB {
|
|||
false
|
||||
)
|
||||
|
||||
val bpNotificationLED = BooleanPref(
|
||||
"notification_led",
|
||||
true
|
||||
)
|
||||
// val bpNotificationLED = BooleanPref(
|
||||
// "notification_led",
|
||||
// true
|
||||
// )
|
||||
|
||||
val bpNotificationSound = BooleanPref(
|
||||
"notification_sound",
|
||||
true
|
||||
)
|
||||
// val bpNotificationSound = BooleanPref(
|
||||
// "notification_sound",
|
||||
// true
|
||||
// )
|
||||
|
||||
val bpNotificationVibration = BooleanPref(
|
||||
"notification_vibration",
|
||||
true
|
||||
)
|
||||
// val bpNotificationVibration = BooleanPref(
|
||||
// "notification_vibration",
|
||||
// true
|
||||
// )
|
||||
|
||||
val bpPostButtonBarTop = BooleanPref(
|
||||
"post_button_bar_at_top",
|
||||
|
|
|
@ -11,8 +11,7 @@ import jp.juggler.util.LogCategory
|
|||
class NetworkStateTracker(
|
||||
val context: Context,
|
||||
val onConnectionStateChanged: () -> Unit,
|
||||
|
||||
) : ConnectivityManager.NetworkCallback() {
|
||||
) : ConnectivityManager.NetworkCallback() {
|
||||
|
||||
companion object {
|
||||
private val log = LogCategory("NetworkStateTracker")
|
||||
|
@ -27,7 +26,7 @@ class NetworkStateTracker(
|
|||
}
|
||||
|
||||
private val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE)
|
||||
as ConnectivityManager
|
||||
as ConnectivityManager
|
||||
|
||||
init {
|
||||
if (Build.VERSION.SDK_INT >= 28) {
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.app.AlertDialog
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import androidx.activity.result.ActivityResultCallback
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
|
@ -88,14 +87,10 @@ class PermissionRequester(
|
|||
|
||||
launchMain {
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT < 23) {
|
||||
activity.showToast(true, deniedId)
|
||||
return@launchMain
|
||||
}
|
||||
|
||||
val shouldShowRational = listNotGranted.any {
|
||||
shouldShowRequestPermissionRationale(activity, it)
|
||||
}
|
||||
|
||||
if (shouldShowRational && rationalId != 0) {
|
||||
suspendCancellableCoroutine { cont ->
|
||||
AlertDialog.Builder(activity)
|
||||
|
@ -112,7 +107,10 @@ class PermissionRequester(
|
|||
.show()
|
||||
}
|
||||
}
|
||||
launcher!!.launch(listNotGranted.toTypedArray())
|
||||
when (val launcher = launcher) {
|
||||
null -> error("launcher not registered.")
|
||||
else -> launcher.launch(listNotGranted.toTypedArray())
|
||||
}
|
||||
} catch (ex: Throwable) {
|
||||
if (ex !is CancellationException) {
|
||||
activity.showToast(ex, "can't request permissions.")
|
||||
|
@ -154,7 +152,9 @@ class PermissionRequester(
|
|||
Intent(
|
||||
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
|
||||
"package:${activity.packageName}".toUri()
|
||||
).let { activity.startActivity(it) }
|
||||
).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}.let { activity.startActivity(it) }
|
||||
} catch (ex: Throwable) {
|
||||
activity.showToast(ex, "openAppSetting failed.")
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.content.ContentResolver
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.provider.OpenableColumns
|
||||
import android.webkit.MimeTypeMap
|
||||
import androidx.annotation.RawRes
|
||||
|
@ -264,14 +263,12 @@ fun intentGetContent(
|
|||
// EXTRA_MIME_TYPES は API 19以降。ACTION_GET_CONTENT でも ACTION_OPEN_DOCUMENT でも指定できる
|
||||
intent.putExtra("android.intent.extra.MIME_TYPES", mimeTypes)
|
||||
|
||||
intent.type = when {
|
||||
mimeTypes.size == 1 -> mimeTypes[0]
|
||||
intent.type = when (mimeTypes.size) {
|
||||
1 -> mimeTypes[0]
|
||||
|
||||
// On Android 6.0 and above using "video/* image/" or "image/ video/*" type doesn't work
|
||||
// it only recognizes the first filter you specify.
|
||||
Build.VERSION.SDK_INT >= 23 -> "*/*"
|
||||
|
||||
else -> mimeTypes.joinToString(" ")
|
||||
else -> "*/*"
|
||||
}
|
||||
|
||||
return Intent.createChooser(intent, caption)
|
||||
|
|
|
@ -2,7 +2,6 @@ package jp.juggler.util
|
|||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.text.SpannableStringBuilder
|
||||
|
@ -312,12 +311,7 @@ fun <T> Array<T>.toHashSet() = HashSet<T>().also { it.addAll(this) }
|
|||
//fun <T> Sequence<T>.toHashSet() = HashSet<T>().also { it.addAll(this) }
|
||||
|
||||
fun defaultLocale(context: Context): Locale =
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
context.resources.configuration.locales[0]
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
context.resources.configuration.locale
|
||||
}
|
||||
context.resources.configuration.locales[0]
|
||||
|
||||
fun Matcher.findOrNull() = if (find()) this else null
|
||||
|
||||
|
|
|
@ -201,10 +201,6 @@ private fun rgbToLab(rgb: Int): Triple<Float, Float, Float> {
|
|||
|
||||
fun AppCompatActivity.setStatusBarColor(forceDark: Boolean = false) {
|
||||
window?.apply {
|
||||
// 古い端末ではナビゲーションバーのアイコン色を設定できないため
|
||||
// メディアビューア画面ではステータスバーやナビゲーションバーの色を設定しない…
|
||||
if (forceDark && Build.VERSION.SDK_INT < 26) return
|
||||
|
||||
if (Build.VERSION.SDK_INT < 30) {
|
||||
@Suppress("DEPRECATION")
|
||||
clearFlags(
|
||||
|
@ -238,17 +234,20 @@ private fun AppCompatActivity.setStatusBarColorCompat(@ColorInt c: Int) {
|
|||
val bit = WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
|
||||
setSystemBarsAppearance(if (rgbToLab(c).first >= 50f) bit else 0, bit)
|
||||
}
|
||||
} else if (Build.VERSION.SDK_INT >= 23) {
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
val bit = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||
@Suppress("DEPRECATION")
|
||||
decorView.systemUiVisibility =
|
||||
if (rgbToLab(c).first >= 50f) {
|
||||
//Dark Text to show up on your light status bar
|
||||
decorView.systemUiVisibility or bit
|
||||
} else {
|
||||
//Light Text to show up on your dark status bar
|
||||
decorView.systemUiVisibility and bit.inv()
|
||||
when {
|
||||
rgbToLab(c).first >= 50f -> {
|
||||
//Dark Text to show up on your light status bar
|
||||
decorView.systemUiVisibility or bit
|
||||
}
|
||||
else -> {
|
||||
//Light Text to show up on your dark status bar
|
||||
decorView.systemUiVisibility and bit.inv()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -268,19 +267,17 @@ private fun AppCompatActivity.setNavigationBarColorCompat(@ColorInt c: Int) {
|
|||
val bit = WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
|
||||
setSystemBarsAppearance(if (rgbToLab(c).first >= 50f) bit else 0, bit)
|
||||
}
|
||||
} else if (Build.VERSION.SDK_INT >= 26) {
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
val bit = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
|
||||
@Suppress("DEPRECATION")
|
||||
decorView.systemUiVisibility = when {
|
||||
rgbToLab(c).first >= 50f -> {
|
||||
//Dark Text to show up on your light status bar
|
||||
//Dark Text to show up on your light status bar
|
||||
rgbToLab(c).first >= 50f ->
|
||||
decorView.systemUiVisibility or bit
|
||||
}
|
||||
else -> {
|
||||
//Light Text to show up on your dark status bar
|
||||
//Light Text to show up on your dark status bar
|
||||
else ->
|
||||
decorView.systemUiVisibility and bit.inv()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,11 +9,9 @@
|
|||
|
||||
package me.drakeet.support.toast
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.content.res.Resources
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import android.view.Display
|
||||
import android.view.View
|
||||
|
@ -95,19 +93,6 @@ class ToastCompat private constructor(
|
|||
companion object {
|
||||
private val log = LogCategory("ToastCompat")
|
||||
|
||||
@SuppressLint("DiscouragedPrivateApi")
|
||||
private fun setContextCompat(view: View?, contextCreator: () -> Context) {
|
||||
if (view != null && Build.VERSION.SDK_INT == 25) {
|
||||
try {
|
||||
val field = View::class.java.getDeclaredField("mContext")
|
||||
field.isAccessible = true
|
||||
field[view] = contextCreator()
|
||||
} catch (ex: Throwable) {
|
||||
log.trace(ex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a standard toast that just contains a text view with the text from a resource.
|
||||
*
|
||||
|
@ -136,7 +121,6 @@ class ToastCompat private constructor(
|
|||
// We cannot pass the SafeToastContext to Toast.makeText() because
|
||||
// the View will unwrap the base context and we are in vain.
|
||||
val base = Toast.makeText(context, text, duration)
|
||||
setContextCompat(base.view) { SafeToastContext(context, base) }
|
||||
return ToastCompat(context, base)
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +136,6 @@ class ToastCompat private constructor(
|
|||
@Deprecated(message = "Custom toast views are deprecated in API level 30.")
|
||||
override fun setView(view: View) {
|
||||
base.view = view
|
||||
setContextCompat(base.view) { SafeToastContext(view.context, base) }
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
|
|
|
@ -617,28 +617,6 @@
|
|||
|
||||
<View style="@style/setting_divider" />
|
||||
|
||||
<TextView
|
||||
style="@style/setting_row_label"
|
||||
android:text="@string/notification_sound_before_oreo" />
|
||||
|
||||
<LinearLayout style="@style/setting_row_form">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnNotificationSoundEdit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/edit"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnNotificationSoundReset"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/reset"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View style="@style/setting_divider" />
|
||||
|
||||
<TextView
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingStart="12dp"
|
||||
android:text="@string/preview" />
|
||||
|
||||
<TextView
|
||||
|
@ -22,10 +22,10 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="6dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingTop="6dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingBottom="6dp"
|
||||
android:textSize="20sp"
|
||||
tools:text="preview..." />
|
||||
|
||||
|
@ -132,7 +132,7 @@
|
|||
|
||||
<TextView
|
||||
style="@style/setting_row_label"
|
||||
android:text="@string/notification_sound_before_oreo" />
|
||||
android:text="@string/notification_sound" />
|
||||
|
||||
<LinearLayout style="@style/setting_row_form">
|
||||
|
||||
|
@ -171,7 +171,6 @@
|
|||
android:measureWithLargestChild="true">
|
||||
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnDiscard"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
|
@ -190,4 +189,4 @@
|
|||
android:text="@string/save"
|
||||
android:textAllCaps="false" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -486,10 +486,8 @@
|
|||
<string name="relative_time_phrase_past">Hi ha %1$d %2$s</string>
|
||||
<string name="relative_time_phrase_future">Després de %1$d %2$s</string>
|
||||
<string name="notification_channel_description">Aquest paràmetre serveix per ajustar les notificacions de %1$s</string>
|
||||
<string name="notification_sound_before_oreo">So de notificació (pre Android 8.0)</string>
|
||||
<string name="notification_style_after_oreo">Estil de notificacions (Android 8.0+)</string>
|
||||
<string name="notification_for">Notificacions per %1$s</string>
|
||||
<string name="notification_style_before_oreo">Estil de notificacions (pre Android 8. Si el teu dispositiu és Android 8.0+, cal que activis el paràmetre a la configuració)</string>
|
||||
<string name="enquete_was_end">Enquesta finalitzada.</string>
|
||||
<string name="enquete_voted">S\'ha votat.</string>
|
||||
<string name="enquete_vote_failed">No s\'ha pogut votar. %1$s</string>
|
||||
|
|
|
@ -1005,9 +1005,7 @@
|
|||
<string name="enquete_vote_failed">不能投票. %1$s</string>
|
||||
<string name="enquete_voted">已投票.</string>
|
||||
<string name="enquete_was_end">投票结束.</string>
|
||||
<string name="notification_style_before_oreo">通知方式( Android 8之前. 如果你的设备是 Android 8.0+, 请检查账号设置)</string>
|
||||
<string name="notification_for">%1$s的通知</string>
|
||||
<string name="notification_sound_before_oreo">通知声音( Android 8.0之前)</string>
|
||||
<string name="notification_style_after_oreo">通知方式(Android 8.0+)</string>
|
||||
<string name="notification_channel_description">此设置用于调整%1$s</string>
|
||||
<string name="relative_time_phrase_future">%1$d %2$s 之后</string>
|
||||
|
|
|
@ -934,10 +934,8 @@
|
|||
<string name="enquete_was_end">Abstimmung beendet.</string>
|
||||
<string name="enquete_vote_failed">Konnte nicht abstimmen. %1$s</string>
|
||||
<string name="enquete_voted">Abgestimmt.</string>
|
||||
<string name="notification_style_before_oreo">Benachrichtigungsstil (vor Android 8. Falls auf deinem Gerät Android 8.0 oder später läuft, sieh bitte in den Konteneinstellungen nach)</string>
|
||||
<string name="notification_for">Benachrichtigung für %1$s</string>
|
||||
<string name="notification_style_after_oreo">Benachrichtigungsstil (Android 8.0 und später)</string>
|
||||
<string name="notification_sound_before_oreo">Benachrichtigungston (vor Android 8.0)</string>
|
||||
<string name="notification_channel_description">Diese Einstellung legt die Benachrichtigung für %1$s fest</string>
|
||||
<string name="relative_time_phrase_future">%1$d %2$s später</string>
|
||||
<string name="relative_time_phrase_past">%1$d %2$s</string>
|
||||
|
|
|
@ -451,11 +451,9 @@
|
|||
<string name="relative_time_unit_days">jours</string>
|
||||
<string name="relative_time_phrase_past">Il y a %1$d %2$s</string>
|
||||
<string name="relative_time_phrase_future">Dans %1$d %2$s</string>
|
||||
<string name="notification_sound_before_oreo">Notification sonore (avant Android 8.0)</string>
|
||||
<string name="notification_style_after_oreo">Style de notifications (Android 8.0+)</string>
|
||||
<string name="notification_for">Notification for %1$s</string>
|
||||
<string name="notification_channel_description">Ce paramètre est utilisé pour ajuster les notifications pour %1$s</string>
|
||||
<string name="notification_style_before_oreo">Style de notification (avant Android 8. Si votre appareil est sous Android 8.0+, veuillez vérifier les paramètres du compte)</string>
|
||||
<string name="enquete_was_end">Sondage terminé.</string>
|
||||
<string name="enquete_voted">a voté.</string>
|
||||
<string name="enquete_vote_failed">Le vote a échoué. %1$s</string>
|
||||
|
|
|
@ -272,10 +272,8 @@
|
|||
<string name="relative_time_unit_days">ימים</string>
|
||||
<string name="relative_time_phrase_future">%1$d %2$s אחר כך</string>
|
||||
<string name="notification_channel_description">הגדרה זו משמשת להתאמת התראות עבור %1$s</string>
|
||||
<string name="notification_sound_before_oreo">צליל התראה (לפני אנדרואיד 8.0)</string>
|
||||
<string name="notification_style_after_oreo">סגנון התראה (אנדרויד 8.0+)</string>
|
||||
<string name="notification_for">התראה עבור %1$s</string>
|
||||
<string name="notification_style_before_oreo">סגנון התראה (לפני אנדרויד 8. אם המכשיר שלך הוא אנדרויד 8.0+ , נא לבדוק את הגדרות החשבון)</string>
|
||||
<string name="enquete_was_end">הסקירה הסתיימה.</string>
|
||||
<string name="enquete_voted">הצביע.</string>
|
||||
<string name="enquete_vote_failed">לא ניתן להצביע. %1$s</string>
|
||||
|
|
|
@ -493,9 +493,7 @@
|
|||
<string name="notification_on_off_desc">通知のON/OFFはアカウント設定にあります</string>
|
||||
<string name="notification_option">通知オプション</string>
|
||||
<string name="notification_sound">通知音</string>
|
||||
<string name="notification_sound_before_oreo">通知音 (Android 7.x 以下)</string>
|
||||
<string name="notification_style_after_oreo">通知スタイル(Android 8.x 以降)</string>
|
||||
<string name="notification_style_before_oreo">通知スタイル(Android 7.x以下。もしお使いのデバイスが8.x以降の場合、アカウント設定から通知スタイルを変更できます)</string>
|
||||
<string name="notification_tl_font_size">通知TLのフォントの大きさ\n(単位:sp。空欄でデフォルト。アプリ再起動が必要)\n…\n…</string>
|
||||
<string name="notification_tl_icon_size">通知TLのアイコンの大きさ (単位:dp。デフォルト:24。アプリ再起動が必要)</string>
|
||||
<string name="notification_type_boost">ブースト</string>
|
||||
|
|
|
@ -463,10 +463,8 @@
|
|||
<string name="relative_time_phrase_past">%1$d %2$s</string>
|
||||
<string name="relative_time_phrase_future">%1$d %2$s 후</string>
|
||||
<string name="notification_channel_description">이 설정은 %1$s에 대한 알림을 조절하는 데 사용됩니다</string>
|
||||
<string name="notification_sound_before_oreo">알림 소리 (안드로이드 8.0 이전)</string>
|
||||
<string name="notification_style_after_oreo">알림 스타일 (안드로이드 8.0 이상)</string>
|
||||
<string name="notification_for">%1$s에 대한 알림</string>
|
||||
<string name="notification_style_before_oreo">알림 스타일 (안드로이드 8 이전. 만약 안드로이드 8.0 이상이면 계정 설정을 확인하세요)</string>
|
||||
<string name="enquete_was_end">설문조사 끝남.</string>
|
||||
<string name="enquete_voted">투표함.</string>
|
||||
<string name="enquete_vote_failed">투표할 수 없음. %1$s</string>
|
||||
|
|
|
@ -372,7 +372,6 @@
|
|||
<string name="relative_time_phrase_past">%1$d %2$s siden</string>
|
||||
<string name="relative_time_phrase_future">%1$d %2$s senere</string>
|
||||
<string name="notification_channel_description">Disse innstillingen brukes for merknad for %1$s</string>
|
||||
<string name="notification_sound_before_oreo">Merknadslyd (før Android 8.0)</string>
|
||||
<string name="notification_style_after_oreo">Merknadsstil (Android 8.0 eller senere)</string>
|
||||
<string name="notification_for">Merknad for %1$s</string>
|
||||
<string name="enquete_voted">Innsendt.</string>
|
||||
|
@ -642,7 +641,6 @@
|
|||
<string name="format_of_quote_name">Format for \"sitatnavn\" (sett tekst som inneholder %1$s)</string>
|
||||
<string name="content_sample">(eksempel) Høvdingens kjære squaw får litt pizza i Mexico by.</string>
|
||||
<string name="remote_profile_warning">Informasjon på andre profilsider kan ikke vises rett. Trykk her for å vise profilen i din nettleser.</string>
|
||||
<string name="notification_style_before_oreo">Merknadsstil (før Android 8. Hvis din enhet har Android 8.0 eller senere, sjekk kontoinnstilling).</string>
|
||||
<string name="auto_cw">Skjul lang tekst automatisk (sett linjeopptelling større enn 0 for å skru på dette valget. Programomstart kreves)</string>
|
||||
<string name="auto_cw_prefix">(Automatisk CW)</string>
|
||||
<string name="profile_pin">Fest på profil</string>
|
||||
|
|
|
@ -483,10 +483,8 @@
|
|||
<string name="relative_time_phrase_past">%1$d %2$s</string>
|
||||
<string name="relative_time_phrase_future">%1$d %2$s later</string>
|
||||
<string name="notification_channel_description">This setting is used to adjust notification for %1$s</string>
|
||||
<string name="notification_sound_before_oreo">Notification sound (pre Android 8.0)</string>
|
||||
<string name="notification_style_after_oreo">Notification style (Android 8.0+)</string>
|
||||
<string name="notification_for">Notification for %1$s</string>
|
||||
<string name="notification_style_before_oreo">Notification style (pre Android 8. if your device is Android 8.0+, please check the account setting)</string>
|
||||
<string name="enquete_was_end">Enquete ended.</string>
|
||||
<string name="enquete_voted">Voted.</string>
|
||||
<string name="enquete_vote_failed">Could not vote. %1$s</string>
|
||||
|
|
|
@ -2,7 +2,7 @@ buildscript {
|
|||
|
||||
ext.jvm_target = "1.8"
|
||||
|
||||
ext.min_sdk_version = 21
|
||||
ext.min_sdk_version = 26
|
||||
ext.target_sdk_version = 31
|
||||
ext.compile_sdk_version = 31
|
||||
|
||||
|
@ -29,7 +29,7 @@ buildscript {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.2.1'
|
||||
classpath 'com.android.tools.build:gradle:7.2.2'
|
||||
|
||||
// room のバージョンの影響で google-services を上げられない場合がある
|
||||
//noinspection GradleDependency
|
||||
|
|
Loading…
Reference in New Issue