App Request Permission in android - Bolt UIX

Permission requests should be simple, transparent, and understandable.

Pay attention to permissions Build trust with your users by being transparent and providing users control over how they experience your app.

UI for prominent disclosure when requesting for permissions from user.

I'm going to show you how to implement run time permission request with kotlin

This article describes the best practices for providing prominent disclosure and consent requests to your app's users.

In the layout file:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/gradient_bg">

    <androidx.core.widget.NestedScrollView
        android:id="@+id/nested_scroll_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none"
        android:scrollingCache="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="10dp">

            <LinearLayout
                android:layout_marginTop="10dp"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:orientation="horizontal">

                <View
                    android:layout_width="0dp"
                    android:layout_height="0dp"
                    android:layout_weight="1" />

                <ImageButton
                    android:id="@+id/bt_close"
                    android:layout_width="?attr/actionBarSize"
                    android:layout_height="?attr/actionBarSize"
                    android:background="?attr/selectableItemBackgroundBorderless"
                    app:srcCompat="@drawable/ic_round_close"
                    app:tint="@color/md_theme_light_onPrimaryContainer"
                    tools:ignore="ContentDescription,SpeakableTextPresentCheck" />
            </LinearLayout>

            <View
                android:layout_width="0dp"
                android:layout_height="10dp" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingBottom="10dp"
                android:paddingTop="10dp">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="20dp"
                    android:layout_marginRight="20dp"
                    android:layout_marginTop="10dp"
                    android:text="Permissions Needed"
                    android:textStyle="bold"
                    style="@style/TextAppearance.Material3.TitleLarge"
                    android:textColor="@color/white"
                    />
                <TextView
                    android:layout_marginLeft="20dp"
                    android:layout_marginRight="20dp"
                    android:layout_marginBottom="10dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="This permissions need for work app, see description for each permission"
                    android:textColor="@color/white" />
            </LinearLayout>

            <com.google.android.material.card.MaterialCardView
                style="?attr/materialCardViewElevatedStyle"
                app:cardBackgroundColor="@android:color/white"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="visible"
                app:cardCornerRadius="10dp"
                app:cardElevation="5dp"
                app:cardUseCompatPadding="true">
                <LinearLayout
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="10dp"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:clickable="false"
                    android:gravity="center_vertical"
                    android:minHeight="50dp"
                    android:orientation="horizontal"
                    android:paddingLeft="5dp"
                    android:paddingRight="5dp"
                    android:focusable="false">

                    <View
                        android:layout_width="5dp"
                        android:layout_height="wrap_content" />

                    <ImageButton
                        android:layout_width="48dp"
                        android:layout_height="48dp"
                        android:background="@android:color/transparent"
                        app:srcCompat="@drawable/permission_location"
                        app:tint="@color/md_theme_light_onPrimaryContainer"
                        tools:ignore="SpeakableTextPresentCheck" />

                    <View
                        android:layout_width="5dp"
                        android:layout_height="wrap_content" />

                    <LinearLayout
                        android:layout_weight="1"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:orientation="vertical">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="Turn On Location Service"
                            style="@style/TextAppearance.Material3.TitleSmall"
                            android:textStyle="bold"
                            android:textColor="@color/md_theme_light_onSecondaryContainer"
                            />

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="Explore the world without getting lost and keep the track of your location."
                            android:textColor="@color/md_theme_light_tertiary" />

                    </LinearLayout>

                    <View
                        android:layout_width="5dp"
                        android:layout_height="wrap_content" />

                    <com.google.android.material.button.MaterialButton
                        android:id="@+id/enableFineLocation"
                        style="?attr/materialButtonOutlinedStyle"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:minWidth="0dp"
                        android:minHeight="48dp"
                        android:text="Allow"
                        android:textColor="@color/md_theme_light_primary" />

                    <View
                        android:layout_width="5dp"
                        android:layout_height="wrap_content" />

                </LinearLayout>
            </com.google.android.material.card.MaterialCardView>

            <com.google.android.material.card.MaterialCardView
                style="?attr/materialCardViewElevatedStyle"
                app:cardBackgroundColor="@android:color/white"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="visible"
                app:cardCornerRadius="10dp"
                app:cardElevation="5dp"
                app:cardUseCompatPadding="true">
                <LinearLayout
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="10dp"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:clickable="false"
                    android:gravity="center_vertical"
                    android:minHeight="50dp"
                    android:orientation="horizontal"
                    android:paddingLeft="5dp"
                    android:paddingRight="5dp"
                    android:focusable="false">

                    <View
                        android:layout_width="5dp"
                        android:layout_height="wrap_content" />

                    <ImageButton
                        android:layout_width="48dp"
                        android:layout_height="48dp"
                        android:background="@android:color/transparent"
                        app:srcCompat="@drawable/permission_bluetooth"
                        app:tint="@color/md_theme_light_onPrimaryContainer"
                        tools:ignore="SpeakableTextPresentCheck" />

                    <View
                        android:layout_width="5dp"
                        android:layout_height="wrap_content" />

                    <LinearLayout
                        android:layout_weight="1"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:orientation="vertical">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="Bluetooth"
                            style="@style/TextAppearance.Material3.TitleSmall"
                            android:textStyle="bold"
                            android:textColor="@color/md_theme_light_onSecondaryContainer"
                            />

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="Enable bluetooth for News of events happening near you"
                            android:textColor="@color/md_theme_light_tertiary" />

                    </LinearLayout>

                    <View
                        android:layout_width="5dp"
                        android:layout_height="wrap_content" />
                    <com.google.android.material.button.MaterialButton
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Allow"
                        android:minHeight="0dp"
                        android:minWidth="0dp"
                        android:textColor="@color/md_theme_light_primary"
                        style="?attr/materialButtonOutlinedStyle"
                        />
                    <View
                        android:layout_width="5dp"
                        android:layout_height="wrap_content" />

                </LinearLayout>
            </com.google.android.material.card.MaterialCardView>

            <com.google.android.material.card.MaterialCardView
                style="?attr/materialCardViewElevatedStyle"
                app:cardBackgroundColor="@android:color/white"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="visible"
                app:cardCornerRadius="10dp"
                app:cardElevation="5dp"
                app:cardUseCompatPadding="true">
                <LinearLayout
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="10dp"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:clickable="false"
                    android:gravity="center_vertical"
                    android:minHeight="50dp"
                    android:orientation="horizontal"
                    android:paddingLeft="5dp"
                    android:paddingRight="5dp"
                    android:focusable="false">

                    <View
                        android:layout_width="5dp"
                        android:layout_height="wrap_content" />

                    <ImageButton
                        android:layout_width="48dp"
                        android:layout_height="48dp"
                        android:background="@android:color/transparent"
                        app:srcCompat="@drawable/baseline_share_location_24"
                        app:tint="@color/md_theme_light_onPrimaryContainer"
                        tools:ignore="SpeakableTextPresentCheck" />

                    <View
                        android:layout_width="5dp"
                        android:layout_height="wrap_content" />

                    <LinearLayout
                        android:layout_weight="1"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:orientation="vertical">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="Enable GPS"
                            style="@style/TextAppearance.Material3.TitleSmall"
                            android:textStyle="bold"
                            android:textColor="@color/md_theme_light_onSecondaryContainer"
                            />

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="Enable GPS for Tagging and sharing your location"
                            android:textColor="@color/md_theme_light_tertiary" />

                    </LinearLayout>

                    <View
                        android:layout_width="5dp"
                        android:layout_height="wrap_content" />
                    <com.google.android.material.button.MaterialButton
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Allow"
                        android:minHeight="0dp"
                        android:minWidth="0dp"
                        android:textColor="@color/md_theme_light_primary"
                        style="?attr/materialButtonOutlinedStyle"
                        />
                    <View
                        android:layout_width="5dp"
                        android:layout_height="wrap_content" />

                </LinearLayout>
            </com.google.android.material.card.MaterialCardView>



            <TextView
                android:layout_marginTop="5dp"
                android:layout_marginLeft="3dp"
                android:layout_marginRight="3dp"
                android:layout_marginBottom="3dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Permissions are necessary for the correct work of the application and the performance of all functions."
                android:textColor="@color/white" />

            <View
                android:layout_width="0dp"
                android:layout_height="15dp" />

        </LinearLayout>
    </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

..

In the fragment : we request location permission when user on click "Allow" button

package com.boltuix.materialuiux

import android.Manifest
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.Fragment
import com.boltuix.materialuiux.databinding.FragmentDemoBinding

class DemoFragment : Fragment() {

    private var _binding: FragmentDemoBinding? = null

    // This property is only valid between onCreateView and
    // onDestroyView.
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {

        _binding = FragmentDemoBinding.inflate(inflater, container, false)
        return binding.root

    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding.enableFineLocation.setOnClickListener {
            requestSinglePermission.launch(Manifest.permission.ACCESS_FINE_LOCATION)
        }

    }


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

    private val requestSinglePermission =
        registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
            if (isGranted) {
                // Do something if permission granted
                binding.enableFineLocation.visibility=View.GONE
            }
            else {
                // Do something as the permission is not granted
                binding.enableFineLocation.visibility=View.VISIBLE
            }
        }
}

..


* Do not forgot to add permission in AndroidManifest.xml.xml (the permission which you request from user)

GET source code on Github:


Comments