Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 8915a3c1 authored by Sunik Kupfer's avatar Sunik Kupfer Committed by Ricki Hirner
Browse files

android 13 compatibility (bitfireAT/davx5#155)



* check for notify permission before notifying

* [WIP] add notification permission request

* Revert "check for notify permission before notifying"

This reverts commit ed8e046d73163bef5684622bd877f08b9ee781c6.

* add notification permission request

* [WIP] add notifications disabled card in accounts view

* add notifications disabled card in accounts view

* reorder permissions

* use dp instead of mm for image max height in permissions view

* stop using array to bundle notification permissions

* Use new permissions contract for PermissionsFragment

Co-authored-by: default avatarRicki Hirner <hirner@bitfire.at>
parent 43ae3fcd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ android {
        setProperty "archivesBaseName", "davx5-ose-" + getVersionName()

        minSdkVersion 21        // Android 5
        targetSdkVersion 32     // Android 12v2
        targetSdkVersion 33     // Android 13

        buildConfigField "String", "userAgent", "\"DAVx5\""

+20 −0
Original line number Diff line number Diff line
@@ -4,12 +4,14 @@

package at.bitfire.davdroid.ui

import android.Manifest
import android.accounts.Account
import android.accounts.AccountManager
import android.accounts.OnAccountsUpdateListener
import android.app.Activity
import android.app.Application
import android.content.*
import android.content.pm.PackageManager
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
@@ -18,6 +20,8 @@ import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.view.*
import androidx.core.content.ContextCompat
import androidx.core.content.PackageManagerCompat
import androidx.core.content.getSystemService
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
@@ -29,6 +33,7 @@ import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import at.bitfire.davdroid.DavUtils
import at.bitfire.davdroid.DavUtils.SyncStatus
import at.bitfire.davdroid.PermissionUtils
import at.bitfire.davdroid.R
import at.bitfire.davdroid.StorageLowReceiver
import at.bitfire.davdroid.databinding.AccountListBinding
@@ -57,6 +62,10 @@ class AccountListFragment: Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding.allowNotifications.setOnClickListener {
            startActivity(Intent(requireActivity(), PermissionsActivity::class.java))
        }

        model.networkAvailable.observe(viewLifecycleOwner) { networkAvailable ->
            binding.noNetworkInfo.visibility = if (networkAvailable) View.GONE else View.VISIBLE
        }
@@ -103,11 +112,22 @@ class AccountListFragment: Fragment() {
        }
    }

    override fun onResume() {
        super.onResume()
        checkPermissions()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    fun checkPermissions() {
        if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED)
            binding.noNotificationsInfo.visibility = View.GONE
        else
            binding.noNotificationsInfo.visibility = View.VISIBLE
    }

    class AccountAdapter(
            val activity: Activity
+26 −12
Original line number Diff line number Diff line
@@ -4,9 +4,11 @@

package at.bitfire.davdroid.ui

import android.Manifest
import android.app.Application
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
@@ -14,7 +16,9 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.MainThread
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.AndroidViewModel
@@ -42,6 +46,10 @@ class PermissionsFragment: Fragment() {

        binding.text.text = getString(R.string.permissions_text, getString(R.string.app_name))

        val requestPermission = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
            model.checkPermissions()
        }

        model.needAutoResetPermission.observe(viewLifecycleOwner, { keepPermissions ->
            if (keepPermissions == true && model.haveAutoResetPermission.value == false) {
                Toast.makeText(requireActivity(), R.string.permissions_autoreset_instruction, Toast.LENGTH_LONG).show()
@@ -50,34 +58,38 @@ class PermissionsFragment: Fragment() {
        })
        model.needContactsPermissions.observe(viewLifecycleOwner, { needContacts ->
            if (needContacts && model.haveContactsPermissions.value == false)
                requestPermissions(CONTACT_PERMISSIONS, 0)
                requestPermission.launch(CONTACT_PERMISSIONS)
        })
        model.needCalendarPermissions.observe(viewLifecycleOwner, { needCalendars ->
            if (needCalendars && model.haveCalendarPermissions.value == false)
                requestPermissions(CALENDAR_PERMISSIONS, 0)
                requestPermission.launch(CALENDAR_PERMISSIONS)
        })
        model.needNotificationPermissions.observe(viewLifecycleOwner, { needNotifications ->
            if (needNotifications && model.haveNotificationPermissions.value == false)
                requestPermission.launch(arrayOf(Manifest.permission.POST_NOTIFICATIONS))
        })
        model.needOpenTasksPermissions.observe(viewLifecycleOwner, { needOpenTasks ->
            if (needOpenTasks == true && model.haveOpenTasksPermissions.value == false)
                requestPermissions(TaskProvider.PERMISSIONS_OPENTASKS, 0)
                requestPermission.launch(TaskProvider.PERMISSIONS_OPENTASKS)
        })
        model.needTasksOrgPermissions.observe(viewLifecycleOwner, { needTasksOrg ->
            if (needTasksOrg == true && model.haveTasksOrgPermissions.value == false)
                requestPermissions(TaskProvider.PERMISSIONS_TASKS_ORG, 0)
                requestPermission.launch(TaskProvider.PERMISSIONS_TASKS_ORG)
        })
        model.needJtxPermissions.observe(viewLifecycleOwner, { needJtx ->
            if (needJtx == true && model.haveJtxPermissions.value == false)
                requestPermissions(TaskProvider.PERMISSIONS_JTX, 0)
                requestPermission.launch(TaskProvider.PERMISSIONS_JTX)
        })
        model.needAllPermissions.observe(viewLifecycleOwner, { needAll ->
            if (needAll && model.haveAllPermissions.value == false) {
                val all = mutableSetOf(*CONTACT_PERMISSIONS, *CALENDAR_PERMISSIONS)
                val all = mutableSetOf(*CONTACT_PERMISSIONS, *CALENDAR_PERMISSIONS, Manifest.permission.POST_NOTIFICATIONS)
                if (model.haveOpenTasksPermissions.value != null)
                    all.addAll(TaskProvider.PERMISSIONS_OPENTASKS)
                if (model.haveTasksOrgPermissions.value != null)
                    all.addAll(TaskProvider.PERMISSIONS_TASKS_ORG)
                if (model.haveJtxPermissions.value != null)
                    all.addAll(TaskProvider.PERMISSIONS_JTX)
                requestPermissions(all.toTypedArray(), 0)
                requestPermission.launch(all.toTypedArray())
            }
        })

@@ -93,11 +105,6 @@ class PermissionsFragment: Fragment() {
        model.checkPermissions()
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        model.checkPermissions()
    }


    class Model(app: Application): AndroidViewModel(app) {

@@ -108,6 +115,8 @@ class PermissionsFragment: Fragment() {
        val needContactsPermissions = MutableLiveData<Boolean>()
        val haveCalendarPermissions = MutableLiveData<Boolean>()
        val needCalendarPermissions = MutableLiveData<Boolean>()
        val haveNotificationPermissions = MutableLiveData<Boolean>()
        val needNotificationPermissions = MutableLiveData<Boolean>()

        val haveOpenTasksPermissions = MutableLiveData<Boolean>()
        val needOpenTasksPermissions = MutableLiveData<Boolean>()
@@ -153,6 +162,10 @@ class PermissionsFragment: Fragment() {
            haveCalendarPermissions.value = calendarPermissions
            needCalendarPermissions.value = calendarPermissions

            val notificationPermissions = ContextCompat.checkSelfPermission(getApplication(), Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED
            haveNotificationPermissions.value = notificationPermissions
            needNotificationPermissions.value = notificationPermissions

            // OpenTasks
            val openTasksAvailable = pm.resolveContentProvider(ProviderName.OpenTasks.authority, 0) != null
            var openTasksPermissions: Boolean? = null
@@ -190,6 +203,7 @@ class PermissionsFragment: Fragment() {
            // "all permissions" switch
            val allPermissions = contactPermissions &&
                    calendarPermissions &&
                    notificationPermissions &&
                    (!openTasksAvailable || openTasksPermissions == true) &&
                    (!tasksOrgAvailable || tasksOrgPermissions == true) &&
                    (!jtxAvailable || jtxPermissions == true)
+5 −0
Original line number Diff line number Diff line
<vector android:autoMirrored="true" android:height="24dp"
    android:tint="#FFFFFF" android:viewportHeight="24"
    android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="@android:color/white" android:pathData="M20,18.69L7.84,6.14 5.27,3.49 4,4.76l2.8,2.8v0.01c-0.52,0.99 -0.8,2.16 -0.8,3.42v5l-2,2v1h13.73l2,2L21,19.72l-1,-1.03zM12,22c1.11,0 2,-0.89 2,-2h-4c0,1.11 0.89,2 2,2zM18,14.68L18,11c0,-3.08 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68c-0.15,0.03 -0.29,0.08 -0.42,0.12 -0.1,0.03 -0.2,0.07 -0.3,0.11h-0.01c-0.01,0 -0.01,0 -0.02,0.01 -0.23,0.09 -0.46,0.2 -0.68,0.31 0,0 -0.01,0 -0.01,0.01L18,14.68z"/>
</vector>
+33 −2
Original line number Diff line number Diff line
@@ -5,6 +5,37 @@
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">

    <androidx.cardview.widget.CardView
        android:id="@+id/no_notifications_info"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        app:contentPadding="@dimen/card_padding">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <androidx.appcompat.widget.AppCompatTextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                app:drawableLeftCompat="@drawable/ic_notifications_off"
                app:drawableTint="?android:attr/textColorPrimary"
                android:drawablePadding="8dp"
                style="@style/TextAppearance.MaterialComponents.Body1"
                android:text="@string/account_list_no_notification_permission"/>

            <Button
                android:id="@+id/allow_notifications"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                style="@style/Widget.MaterialComponents.Button.TextButton"
                android:text="@string/account_permissions_action" />

        </LinearLayout>
    </androidx.cardview.widget.CardView>

    <androidx.cardview.widget.CardView
        android:id="@+id/no_network_info"
        android:layout_width="match_parent"
@@ -31,7 +62,7 @@
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                style="@style/Widget.MaterialComponents.Button.TextButton"
                android:text="Manage connections" />
                android:text="@string/account_list_manage_connections" />

        </LinearLayout>
    </androidx.cardview.widget.CardView>
@@ -63,7 +94,7 @@
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                style="@style/Widget.MaterialComponents.Button.TextButton"
                android:text="Manage storage" />
                android:text="@string/account_list_manage_storage" />

        </LinearLayout>
    </androidx.cardview.widget.CardView>
Loading