Как мне вернуться к своему приложению после того, как пользователь предоставил разрешение на использование в Kotlin? - PullRequest
0 голосов
/ 04 марта 2019

Мне нужно, чтобы мое приложение автоматически возвращалось в мое приложение, как только пользователь предоставил разрешение на доступ к статистике использования с помощью кнопки переключения / переключения на экране настроек.Это возможно в приложении Google FILES.PSB FLOW из Google File App: Поток приложения Google Files

Как мне добиться этого в моем приложении Kotlin.Я пробовал несколько способов, но не смог добиться этого.Пожалуйста, порекомендуйте.Спасибо.

ОСНОВНАЯ ДЕЯТЕЛЬНОСТЬ

класс MainActivity: AppCompatActivity () {

private lateinit var usage: UsageStatsManager
private lateinit var impStats: MutableList<UsageStats>
private lateinit var ops: AppOpsManager
private var opsChanged = false


private val opsListener = object : AppOpsManager.OnOpChangedListener {

    override fun onOpChanged(op: String?, packageName: String?) {
        //Stop Watching
        ops.stopWatchingMode(this)

        if (!opsChanged) {
            opsChanged = true
            if (usagePermission()) {
                val intent = Intent(this@MainActivity, MainActivity::class.java).apply {
                    addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
                }
                startActivity(intent)
            }
        }
    }
}

private fun usagePermission(): Boolean {
    val mode = ops.checkOpNoThrow(
        AppOpsManager.OPSTR_GET_USAGE_STATS,
        android.os.Process.myUid(),
        packageName
    ) ?: AppOpsManager.MODE_ALLOWED
    return mode == AppOpsManager.MODE_ALLOWED
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
    ops = getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
    ops.startWatchingMode(AppOpsManager.OPSTR_GET_USAGE_STATS, packageName, opsListener)
    binding.settings.setOnClickListener {
        openSettings()
    }
}


override fun onDestroy() {
    ops.stopWatchingMode(opsListener)
    super.onDestroy()
}

fun openSettings() {
    val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)
    if (intent.resolveActivity(packageManager) != null)
        startActivity(intent)
}

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    val fragmentTransaction = fragmentManager.beginTransaction()
    val fragment = FragmentA()
    fragmentTransaction.add(R.id.main_activity, fragment)
    fragmentTransaction.commit()

}

}}

ФРАГМЕНТ A

классTitleFragment: Fragment () {

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

    val binding = DataBindingUtil.inflate<FragmentTitleBinding>(inflater, R.layout.fragmentA, container, false)
    return binding.root
}

override fun onDestroyView() {
    super.onDestroyView()
}

****MANIFEST FILE***
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sample">

<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>

</manifest>



FRAGMENT A XML
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navGraph="@navigation/navigation">

<TextView
android:id="@+id/View"
android:layout_width="120dp"
android:layout_height="43dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="@string/welcome"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

</layout>


NAVIGATION XML
SINCE I AM USING NAVIGATION GRAPH

<?xml version="1.0" encoding="utf-8"?>
<navigation

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:id="@+id/navigation"
app:startDestination="@+id/fragmentA">

<fragment
android:id="@+id/fragmentA"
android:name="com.sample.FragmentA"
android:label="FragmentA"
tools:layout="@layout/fragmentA"/>


</navigation>

**ACTIVITY MAN XML**
<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<LinearLayout
android:id="@+id/main_activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">


<fragment
android:id="@+id/myNavHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost ="true"
app:navGraph="@navigation/navigation"/>



</LinearLayout>

</layout>

1 Ответ

0 голосов
/ 09 марта 2019

С AppOpsManager Документация на Android.

startWatchingMode

public void startWatchingMode (String op, 
                String packageName, 
                AppOpsManager.OnOpChangedListener callback)

Отслеживание изменений режима работы для данной операциив данном пакете приложения.Вы можете наблюдать за операционными изменениями только для своего UID.

Решение: Вы можете выполнить следующий пример, чтобы вернуться к своему приложению после того, как пользователи предоставят разрешение на доступ к данным об использовании.

class MainActivity : AppCompatActivity() {

    private var mAppOpsManager: AppOpsManager? = null

    private var mOpChanged = false
    private val mOnOpChangedListener = object : AppOpsManager.OnOpChangedListener {
        override fun onOpChanged(op: String?, packageName: String?) {
            // Stop watch op changed
            mAppOpsManager!!.stopWatchingMode(this)

            if (!mOpChanged) {
                mOpChanged = true
                if (hasUsageDataAccessPermission()) {
                    // Start your designed activity here
                    val intent = Intent(this@MainActivity, MainActivity::class.java).apply {
                        addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
                        // [NOTE] You can put some data into this intent.
                        // This intent will be received in onNewIntent method.
                    }
                    startActivity(intent)
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mAppOpsManager = getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager?
        mAppOpsManager?.startWatchingMode(AppOpsManager.OPSTR_GET_USAGE_STATS, 
                                          packageName, 
                                          mOnOpChangedListener)

        if (!hasUsageDataAccessPermission()) {
            val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)
            if (intent.resolveActivity(packageManager) != null) {
                startActivity(intent)
            }
        }
    }

    override fun onDestroy() {
        mAppOpsManager?.stopWatchingMode(mOnOpChangedListener)
        super.onDestroy()
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        // [IMPORTANT] After users grant usage data access permission, this activity will display
        // and this method will be called instead of onCreate.
        // You should handle your logic here.
    }

    private fun hasUsageDataAccessPermission(): Boolean {
        val mode = mAppOpsManager?.checkOpNoThrow(
            AppOpsManager.OPSTR_GET_USAGE_STATS,
            android.os.Process.myUid(),
            packageName
        ) ?: AppOpsManager.MODE_ALLOWED

        return mode == AppOpsManager.MODE_ALLOWED
    }
}
...