我在Android中使用以下代码授予run time permission
,此处我正在尝试为Camera
执行此操作。
我将所需要的内容添加到最清晰的内容中:
<uses-permission android:name="android.permission.CAMERA"/>
以下MainActivity.Kt
与我完美配合:
package com.example.hasan.runtime.feature
import android.Manifest
import android.os.Bundle
import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import feature.utilis.isPermissionGranted
import feature.utilis.requestPermission
import feature.utilis.shouldShowPermissionRationale
import feature.utilis.showSnackbar
import kotlinx.android.synthetic.main.activity_main.*
const val PERMISSION_REQUEST_CAMERA = 0
class MainActivity : AppCompatActivity() {
// private lateinit var layout: View
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn_cam.setOnClickListener { showCamera() }
}
fun showCamera() {
if (isPermissionGranted(Manifest.permission.CAMERA)) {
main_layout.showSnackbar(R.string.camera_permission_available,
Snackbar.LENGTH_INDEFINITE, R.string.ok){
startCamera()
}
} else {
requestCameraPermission()
}
}
fun startCamera() {
// val intent = Intent(this, CameraPreviewActivity::class.java)
// startActivity(intent)
Toast.makeText(this, "Done correctly", Toast.LENGTH_LONG).show()
}
private fun requestCameraPermission() {
// Permission has not been granted and must be requested.
if (shouldShowPermissionRationale(Manifest.permission.CAMERA)) {
main_layout.showSnackbar(R.string.camera_access_required,
Snackbar.LENGTH_INDEFINITE, R.string.ok) {
requestPermission(Manifest.permission.CAMERA,
PERMISSION_REQUEST_CAMERA)
}
} else {
main_layout.showSnackbar(R.string.camera_permission_not_available,
Snackbar.LENGTH_INDEFINITE, R.string.ok){}
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
grantResults: IntArray) {
if (requestCode == REQUEST_CAMERA) {
if (isPermissionGranted(Manifest.permission.CAMERA)) {
main_layout.showSnackbar(R.string.camera_permission_available,
Snackbar.LENGTH_INDEFINITE, R.string.ok){}
} else {
main_layout.showSnackbar(R.string.camera_permission_not_available,
Snackbar.LENGTH_INDEFINITE, R.string.ok){}
}
} else if (requestCode == REQUEST_CONTACTS) {
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
}
companion object {
const val REQUEST_CAMERA = 0
const val REQUEST_CONTACTS = 1
val PERMISSIONS_CONTACT = arrayOf(Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS)
}
}
我在下面Extensions
写了这些内容,只是为了让上面的代码非常清楚谁阅读它:
ActivityExt.Kt
:
package feature.utilis
import android.content.pm.PackageManager
import android.support.v4.app.ActivityCompat
import android.support.v7.app.AppCompatActivity
fun AppCompatActivity.isPermissionGranted(permission: String) =
ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
fun AppCompatActivity.shouldShowPermissionRationale(permission: String) =
ActivityCompat.shouldShowRequestPermissionRationale(this, permission)
fun AppCompatActivity.requestPermission(permission: String, requestId: Int) =
ActivityCompat.requestPermissions(this, arrayOf(permission), requestId)
fun AppCompatActivity.batchRequestPermissions(permissions: Array<String>, requestId: Int) =
ActivityCompat.requestPermissions(this, permissions, requestId)
ViewExt.Kt
:
package feature.utilis
import android.support.design.widget.Snackbar
import android.view.View
fun View.showSnackbar(msgId: Int, length: Int) {
showSnackbar(context.getString(msgId), length)
}
fun View.showSnackbar(msg: String, length: Int) {
showSnackbar(msg, length, null, {})
}
fun View.showSnackbar(
msgId: Int,
length: Int,
actionMessageId: Int,
action: (View) -> Unit
) {
showSnackbar(context.getString(msgId), length, context.getString(actionMessageId), action)
}
fun View.showSnackbar(
msg: String,
length: Int,
actionMessage: CharSequence?,
action: (View) -> Unit
) {
val snackbar = Snackbar.make(this, msg, length)
if (actionMessage != null) {
snackbar.setAction(actionMessage) {
action(this)
}.show()
}
}
我的问题是,当我添加我需要的所有权限时,我觉得MainActivity.Kt
文件会非常长,因为建议逐个询问它们,如何将其拆分为多个文件,以便每个文件都执行该操作权限所需的操作,例如SMS
,Contact
,...
答案 0 :(得分:0)
我通过以下方式解决了这个问题:
创建ActivityExt.tk
:
package feature.extensions
import android.app.Activity
import android.content.pm.PackageManager
import android.support.v4.app.ActivityCompat
import android.widget.Toast
fun Activity.isPermissionGranted(permission: String) =
ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
fun Activity.arePermissionsGranted(permissions: Array<String>): Boolean {
permissions.forEach { it ->
if(ActivityCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED)
return false
}
return true
}
fun Activity.shouldShowPermissionRationale(permission: String) =
ActivityCompat.shouldShowRequestPermissionRationale(this, permission)
fun Activity.requestPermission(permission: String, requestId: Int) =
ActivityCompat.requestPermissions(this, arrayOf(permission), requestId)
fun Activity.batchRequestPermissions(permissions: Array<String>, requestId: Int) =
ActivityCompat.requestPermissions(this, permissions, requestId)
fun Activity.toast(message: CharSequence) =
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
创建PermissionsResult.Kt
:
package feature.utilities
import android.Manifest
import android.Manifest.permission.*
import android.app.Activity
import android.support.design.widget.Snackbar
import android.view.View
import com.example.hasan.runtime.feature.PERMISSION_REQUEST_CAMERA
import com.example.hasan.runtime.feature.R
import feature.extensions.requestPermission
import feature.extensions.toast
import feature.extentions.showSnackbar
object UtilPermissionsResult {
fun getPermissionsResult(activity: Activity?, layout: View?,
permissions: Array<String>, grantResults: IntArray) {
val permissionsMap = HashMap<String, Int>()
for ((index, permission) in permissions.withIndex()) {
permissionsMap[permission] = grantResults[index]
}
if(permissionsMap[CAMERA] != 0) {
layout!!.showSnackbar(R.string.camera_permission_not_available,
Snackbar.LENGTH_INDEFINITE, R.string.ok){
activity!!.toast("Camera permission NOT granted")
activity!!.requestPermission(Manifest.permission.CAMERA,
PERMISSION_REQUEST_CAMERA)
}
}
else {
layout!!.showSnackbar(R.string.camera_permission_available,
Snackbar.LENGTH_INDEFINITE, R.string.ok){
activity!!.toast("Camera permission granted")
}
}
if(permissionsMap[ACCESS_FINE_LOCATION] != 0
|| permissionsMap[READ_SMS] != 0) {
activity!!.toast("Location and permissions are a must")
} else {
activity!!.toast("Thanks, all permissions had been granted")
}
}
}
创建Permissions.Kt
:
package feature.utilities
import android.Manifest.permission.*
import android.app.Activity
import android.support.design.widget.Snackbar
import android.view.View
import com.example.hasan.runtime.feature.PERMISSION_REQUEST_ALL
import com.example.hasan.runtime.feature.PERMISSION_REQUEST_CAMERA
import com.example.hasan.runtime.feature.R
import feature.extensions.*
import feature.extentions.showSnackbar
val PERMISSIONS =
arrayOf(ACCESS_FINE_LOCATION,
ACCESS_COARSE_LOCATION,
READ_SMS, READ_CONTACTS,
ACCESS_NETWORK_STATE)
object UtilPermissions {
fun showCamera(activity: Activity?, layout: View?) {
// using context
if (activity!!.isPermissionGranted(CAMERA)) {
startCamera(activity)
} else {
requestCameraPermission(activity, layout)
}
}
private fun requestCameraPermission(activity: Activity?, layout: View?) {
if (activity!!.shouldShowPermissionRationale(CAMERA)) {
layout!!.showSnackbar(R.string.camera_access_required,
Snackbar.LENGTH_INDEFINITE, R.string.ok) {
// activity!!.requestPermission(CAMERA, PERMISSION_REQUEST_CAMERA)
activity!!.batchRequestPermissions(PERMISSIONS, PERMISSION_REQUEST_ALL)
}
}
else { // useful in case camera not available
layout!!.showSnackbar(R.string.camera_permission_not_available,
Snackbar.LENGTH_INDEFINITE, R.string.ok){
activity!!.requestPermission(CAMERA,
PERMISSION_REQUEST_CAMERA)
}
}
}
private fun startCamera(activity: Activity?) {
// val intent = Intent(this, CameraPreviewActivity::class.java)
// startActivity(intent)
activity!!.toast("Done smoothly")
}
}
然后MainActivity.Kt
变得像下面一样简单和小:
package com.example.hasan.runtime.feature
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.View
import feature.utilities.UtilPermissions.showCamera
import feature.utilities.UtilPermissionsResult.getPermissionsResult
import kotlinx.android.synthetic.main.activity_main.*
const val PERMISSION_REQUEST_CAMERA = 0
const val PERMISSION_REQUEST_ALL = 0
private lateinit var layout: View
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
layout = main_layout
btn_cam.setOnClickListener { showCamera(this, main_layout) }
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
grantResults: IntArray) {
getPermissionsResult(
this,
layout,
permissions,
grantResults
)
}
}
AndroidManifest.xml
包括以下内容:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hasan.runtime.feature">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application>
<activity android:name=".MainActivity">
<intent-filter android:order="1">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="example.com"
android:pathPattern="/.*"
android:scheme="https" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
我的ViewWxt.Kt
仍然没有变化:
package feature.extentions
import android.support.design.widget.Snackbar
import android.view.View
fun View.showSnackbar(msgId: Int, length: Int) {
showSnackbar(context.getString(msgId), length)
}
fun View.showSnackbar(msg: String, length: Int) {
showSnackbar(msg, length, null, {})
}
fun View.showSnackbar(
msgId: Int,
length: Int,
actionMessageId: Int,
action: (View) -> Unit
) {
showSnackbar(context.getString(msgId), length, context.getString(actionMessageId), action)
}
fun View.showSnackbar(
msg: String,
length: Int,
actionMessage: CharSequence?,
action: (View) -> Unit
) {
val snackbar = Snackbar.make(this, msg, length)
if (actionMessage != null) {
snackbar.setAction(actionMessage) {
action(this)
}.show()
}
}
我为'getLocation.Kt'创建了另一个文件,并且使用以下代码运行正常:
package feature.utilities
import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.location.Location
import android.support.design.widget.Snackbar
import android.view.View
import android.widget.TextView
import com.example.hasan.runtime.feature.PERMISSION_REQUEST_ALL
import com.example.hasan.runtime.feature.R
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
import feature.extensions.arePermissionsGranted
import feature.extensions.batchRequestPermissions
import feature.extensions.toast
import feature.extentions.showSnackbar
val PERMISSIONS =
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION)
private lateinit var fusedLocationClient: FusedLocationProviderClient
object UtilLocation {
fun getLocation(activity: Activity?, layout: View?, latitudeTxt: TextView?, longitudeTxt: TextView?) {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(activity!!)
if (activity!!.arePermissionsGranted(PERMISSIONS)) {
startLocation(activity, layout, latitudeTxt, longitudeTxt)
} else {
requestCameraPermission(activity, layout)
}
}
private fun requestCameraPermission(activity: Activity?, layout: View?) {
layout!!.showSnackbar(R.string.location_access_required,
Snackbar.LENGTH_INDEFINITE, R.string.ok) {
activity!!.batchRequestPermissions(PERMISSIONS, PERMISSION_REQUEST_ALL)
}
}
@SuppressLint("MissingPermission")
private fun startLocation(activity: Activity?, layout: View?, latitudeTxt: TextView?, longitudeTxt: TextView?) {
fusedLocationClient.lastLocation
.addOnSuccessListener { location : Location? ->
latitudeTxt!!.text = location!!.latitude.toString()
longitudeTxt!!.text = location!!.longitude.toString()
// Got last known location. In some rare situations this can be null.
activity!!.toast("lat: "+location!!.latitude.toString()+", long: "+location!!.longitude.toString())
}
}
}