mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Add exact alarm message
This commit is contained in:
@@ -19,7 +19,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.kunzisoft.keepass.settings.preferencedialogfragment
|
package com.kunzisoft.keepass.settings.preferencedialogfragment
|
||||||
|
|
||||||
|
import android.app.AlarmManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.provider.Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM
|
||||||
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.NumberPicker
|
import android.widget.NumberPicker
|
||||||
import com.kunzisoft.keepass.R
|
import com.kunzisoft.keepass.R
|
||||||
@@ -62,6 +68,30 @@ class DurationDialogFragmentCompat : InputPreferenceDialogFragmentCompat() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
|
||||||
|
(context?.applicationContext?.getSystemService(Context.ALARM_SERVICE) as AlarmManager?)?.let { alarmManager ->
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||||
|
&& !alarmManager.canScheduleExactAlarms()) {
|
||||||
|
setExplanationText(R.string.warning_exact_alarm)
|
||||||
|
setExplanationButton(R.string.permission) {
|
||||||
|
// Open the exact alarm permission screen
|
||||||
|
try {
|
||||||
|
startActivity(Intent().apply {
|
||||||
|
action = ACTION_REQUEST_SCHEDULE_EXACT_ALARM
|
||||||
|
})
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Unable to open exact alarm permission screen", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
explanationText = ""
|
||||||
|
setExplanationButton("") {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun durationToDaysHoursMinutesSeconds(duration: Long) {
|
private fun durationToDaysHoursMinutesSeconds(duration: Long) {
|
||||||
if (duration < 0) {
|
if (duration < 0) {
|
||||||
mEnabled = false
|
mEnabled = false
|
||||||
@@ -164,6 +194,7 @@ class DurationDialogFragmentCompat : InputPreferenceDialogFragmentCompat() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private const val TAG = "DurationDialogFrgCmpt"
|
||||||
private const val ENABLE_KEY = "ENABLE_KEY"
|
private const val ENABLE_KEY = "ENABLE_KEY"
|
||||||
private const val DAYS_KEY = "DAYS_KEY"
|
private const val DAYS_KEY = "DAYS_KEY"
|
||||||
private const val HOURS_KEY = "HOURS_KEY"
|
private const val HOURS_KEY = "HOURS_KEY"
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ package com.kunzisoft.keepass.settings.preferencedialogfragment
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
|
import android.widget.Button
|
||||||
import android.widget.CompoundButton
|
import android.widget.CompoundButton
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
@@ -35,6 +36,7 @@ abstract class InputPreferenceDialogFragmentCompat : PreferenceDialogFragmentCom
|
|||||||
private var inputTextView: EditText? = null
|
private var inputTextView: EditText? = null
|
||||||
private var textUnitView: TextView? = null
|
private var textUnitView: TextView? = null
|
||||||
private var textExplanationView: TextView? = null
|
private var textExplanationView: TextView? = null
|
||||||
|
private var explanationButton: Button? = null
|
||||||
private var switchElementView: CompoundButton? = null
|
private var switchElementView: CompoundButton? = null
|
||||||
|
|
||||||
private var mOnInputTextEditorActionListener: TextView.OnEditorActionListener? = null
|
private var mOnInputTextEditorActionListener: TextView.OnEditorActionListener? = null
|
||||||
@@ -100,6 +102,27 @@ abstract class InputPreferenceDialogFragmentCompat : PreferenceDialogFragmentCom
|
|||||||
explanationText = getString(explanationTextId)
|
explanationText = getString(explanationTextId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val explanationButtonText: String?
|
||||||
|
get() = explanationButton?.text?.toString() ?: ""
|
||||||
|
|
||||||
|
fun setExplanationButton(explanationButtonText: String?, clickListener: View.OnClickListener) {
|
||||||
|
explanationButton?.apply {
|
||||||
|
if (explanationButtonText != null && explanationButtonText.isNotEmpty()) {
|
||||||
|
text = explanationButtonText
|
||||||
|
visibility = View.VISIBLE
|
||||||
|
setOnClickListener(clickListener)
|
||||||
|
} else {
|
||||||
|
text = ""
|
||||||
|
visibility = View.GONE
|
||||||
|
setOnClickListener(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setExplanationButton(@StringRes explanationButtonTextId: Int, clickListener: View.OnClickListener) {
|
||||||
|
setExplanationButton(getString(explanationButtonTextId), clickListener)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onBindDialogView(view: View) {
|
override fun onBindDialogView(view: View) {
|
||||||
super.onBindDialogView(view)
|
super.onBindDialogView(view)
|
||||||
|
|
||||||
@@ -128,6 +151,8 @@ abstract class InputPreferenceDialogFragmentCompat : PreferenceDialogFragmentCom
|
|||||||
textUnitView?.visibility = View.GONE
|
textUnitView?.visibility = View.GONE
|
||||||
textExplanationView = view.findViewById(R.id.explanation_text)
|
textExplanationView = view.findViewById(R.id.explanation_text)
|
||||||
textExplanationView?.visibility = View.GONE
|
textExplanationView?.visibility = View.GONE
|
||||||
|
explanationButton = view.findViewById(R.id.explanation_button)
|
||||||
|
explanationButton?.visibility = View.GONE
|
||||||
switchElementView = view.findViewById(R.id.switch_element)
|
switchElementView = view.findViewById(R.id.switch_element)
|
||||||
switchElementView?.visibility = View.GONE
|
switchElementView?.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ object TimeoutHelper {
|
|||||||
triggerTime,
|
triggerTime,
|
||||||
getLockPendingIntent(context)
|
getLockPendingIntent(context)
|
||||||
)
|
)
|
||||||
// TODO explain why exact alarm is needed for timeout
|
|
||||||
} else {
|
} else {
|
||||||
alarmManager.setExact(
|
alarmManager.setExact(
|
||||||
AlarmManager.RTC,
|
AlarmManager.RTC,
|
||||||
|
|||||||
@@ -35,6 +35,6 @@
|
|||||||
android:layout_margin="@dimen/button_margin"
|
android:layout_margin="@dimen/button_margin"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_horizontal"
|
android:text="@string/file_browser"
|
||||||
android:text="@string/file_browser" />
|
style="@style/Widget.AppCompat.Button.Small"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -17,133 +17,155 @@
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
|
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/edit"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:importantForAutofill="noExcludeDescendants"
|
|
||||||
tools:targetApi="o">
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
|
||||||
android:id="@+id/explanation_text"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
style="@style/KeepassDXStyle.TextAppearance.SmallTitle"/>
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
|
||||||
android:id="@+id/switch_element"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/enable"
|
|
||||||
android:layout_marginStart="20dp"
|
|
||||||
android:layout_marginLeft="20dp"
|
|
||||||
android:layout_marginEnd="20dp"
|
|
||||||
android:layout_marginRight="20dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/explanation_text" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/edit"
|
||||||
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/switch_element">
|
android:importantForAutofill="noExcludeDescendants"
|
||||||
|
tools:targetApi="o">
|
||||||
<LinearLayout
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
android:id="@+id/duration_days_picker"
|
android:id="@+id/explanation_text"
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:layout_width="0dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginLeft="20dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:layout_marginRight="20dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/duration_hours_picker"
|
|
||||||
app:layout_constraintRight_toLeftOf="@+id/duration_hours_picker">
|
|
||||||
<NumberPicker
|
|
||||||
android:id="@+id/days_picker"
|
|
||||||
android:scrollbarFadeDuration="0"
|
|
||||||
android:scrollbarDefaultDelayBeforeFade="0"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:src="@drawable/ic_day_white_24dp"
|
|
||||||
app:tint="?android:attr/textColor"
|
|
||||||
android:contentDescription="@string/digits" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/duration_hours_picker"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
tools:ignore="HardcodedText"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/duration_days_picker"
|
|
||||||
app:layout_constraintLeft_toRightOf="@+id/duration_days_picker"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/duration_time_picker"
|
|
||||||
app:layout_constraintRight_toLeftOf="@+id/duration_time_picker">
|
|
||||||
<NumberPicker
|
|
||||||
android:id="@+id/hours_picker"
|
|
||||||
android:scrollbarFadeDuration="0"
|
|
||||||
android:scrollbarDefaultDelayBeforeFade="0"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:text=":" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/duration_time_picker"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
tools:ignore="HardcodedText"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/duration_hours_picker"
|
|
||||||
app:layout_constraintLeft_toRightOf="@+id/duration_hours_picker"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent">
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
<NumberPicker
|
style="@style/KeepassDXStyle.TextAppearance.SmallTitle"/>
|
||||||
android:id="@+id/minutes_picker"
|
|
||||||
android:scrollbarFadeDuration="0"
|
|
||||||
android:scrollbarDefaultDelayBeforeFade="0"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:textSize="28sp"
|
|
||||||
android:text="'"/>
|
|
||||||
<NumberPicker
|
|
||||||
android:id="@+id/seconds_picker"
|
|
||||||
android:scrollbarFadeDuration="0"
|
|
||||||
android:scrollbarDefaultDelayBeforeFade="0"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:textSize="28sp"
|
|
||||||
android:text="''"/>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/explanation_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginLeft="20dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:layout_marginRight="20dp"
|
||||||
|
tools:text="permission"
|
||||||
|
style="@style/Widget.AppCompat.Button.Small"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/explanation_text" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.SwitchCompat
|
||||||
|
android:id="@+id/switch_element"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/enable"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginLeft="20dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:layout_marginRight="20dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/explanation_button" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/switch_element">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/duration_days_picker"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/duration_hours_picker"
|
||||||
|
app:layout_constraintRight_toLeftOf="@+id/duration_hours_picker">
|
||||||
|
<NumberPicker
|
||||||
|
android:id="@+id/days_picker"
|
||||||
|
android:scrollbarFadeDuration="0"
|
||||||
|
android:scrollbarDefaultDelayBeforeFade="0"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:src="@drawable/ic_day_white_24dp"
|
||||||
|
app:tint="?android:attr/textColor"
|
||||||
|
android:contentDescription="@string/digits" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/duration_hours_picker"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
tools:ignore="HardcodedText"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/duration_days_picker"
|
||||||
|
app:layout_constraintLeft_toRightOf="@+id/duration_days_picker"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/duration_time_picker"
|
||||||
|
app:layout_constraintRight_toLeftOf="@+id/duration_time_picker">
|
||||||
|
<NumberPicker
|
||||||
|
android:id="@+id/hours_picker"
|
||||||
|
android:scrollbarFadeDuration="0"
|
||||||
|
android:scrollbarDefaultDelayBeforeFade="0"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:text=":" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/duration_time_picker"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
tools:ignore="HardcodedText"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/duration_hours_picker"
|
||||||
|
app:layout_constraintLeft_toRightOf="@+id/duration_hours_picker"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent">
|
||||||
|
<NumberPicker
|
||||||
|
android:id="@+id/minutes_picker"
|
||||||
|
android:scrollbarFadeDuration="0"
|
||||||
|
android:scrollbarDefaultDelayBeforeFade="0"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textSize="28sp"
|
||||||
|
android:text="'"/>
|
||||||
|
<NumberPicker
|
||||||
|
android:id="@+id/seconds_picker"
|
||||||
|
android:scrollbarFadeDuration="0"
|
||||||
|
android:scrollbarDefaultDelayBeforeFade="0"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textSize="28sp"
|
||||||
|
android:text="''"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</ScrollView>
|
||||||
@@ -325,6 +325,8 @@
|
|||||||
<string name="warning_database_info_changed">The information contained in your database file has been modified outside the app.</string>
|
<string name="warning_database_info_changed">The information contained in your database file has been modified outside the app.</string>
|
||||||
<string name="warning_database_info_changed_options">Overwrite the external modifications by saving the database or reload it with the latest changes.</string>
|
<string name="warning_database_info_changed_options">Overwrite the external modifications by saving the database or reload it with the latest changes.</string>
|
||||||
<string name="warning_database_revoked">Access to the file revoked by the file manager, close the database and reopen it from its location.</string>
|
<string name="warning_database_revoked">Access to the file revoked by the file manager, close the database and reopen it from its location.</string>
|
||||||
|
<string name="warning_exact_alarm">You have not allowed the app to use an exact alarm. As a result, the features requiring a timer will not be done with an exact time.</string>
|
||||||
|
<string name="permission">Permission</string>
|
||||||
<string name="version_label">Version %1$s</string>
|
<string name="version_label">Version %1$s</string>
|
||||||
<string name="build_label">Build %1$s</string>
|
<string name="build_label">Build %1$s</string>
|
||||||
<string name="configure_biometric">No biometric or device credential is enrolled.</string>
|
<string name="configure_biometric">No biometric or device credential is enrolled.</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user