Skip to content

Commit

Permalink
#80 First attempt to fix permissions requests
Browse files Browse the repository at this point in the history
  • Loading branch information
yvolk committed Jan 3, 2024
1 parent 0672401 commit 0092ea6
Show file tree
Hide file tree
Showing 15 changed files with 154 additions and 133 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class AppWidgetProvider : android.appwidget.AppWidgetProvider() {

override fun onReceive(context: Context, intent: Intent) {
Log.d(TAG, "onReceive, intent:$intent")
AllSettings.ensureLoadedFromFiles(context, false)
AllSettings.ensureLoadedFromFiles(context)
val action = intent.action
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE == action) {
val extras = intent.extras
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import org.andstatus.todoagenda.provider.EventProviderType
import org.andstatus.todoagenda.util.CalendarIntentUtil
import org.andstatus.todoagenda.util.DateUtil
import org.andstatus.todoagenda.util.PermissionsUtil
import org.andstatus.todoagenda.util.StringUtil
import org.andstatus.todoagenda.widget.WidgetEntry
import org.joda.time.DateTime
import java.util.concurrent.TimeUnit
Expand All @@ -29,14 +28,15 @@ class EnvironmentChangedReceiver : BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent) {
Log.i(TAG, "Received intent: $intent")
AllSettings.ensureLoadedFromFiles(context, false)
val widgetId = intent?.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0) ?: 0
AllSettings.ensureLoadedFromFiles(context)
val widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0) ?: 0
val settings = if (widgetId == 0) null else AllSettings.loadedInstances[widgetId]
val action0 = if (intent == null) "" else intent.action!!
var action =
if (intent == null || settings == null || StringUtil.isEmpty(action0)) RemoteViewsFactory.ACTION_REFRESH else action0
if (action != RemoteViewsFactory.ACTION_REFRESH && !PermissionsUtil.arePermissionsGranted(context)) {
action = RemoteViewsFactory.ACTION_CONFIGURE
val action = if (settings == null || intent.action.isNullOrBlank()) {
RemoteViewsFactory.ACTION_REFRESH
} else if (PermissionsUtil.mustRequestPermissions(context)) {
RemoteViewsFactory.ACTION_CONFIGURE
} else {
intent.action
}
when (action) {
RemoteViewsFactory.ACTION_OPEN_CALENDAR -> {
Expand All @@ -55,7 +55,10 @@ class EnvironmentChangedReceiver : BroadcastReceiver() {
updateWidget(context, widgetId)
}

RemoteViewsFactory.ACTION_GOTO_TODAY -> gotoToday(context, widgetId)
RemoteViewsFactory.ACTION_GOTO_TODAY -> {
gotoToday(context, widgetId)
}

RemoteViewsFactory.ACTION_ADD_CALENDAR_EVENT -> {
val addCalendarEvent = settings!!.getFirstSource(true)!!.source.providerType
.getEventProvider(context, widgetId)
Expand All @@ -71,8 +74,8 @@ class EnvironmentChangedReceiver : BroadcastReceiver() {
}

RemoteViewsFactory.ACTION_CONFIGURE -> {
val configure: Intent = MainActivity.intentToConfigure(context, widgetId)
startActivity(context, configure, action, widgetId, "Open widget Settings")
val activityIntent: Intent = MainActivity.intentToConfigure(context, widgetId)
startActivity(context, activityIntent, action, widgetId, "Open widget Settings")
}

else -> updateAllWidgets(context)
Expand Down
135 changes: 65 additions & 70 deletions app/src/main/kotlin/org/andstatus/todoagenda/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,49 +16,29 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.app.ActivityCompat.OnRequestPermissionsResultCallback
import org.andstatus.todoagenda.prefs.AllSettings
import org.andstatus.todoagenda.prefs.ApplicationPreferences
import org.andstatus.todoagenda.prefs.ApplicationPreferences.isAskForPermissions
import org.andstatus.todoagenda.provider.EventProviderType
import org.andstatus.todoagenda.provider.EventProviderType.Companion.neededPermissions
import org.andstatus.todoagenda.util.IntentUtil
import org.andstatus.todoagenda.util.PermissionsUtil

/**
* @author [email protected]
*/
class MainActivity : AppCompatActivity(), OnRequestPermissionsResultCallback {
var permissionsGranted = false
var listView: ListView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
try {
setContentView(R.layout.activity_main)
} catch (e: Exception) {
Log.w("onCreate", "Failed to find layout", e)
finish()
return
}
listView = findViewById(android.R.id.list)
checkPermissions()
if (openThisActivity()) {
setContentView(R.layout.activity_main)
AllSettings.reInitialize(this)
if (isOpenThisActivity()) {
updateScreen()
}
}

private fun checkPermissionsAndRequestThem() {
checkPermissions()
if (!permissionsGranted) {
val neededPermissions: List<String> = EventProviderType.neededPermissions.toList()
Log.d(this.localClassName, "Requesting permissions: $neededPermissions")
val arr: Array<String> = Array(neededPermissions.size) {i -> neededPermissions[i] }
ActivityCompat.requestPermissions(this, arr, 1)
}
}

private fun checkPermissions() {
permissionsGranted = PermissionsUtil.arePermissionsGranted(this)
}

private fun openThisActivity(): Boolean {
private fun isOpenThisActivity(): Boolean {
var widgetIdToConfigure = 0
if (permissionsGranted) {
if (!PermissionsUtil.mustRequestPermissions(this)) {
widgetIdToConfigure = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0)
if (widgetIdToConfigure == 0 && AllSettings.getInstances(this).size == 1) {
widgetIdToConfigure = AllSettings.getInstances(this).keys.iterator().next()
Expand All @@ -78,32 +58,37 @@ class MainActivity : AppCompatActivity(), OnRequestPermissionsResultCallback {
}

private fun updateScreen() {
var messageResourceId = R.string.permissions_justification
if (permissionsGranted) {
messageResourceId = if (AllSettings.getInstances(this).isEmpty()) {
val needToRequestPermission = PermissionsUtil.mustRequestPermissions(this)
val messageResourceId = if (needToRequestPermission) {
R.string.permissions_justification
} else {
if (AllSettings.getInstances(this).isEmpty()) {
R.string.no_widgets_found
} else {
R.string.select_a_widget_to_configure
}
}
val message = findViewById<TextView>(R.id.message)
message?.setText(messageResourceId)
if (!AllSettings.getInstances(this).isEmpty() && permissionsGranted) {
fillWidgetList()
listView!!.visibility = View.VISIBLE
} else {
listView!!.visibility = View.GONE
}
val goToHomeScreenButton = findViewById<Button>(R.id.go_to_home_screen_button)
if (goToHomeScreenButton != null) {
goToHomeScreenButton.visibility = if (permissionsGranted &&
AllSettings.getInstances(this).isEmpty()
) View.VISIBLE else View.GONE
}
val grantPermissionsButton = findViewById<Button>(R.id.grant_permissions)
if (grantPermissionsButton != null) {
grantPermissionsButton.visibility = if (permissionsGranted) View.GONE else View.VISIBLE
var text = this.getText(messageResourceId)
if (needToRequestPermission) {
text = text.toString() + EventProviderType.neededPermissions
.fold("\n") { acc, it -> "$acc\n$it" }
}
findViewById<TextView>(R.id.message)?.setText(text)

findViewById<ListView>(R.id.instancesList)?.visibility =
if (!needToRequestPermission && AllSettings.getInstances(this).isNotEmpty()) {
fillWidgetList()
View.VISIBLE
} else {
View.GONE
}
findViewById<Button>(R.id.grant_permissions)?.visibility =
if (needToRequestPermission) View.VISIBLE else View.GONE
findViewById<Button>(R.id.dont_ask_for_permissions_button)?.visibility =
if (needToRequestPermission && isAskForPermissions(this)) View.VISIBLE else View.GONE
findViewById<Button>(R.id.go_to_home_screen_button)?.visibility =
if (!needToRequestPermission && AllSettings.getInstances(this).isEmpty()) View.VISIBLE else View.GONE

EnvironmentChangedReceiver.updateAllWidgets(this)
}

Expand All @@ -115,37 +100,47 @@ class MainActivity : AppCompatActivity(), OnRequestPermissionsResultCallback {
map[KEY_ID] = Integer.toString(settings.widgetId)
data.add(map)
}
listView!!.adapter = SimpleAdapter(
this,
data,
R.layout.widget_list_item,
arrayOf(KEY_VISIBLE_NAME),
intArrayOf(R.id.widget_name)
)
listView!!.onItemClickListener = OnItemClickListener { parent, view, position, id ->
val stringStringMap = data[position]
val widgetId: String? = stringStringMap[KEY_ID]
if (widgetId.isNullOrBlank()) {
Log.w("fillWidgetList", "No $KEY_ID in $stringStringMap")
} else {
val intent: Intent = WidgetConfigurationActivity.intentToStartMe(
this@MainActivity, Integer.valueOf(widgetId)
)
startActivity(intent)
findViewById<ListView>(R.id.instancesList)?.let { listView ->
listView.adapter = SimpleAdapter(
this,
data,
R.layout.widget_list_item,
arrayOf(KEY_VISIBLE_NAME),
intArrayOf(R.id.widget_name)
)
listView.onItemClickListener = OnItemClickListener { parent, view, position, id ->
val stringStringMap = data[position]
val widgetId: String? = stringStringMap[KEY_ID]
if (widgetId.isNullOrBlank()) {
Log.w("fillWidgetList", "No $KEY_ID in $stringStringMap")
} else {
val intent: Intent = WidgetConfigurationActivity.intentToStartMe(
this@MainActivity, Integer.valueOf(widgetId)
)
startActivity(intent)
}
finish()
}
finish()
}
}

fun grantPermissions(view: View?) {
checkPermissionsAndRequestThem()
fun onGrantPermissionsButtonClick(view: View?) {
neededPermissions.toList().takeIf { it.isNotEmpty() }?.let { neededPermissions ->
Log.d(localClassName, "Requesting permissions: $neededPermissions")
val arr: Array<String> = Array(neededPermissions.size) { i -> neededPermissions[i] }
ActivityCompat.requestPermissions(this, arr, 1)
}
updateScreen()
}

fun onDontAskForPermissionsButtonClick(view: View?) {
ApplicationPreferences.setAskForPermissions(this, false)
onHomeButtonClick(view)
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
AllSettings.ensureLoadedFromFiles(this, true)
AllSettings.reInitialize(this)
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
checkPermissions()
updateScreen()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.andstatus.todoagenda.prefs.AllSettings
class RemoteViewsService : android.widget.RemoteViewsService() {
override fun onCreate() {
Log.d(TAG, "onCreate")
AllSettings.ensureLoadedFromFiles(this, false)
AllSettings.ensureLoadedFromFiles(this)
}

override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class WidgetConfigurationActivity : AppCompatActivity(), PreferenceFragmentCompa
super.onPause()
if (saveOnPause) {
ApplicationPreferences.save(this, widgetId)
EnvironmentChangedReceiver.Companion.updateWidget(this, widgetId)
EnvironmentChangedReceiver.updateWidget(this, widgetId)
}
}

Expand Down Expand Up @@ -79,10 +79,10 @@ class WidgetConfigurationActivity : AppCompatActivity(), PreferenceFragmentCompa
newWidgetId = ApplicationPreferences.getWidgetId(this)
}
var restartIntent: Intent? = null
if (newWidgetId == 0 || !PermissionsUtil.arePermissionsGranted(this)) {
restartIntent = MainActivity.Companion.intentToStartMe(this)
if (newWidgetId == 0 || PermissionsUtil.mustRequestPermissions(this)) {
restartIntent = MainActivity.intentToStartMe(this)
} else if (widgetId != 0 && widgetId != newWidgetId) {
restartIntent = MainActivity.Companion.intentToConfigure(this, newWidgetId)
restartIntent = MainActivity.intentToConfigure(this, newWidgetId)
} else if (widgetId == 0) {
widgetId = newWidgetId
ApplicationPreferences.fromInstanceSettings(this, widgetId)
Expand All @@ -97,14 +97,15 @@ class WidgetConfigurationActivity : AppCompatActivity(), PreferenceFragmentCompa

private fun restartIfNeeded() {
if (widgetId != ApplicationPreferences.getWidgetId(this) ||
!PermissionsUtil.arePermissionsGranted(this)
PermissionsUtil.mustRequestPermissions(this)
) {
widgetId = 0
startActivity(MainActivity.Companion.intentToStartMe(this))
startActivity(MainActivity.intentToStartMe(this))
finish()
}
}

@Deprecated("Deprecated in Java")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_ID_BACKUP_SETTINGS -> if (resultCode == RESULT_OK && data != null) {
Expand All @@ -122,7 +123,7 @@ class WidgetConfigurationActivity : AppCompatActivity(), PreferenceFragmentCompa
private fun backupSettings(uri: Uri?) {
if (uri == null) return
val settings = AllSettings.instanceFromId(this, widgetId)
val jsonSettings: String = WidgetData.Companion.fromSettings(this, settings).toJsonString()
val jsonSettings: String = WidgetData.fromSettings(this, settings).toJsonString()
var pfd: ParcelFileDescriptor? = null
var out: FileOutputStream? = null
try {
Expand Down Expand Up @@ -214,7 +215,7 @@ ${e.message}"""

companion object {
val EXTRA_GOTO_PREFERENCES_SECTION: String =
RemoteViewsFactory.Companion.PACKAGE + ".extra.GOTO_COLORS_PREFERENCES"
RemoteViewsFactory.PACKAGE + ".extra.GOTO_COLORS_PREFERENCES"
const val EXTRA_GOTO_SECTION_COLORS = "colors"
private val TAG = WidgetConfigurationActivity::class.java.simpleName
const val FRAGMENT_TAG = "settings_fragment"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class CalendarEventProvider(type: EventProviderType, context: Context, widgetId:
fun queryEvents(): List<CalendarEvent> {
initialiseParameters()
myContentResolver.onQueryEvents()
if (myContentResolver.isPermissionNeeded(context, type.permission) ||
if (myContentResolver.isPermissionNeeded(type) ||
settings.getActiveEventSources(type).isEmpty()
) {
return emptyList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ object AllSettings {
private var instancesLoaded = false
private val instances: MutableMap<Int, InstanceSettings> = ConcurrentHashMap()
fun instanceFromId(context: Context, widgetId: Int): InstanceSettings {
ensureLoadedFromFiles(context, false)
ensureLoadedFromFiles(context)
synchronized(instances) {
val settings = instances[widgetId]
return settings ?: newInstance(context, widgetId)
Expand All @@ -49,7 +49,9 @@ object AllSettings {
}
}

fun ensureLoadedFromFiles(context: Context, reInitialize: Boolean) {
fun reInitialize(context: Context) = ensureLoadedFromFiles(context, true)

fun ensureLoadedFromFiles(context: Context, reInitialize: Boolean = false) {
if (instancesLoaded && !reInitialize) return
synchronized(instances) {
if (instancesLoaded && !reInitialize) return
Expand Down Expand Up @@ -108,7 +110,7 @@ object AllSettings {
}

fun delete(context: Context, widgetId: Int) {
ensureLoadedFromFiles(context, false)
ensureLoadedFromFiles(context)
synchronized(instances) {
instances.remove(widgetId)
SettingsStorage.delete(context, getStorageKey(widgetId))
Expand Down Expand Up @@ -151,7 +153,7 @@ object AllSettings {
}

fun getInstances(context: Context): Map<Int, InstanceSettings> {
ensureLoadedFromFiles(context, false)
ensureLoadedFromFiles(context)
return instances
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import org.andstatus.todoagenda.widget.WidgetHeaderLayout
object ApplicationPreferences {
const val PREF_DIFFERENT_COLORS_FOR_DARK = "differentColorsForDark"
private const val PREF_COLOR_THEME_TYPE = "colorThemeType"
private const val PREF_ASK_FOR_PERMISSIONS = "askForPermissions"

fun fromInstanceSettings(context: Context, widgetId: Int) {
synchronized(ApplicationPreferences::class.java) {
val settings = AllSettings.instanceFromId(context, widgetId)
Expand Down Expand Up @@ -82,6 +84,14 @@ object ApplicationPreferences {
}
}

fun isAskForPermissions(context: Context): Boolean {
return getBoolean(context, PREF_ASK_FOR_PERMISSIONS, true)
}

fun setAskForPermissions(context: Context, value: Boolean) {
setBoolean(context, PREF_ASK_FOR_PERMISSIONS, value)
}

fun getWidgetId(context: Context?): Int {
return if (context == null) 0 else getInt(context, InstanceSettings.PREF_WIDGET_ID, 0)
}
Expand Down Expand Up @@ -426,7 +436,6 @@ object ApplicationPreferences {
}
}

// TODO: is return type nullable?
fun getString(context: Context, key: String?, defaultValue: String = ""): String {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return (if (prefs == null) defaultValue
Expand Down
Loading

0 comments on commit 0092ea6

Please sign in to comment.