How to download an image from jetpack compose in Kotlin? - kotlin

So in my app I am loading images using AsyncImage
#Compose
...
AsyncImage(model = link,
contentDescription = title,
...
And it loads the images in the app using jetpack compose. I've made a download button and when I click I want to download an image to the external storage with downloadManager.
...
val requestPermissionLauncher =
rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()
){ isGranted: Boolean ->
if(isGranted){
Log.i("Permission: ", "Granted")
}
else {
Log.i("Permission: ", "Denied")
}
}
IconButton(
onClick = {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
if(ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
{
// IF PERMISSION GRANTED DOWNLOAD IMAGE
fun downloading(link, title, context)
Toast.makeText(context, "Downloaded", Toast.LENGTH_SHORT).show()
}
else if(ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
{
//PERMISSION HAS NOT BEEN ASKED YET
requestPermissionLauncher.launch(
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
}
}
else{
// IF <= Build.VERSION_CODES.Q, NO NEED FOR PERMISSION
fun downloading(link, title, context)
Toast.makeText(context, "Downloaded", Toast.LENGTH_SHORT).show()
}
}) {
Icon(
Icons.Outlined.ArrowDropDown,
contentDescription = "Download Button",
)}
This is the function to download the image. But it doesn't do anything when I click the button. I have the permissions on the AndroidManifest.xml. I looked at my downloaded images and they are not there. The permission works fine and I'm not getting any errors. I just can't download the image.
fun downloading(imageLink:String, title:String, context: Context){
val request = DownloadManager.Request(Uri.parse(imageLink))
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE)
request.setTitle("Download")
request.setDescription("Downloading Image")
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,
"${System.currentTimeMillis()}")
val manager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
manager.enqueue(request)
}
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER" />

Related

Store full-size images using a FileProvider

I want to save an image in its full size. I use a file provider for this. I can take the picture, but I don't get any data in the onActivityResult function. The intent is null.
What am I doing wrong?
provider_path.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<root-path name="root" path="." />
</paths>
provider in AndroidManifest.xml:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.bkoubik.longlesstime.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_path"/>
</provider>
My Fragment Class:
fun capturePhoto(){
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
val fileUri:File = createImageFile();
val photoURI = FileProvider.getUriForFile(
requireActivity(),
"com.bkoubik.longlesstime.fileprovider",
fileUri
)
intent.putExtra( MediaStore.EXTRA_OUTPUT, photoURI )
startActivityForResult(intent,IMAGE_REQUEST)
}
private fun createImageFile(): File {
val wrapper = ContextWrapper(requireContext())
var photoFile = wrapper.getDir(IMAGE_DIRECTORY,Context.MODE_PRIVATE)
photoFile = File(photoFile,"${UUID.randomUUID()}.jpg")
return photoFile
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(requestCode == IMAGE_REQUEST && resultCode == Activity.RESULT_OK && data != null)
{
//data = null
val imgData = data.data!!
...
}
}
companion object {
private val IMAGE_DIRECTORY = "long_less"
}
Error:
java.lang.IllegalArgumentException: Failed to find configured root that contains /data/data/com.bkoubik.longlesstime/app_long_less/1219a0bd-c17e-4709-b880-1e4f549362f6.jpg
First of all, I'll strongly recommend you to use new contracts API which is also recommended by Google:
While the underlying startActivityForResult() and onActivityResult() APIs are available on the Activity class on all API levels, it is strongly recommended to use the Activity Result APIs introduced in AndroidX Activity and Fragment. (see Android docs)
Than, when photo was taken from GUI, I'm getting photo data from provider like this (it's my separate camera request Activity). Also, I'm using external cache directory because on my Android 10.0 device data folder is not accessible (see Android docs)
P.S. Take a note about grantUriPermission method call on photo URI
// URI for photo file
private lateinit var mPhotoUri : Uri
/// Photo file itself
private lateinit var mPhotoFile : File
// Camera permission request
private val mRequestCamera = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
// Camera permission request parse
when (result.resultCode) {
// Success
RESULT_OK -> {
// Photo request
mRequestPhoto.launch(mPhotoUri)
}
// No permisison
else -> {
// Close activity
finish()
}
}
}
// Photo request
private val mRequestPhoto = registerForActivityResult(ActivityResultContracts.TakePicture()) { result ->
// Check request result
when (result) {
// Success
true -> {
// Photo from media stream
val photoData = BitmapFactory.decodeStream(
contentResolver.openInputStream(mPhotoUri)
)
// Stream for photo save
val dataStream = ByteArrayOutputStream()
// Compress photo as JPEG of 90% quality
photoData.compress(
Bitmap.CompressFormat.JPEG,
90,
dataStream
)
// Coroutine to write photo
CoroutineScope(Dispatchers.Main).launch {
// Inside IO context
withContext(Dispatchers.IO) {
// File output stream
FileOutputStream(mPhotoFile).also { fileStream ->
// Write JPEG image data to file
fileStream.write(dataStream.toByteArray())
// Close JPEG image data stream
dataStream.close()
// Close file stream
fileStream.close()
}
}
}
// Done here - notify someone photo is ready
sendBroadcast(
Intent(
<Where/Whom to send>
).apply {
// Content provider URI
putExtra(
<Photo URI extra name>,
mPhotoUri
)
}
)
// Close activity
finish()
}
// Error
else -> {
// Close activity
finish()
}
}
}
// Activity onCreate method
#Override
override fun onCreate(savedInstanceState: Bundle?) {
// Parent method call
super.onCreate(savedInstanceState)
// Try
try {
// Create temporary file
mPhotoFile = File.createTempFile(
"<file prefix>",
"<file suffix>",
externalCacheDir
).apply {
// Make it writable
setWritable(true)
}
// Get file URI (Android M+ ?)
mPhotoUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// Trying to get provider (I send it to this Activity via Intent with extra "EXTRA_AUTHORITY")
intent?.extras?.getString("EXTRA_AUTHORITY")
?.let { authority ->
// For Android 7.0+ getting FileProvider
FileProvider.getUriForFile(
applicationContext,
authority,
mPhotoFile
)
// Else for Android 7.0 or lower
} ?: Uri.fromFile(mPhotoFile)
} else {
// Else for Android 7.0 or lower
Uri.fromFile(mPhotoFile)
}
// Permissions for URI itself
grantUriPermission(
packageName,
mPhotoUri,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
)
// Catch
} catch (e: Exception) {
// Stacktrace to logcat
e.printStackTrace()
// Close camera activity
finish()
}
// No camera permissions ?
if (!ActivityPermissionsCamera.hasPermissions(applicationContext)) {
// Intent for camera permissions
val permissionsIntent = Intent(
applicationContext,
<Permissions for Camera Activity>::class.java
).apply {
// New task
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
// Request permissions
mRequestCamera.launch(permissionsIntent)
} else {
// Camera launch
mRequestPhoto.launch(mPhotoUri)
}
}
And this is how I reques photo from camera:
// Photo pending intent
private fun createPendingIntentPhoto() : PendingIntent? {
// Runtime check - any camera ?!
if (!applicationContext.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) {
// No camera - no photo !!!
return null
}
// Intent flags
val intentFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PendingIntent.FLAG_IMMUTABLE or
PendingIntent.FLAG_UPDATE_CURRENT
} else {
PendingIntent.FLAG_UPDATE_CURRENT
}
// Pending intent
return PendingIntent.getActivity(
applicationContext,
1,
Intent(
applicationContext,
<Activity for Camera>::class.java
).apply {
// Pass provider as Intent extra
putExtra("EXTRA_AUTHORITY", "${BuildConfig.APPLICATION_ID}.provider")
},
intentFlags
)
}
P.P.S. Quick note on why do I pass provider URI over Intent's extra - my camera routines are in separate library which is used in GUI-project So they can have different BuildConfig.APPLICATION_ID. This allows me to use same library in many projects.

ActivityResultContracts TakePicture it is always returning false as a result

I'm using Jetpack Compose, and when I call the method to take a picture with the camera, the result of ActivityResultContracts.TakePicture is always false.
Sample code:
#OptIn(ExperimentalPermissionsApi::class)
#Composable
fun SomeScreen() {
val photoUri by remember { mutableStateOf(value = Uri.EMPTY) }
val cameraLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.TakePicture(),
onResult = { success ->
if (success) {
println("success")
println("photo uri: $photoUri")
} else println("result failed")
}
)
val cameraPermissionState = rememberPermissionState(
permission = Manifest.permission.CAMERA,
onPermissionResult = { granted ->
if (granted) cameraLauncher.launch(photoUri)
else print("camera permission is denied")
}
)
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(onClick = cameraPermissionState::launchPermissionRequest) {
Text(text = "Take a photo with Camera")
}
}
}
I used the accompanist-permissions library to make it easier, the part of opening the camera app and taking the photo is apparently working normally, but the result from cameraLauncher is always false...
Can anyone guide me to solve this problem?
The problem with your code is that you are passing an empty Uri to launch, and the Camera app can't save the image in that Uri. If you open the TakePicture class or place the mouse cursor over it, you will see the following information:
An ActivityResultContract to take a picture saving it into the
provided content-Uri. Returns true if the image was saved into the
given Uri.
In other words, the TakePicture class will not automatically create a File for you, you will have to create a File yourself and provide the Uri.
I'll assume a simple scenario where you want to take a photo for some temporary task within the app. To achieve this goal, you need to understand some steps that are missing in your code:
As you need to create a File and expose it to the Camera app, you need to create rules with the File Provider and declare it in the Manifest file.
The function that creates a File and exposes its Uri with the FileProvider.
Lets start with file_paths.xml (inside res/xml):
<?xml version="1.0" encoding="utf-8"?>
<paths>
<cache-path
name="cache_pictures"
path="/" />
</paths>
I'm using cache-path here following the idea of keeping the files temporarily.
In the Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.CAMERA" />
<application ...>
<activity .../>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
</application>
</manifest>
Extension to create a File and return a Uri:
fun Context.createTempPictureUri(
provider: String = "${BuildConfig.APPLICATION_ID}.provider",
fileName: String = "picture_${System.currentTimeMillis()}",
fileExtension: String = ".png"
): Uri {
val tempFile = File.createTempFile(
fileName, fileExtension, cacheDir
).apply {
createNewFile()
}
return FileProvider.getUriForFile(applicationContext, provider, tempFile)
}
The cache folder is being used in this example with cacheDir. If changing here to filesDir, be sure to change in the cache-path on file_paths.xml to files-path.
Now in Composable Screen you can have something like this:
#OptIn(ExperimentalPermissionsApi::class)
#Composable
fun SomeScreen() {
val context = LocalContext.current
var currentPhotoUri by remember { mutableStateOf(value = Uri.EMPTY) }
var tempPhotoUri by remember { mutableStateOf(value = Uri.EMPTY) }
val cameraLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.TakePicture(),
onResult = { success ->
if (success) currentPhotoUri = tempPhotoUri
}
)
val cameraPermissionState = rememberPermissionState(
permission = Manifest.permission.CAMERA,
onPermissionResult = { granted ->
if (granted) {
tempPhotoUri = context.createTempPictureUri()
cameraLauncher.launch(tempPhotoUri)
} else print("camera permission is denied")
}
)
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
AnimatedVisibility(visible = currentPhotoUri.toString().isNotEmpty()) {
// from coil library
AsyncImage(
modifier = Modifier.size(size = 240.dp),
model = currentPhotoUri,
contentDescription = null
)
}
Button(onClick = cameraPermissionState::launchPermissionRequest) {
Text(text = "Take a photo with Camera")
}
}
}

Kotlin app using camera does not return picture if camera is never launched before

I've stuck for a while with annoying issue with emulator's camera in my app. (The same is repro on a real device)
The camera is used from a dialog fragment to take a picture that later will be uploaded to remote host.
private val cameraPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted ->
if (isGranted) {
makeImageWithCamera()
} else {
dismiss()
}
}
private val cameraLauncher = registerForActivityResult(
ActivityResultContracts.TakePicture()
) { isSuccess ->
if (isSuccess) {
path?.let { path ->
viewModel.setPhoto(path = path)
}
}
dismiss()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
subscribeFlow(viewModel.action) { dismiss() }
with(binding) {
buttonCamera.setOnClickListener { useCamera() }
buttonCancel.setOnClickListener { dismiss() }
}
}
private fun useCamera() {
val isGranted = ContextCompat.checkSelfPermission(requireContext(), PERM_CAMERA) ==
PackageManager.PERMISSION_GRANTED
if (!isGranted) {
cameraPermissionLauncher.launch(PERM_CAMERA)
} else {
makeImageWithCamera()
}
}
private fun makeImageWithCamera() {
try {
val photoFileName = "photo${id}"
val photosDir = requireContext()
.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
val photoFile = File.createTempFile(photoFileName, ".jpg", photosDir)
val photoUri: Uri = FileProvider.getUriForFile(
requireContext(),
"app.provider",
photoFile
)
path = photoFile.absolutePath
cameraLauncher.launch(photoUri)
} catch (err : IOException) {
Log.e(TAG, err.stackTraceToString())
}
}
The issue happens only in situation when camera itself is never launched on a device:
Inside my app I press camera button
Receive a request for camera usage permission from my app and accept it.
Camera app is starting and requests its own permission to access geolocation (it wants to add location-based tags to photos) - at this point it is irrelevant wether to accept or deny it.
Camera enters the scene. Now if I press shot button it makes a photo and stays in the scene allowing to make infinite amount of photos, as if I've launched Camera app in regular way.
If I use back button to return to my app - nothing have change at all, dialog is just dismisses.
If I launch the same second time, or just launch Camera app itself and accept/deny permissions request from it, all is fixed. Camera takes exactly one shot and allows me to accept it, after that it comes back to my app and processes received photo.
So while for the user experience this behaviour can be just annoying, it with a high probability makes the Firebase robotests to fail on this point.
What could be the possible root of a problem?

I am trying to create a camera app and i having problem with the capture button. When i click on the button it not working

I have tried much code for takephoto function but still not working please help.
val photofile =
File(externalMediaDirs.firstOrNull(), "CameraX - ${System.currentTimeMillis()}.jpg")
val output = ImageCapture.OutputFileOptions.Builder(photofile).build()
imageCapture?.takePicture(
output, ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageSavedCallback {
override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
Toast.makeText(applicationContext,"Image Capture Succesfully",Toast.LENGTH_LONG).show()
}
override fun onError(exception: ImageCaptureException) {
Toast.makeText(applicationContext,"Image Capture Failed!",Toast.LENGTH_LONG).show()
}
}
)
check if u have permission to take a photo and to save file in the storage:
In AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
And then request permissions, for example:
try {
ActivityCompat.requestPermissions(this#MainActivity, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 123)
if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
/* YOUR CODE HERE */
}
} catch (e: Exception) {
e.printStackTrace()
}

What's the right way to get permissions for phone call intent

How to request permissions using Kotlin.
I am trying to make a phone call function
fun buChargeEvent(view: View){
var number: Int = txtCharge.text.toString().toInt()
val intentChrage = Intent(Intent.ACTION_CALL)
intent.data = Uri.parse("tel:$number")
startActivity(intentChrage)
}
I added user permissions in manifest
but still having the same
error .
You need to add permission to your manifest first
<uses-permission android:name="android.permission.CALL_PHONE" />
After permission added in manifest following code would work fine for you "Number_to_call" will be youe number that is need to be replaced
val call = Intent(Intent.ACTION_DIAL)
call.setData(Uri.parse("tel:" +"Number_to_call"))
startActivity(call)
You need to add the run time permission. Download the source code from here
//Click function of layout:
rl_call.setOnClickListener {
if (boolean_call) {
phonecall()
}else {
fn_permission(Manifest.permission.CALL_PHONE,CALLMODE)
}
}
// Request permission response
fun fn_permission(permission:String,mode:Int){
requestPermissions(permission, object : PermissionCallBack {
override fun permissionGranted() {
super.permissionGranted()
Log.v("Call permissions", "Granted")
boolean_call=true
phonecall()
}
override fun permissionDenied() {
super.permissionDenied()
Log.v("Call permissions", "Denied")
boolean_call=false
}
})
}
// function to call intent
fun phonecall() {
val intent = Intent(Intent.ACTION_CALL);
intent.data = Uri.parse("tel:1234567890s")
startActivity(intent)
}
Thanks!
First you need to add permission to your manifest first :
<uses-permission android:name="android.permission.CALL_PHONE" />
This bit of code is used on the place of your method :
fun buChargeEvent(view: View) {
var number: Int = txtCharge.text.toString().toInt()
val callIntent = Intent(Intent.ACTION_CALL)
callIntent.data = Uri.parse("tel:$number")
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this as Activity,
Manifest.permission.CALL_PHONE)) {
} else {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.CALL_PHONE),
MY_PERMISSIONS_REQUEST_CALL_PHONE)
}
}
startActivity(callIntent)
}
You need to request the runtime permission, since Android 6.0 certain permissions require you to ask at install and again at runtime.
Following the instructions here explains how to ask for permission at runtime.
This is the complete code for runtime permissions for Call Phone
Step 1:- add permission in manifest
<uses-permission android:name="android.permission.CALL_PHONE" />
Step 2:- Call this method checkAndroidVersion() in onCreate()
fun checkAndroidVersion() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkAndRequestPermissions()) {
} else {
}
} else {
// do code for pre-lollipop devices
}
}
val REQUEST_ID_MULTIPLE_PERMISSIONS = 1
fun checkAndRequestPermissions(): Boolean {
val call = ContextCompat.checkSelfPermission(this#MainActivity, Manifest.permission.CALL_PHONE)
val listPermissionsNeeded = ArrayList<String>()
if (call != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.CALL_PHONE)
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this#MainActivity, listPermissionsNeeded.toTypedArray(), REQUEST_ID_MULTIPLE_PERMISSIONS)
return false
}
return true
}
fun checkAndRequestPermissions(): Boolean {
val call = ContextCompat.checkSelfPermission(this#MainActivity, Manifest.permission.CALL_PHONE)
val listPermissionsNeeded = ArrayList<String>()
if (call != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.CALL_PHONE)
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this#MainActivity, listPermissionsNeeded.toTypedArray(), REQUEST_ID_MULTIPLE_PERMISSIONS)
return false
}
return true
}
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>, grantResults: IntArray) {
Log.d("in fragment on request", "Permission callback called-------")
when (requestCode) {
REQUEST_ID_MULTIPLE_PERMISSIONS -> {
val perms = HashMap<String, Int>()
// Initialize the map with both permissions
perms[Manifest.permission.CALL_PHONE] = PackageManager.PERMISSION_GRANTED
// Fill with actual results from user
if (grantResults.size > 0) {
for (i in permissions.indices)
perms[permissions[i]] = grantResults[i]
// Check for both permissions
if (perms[Manifest.permission.CALL_PHONE] == PackageManager.PERMISSION_GRANTED
) {
print("Storage permissions are required")
// process the normal flow
//else any one or both the permissions are not granted
} else {
Log.d("in fragment on request", "Some permissions are not granted ask again ")
//permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
// // shouldShowRequestPermissionRationale will return true
//show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
if (ActivityCompat.shouldShowRequestPermissionRationale(this#MainActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE) || ActivityCompat.shouldShowRequestPermissionRationale(this#MainActivity, Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this#MainActivity, Manifest.permission.READ_EXTERNAL_STORAGE) || ActivityCompat.shouldShowRequestPermissionRationale(this#MainActivity, Manifest.permission.ACCESS_FINE_LOCATION)) {
showDialogOK("Call permission is required for this app",
DialogInterface.OnClickListener { dialog, which ->
when (which) {
DialogInterface.BUTTON_POSITIVE -> checkAndRequestPermissions()
DialogInterface.BUTTON_NEGATIVE -> {
}
}// proceed with logic by disabling the related features or quit the app.
})
} else {
Toast.makeText(this#MainActivity, "Go to settings and enable permissions", Toast.LENGTH_LONG)
.show()
// //proceed with logic by disabling the related features or quit the app.
}//permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
}
}
}
}
}
fun showDialogOK(message: String, okListener: DialogInterface.OnClickListener) {
AlertDialog.Builder(this#MainActivity)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show()
}
**Step 3**:- On button click
fun buChargeEvent(view: View){
if(checkAndRequestPermissions(){
var number: Int = txtCharge.text.toString().toInt()
val intentChrage = Intent(Intent.ACTION_CALL)
intent.data = Uri.parse("tel:$number")
startActivity(intentChrage)
}
}