My activity RequiresLocation is to request permission to location services.
Here's the code:
import android.content.pm.PackageManager
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.widget.Button
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_requires_location.*
import java.util.jar.Manifest
class RequiresLocation : AppCompatActivity() {
val requestCode: Int = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_requires_location)
turnOnLocationButton.setOnClickListener {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission has already been granted", Toast.LENGTH_SHORT).show()
}
else {
requestLocationPermission()
}
}
}
}
private fun requestLocationPermission(): {
ActivityCompat.requestPermissions(
RequiresLocation.class,
arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
requestCode) // coming up in red
}
however the requestcode is coming up in red on Android Studio as unresolved reference. How come I can't pass it in? - is it because it's a private variable?
I'm following the official android tutorial for requestPermissions()
Use this#RequiresLocation instead of RequiresLocation.class
Try this
ActivityCompat.requestPermissions(
this#RequiresLocation,
arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
requestCode)
Or
private fun requestLocationPermission() {
ActivityCompat.requestPermissions(
this,
arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
requestCode) // coming up in red
}
UPDATE
class RequiresLocation : AppCompatActivity() {
val requestCode: Int = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_requires_location)
turnOnLocationButton.setOnClickListener {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission has already been granted", Toast.LENGTH_SHORT).show()
}
else {
requestLocationPermission()
}
}
}
private fun requestLocationPermission() {
ActivityCompat.requestPermissions(
this,
arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
requestCode) // coming up in red
}
}
Related
I would like to create a custom ActivityResultContract to request both coarse and fine location that has a custom response.
class LocationPermission : ActivityResultContract<Void?, LocationPermissionResult>() {
override fun createIntent(context: Context, input: Array<String>): Intent {
val requestPermissions = arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
return Intent(ActivityResultContracts.RequestMultiplePermissions.ACTION_REQUEST_PERMISSIONS)
.putExtra(ActivityResultContracts.RequestMultiplePermissions.EXTRA_PERMISSIONS, requestPermissions)
}
...
}
Calling that from an activity:
private val reportLocationIntent = registerForActivityResult(LocationPermission()) { result ->
}
...
reportLocationIntent.launch()
However when doing so createIntent is never called. What am I doing wrong?
Your code in question has compilation errors, however this approach seems to work. I don't really know what the "custom response" should be from the question directly, so I've created a class called class LocationPermissionResult(val granted: Boolean) based on your question. It is mostly compiled from RequestMultiplePermissions from ActivityResultContracts.
Tested on API 30 and API 33 emulator, the permission dialog opens and the returned result is correct as well. (Make sure the permissions are added to AndroidManifest.xml)
Here is the source code:
class LocationPermission : ActivityResultContract<Void?, LocationPermissionResult>() {
private val permissions = arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
override fun createIntent(context: Context, input: Void?): Intent {
return Intent(ActivityResultContracts.RequestMultiplePermissions.ACTION_REQUEST_PERMISSIONS).putExtra(
ActivityResultContracts.RequestMultiplePermissions.EXTRA_PERMISSIONS, permissions)
}
override fun getSynchronousResult(context: Context,
input: Void?): SynchronousResult<LocationPermissionResult>? {
val allGranted = permissions.all { permission ->
ContextCompat.checkSelfPermission(
context,
permission
) == PackageManager.PERMISSION_GRANTED
}
return if (allGranted) {
SynchronousResult(LocationPermissionResult(true))
} else null
}
override fun parseResult(resultCode: Int, intent: Intent?): LocationPermissionResult {
if (resultCode != Activity.RESULT_OK) return LocationPermissionResult(false)
if (intent == null) return LocationPermissionResult(false)
val grantResults = intent.getIntArrayExtra(
ActivityResultContracts.RequestMultiplePermissions.EXTRA_PERMISSION_GRANT_RESULTS)
return LocationPermissionResult(grantResults?.all { it == PackageManager.PERMISSION_GRANTED } == true)
}
}
class LocationPermissionResult(val granted: Boolean)
this is my solution to request both coarse and fine location, i hope this will do the job
object Permission {
private const val REQUEST_CODE_PERMISSION: Int = 1
#SuppressLint("ObsoleteSdkInt")
fun isGrantedLocationPermission(context: Context): Boolean {
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
true
} else {
context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED ||
context.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
}
fun grantLocationPermission(context: Context) {
val permissions = arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
(context as MainActivity).requestPermissions(permissions, REQUEST_CODE_PERMISSION)
}
}
Use it from MainActivity:
override fun onCreate(savedInstanceState: Bundle?) {
...
val button = findViewById<Button>(R.id.btnGetLocation)
button.setOnClickListener {
getLocation()
}
}
private fun getLocation() {
//check if permission isnt granted:
if (!Permission.isGrantedLocationPermission(this))
Permission.grantLocationPermission(this)
else {
...
}
}
//Check if user give permission or not:
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//permission granted
} else {
//permission denied
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
import android.Manifest
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.Looper
import android.util.Log
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.android.gms.location.*
#RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
class DeviceScanActivity : AppCompatActivity() {
//Getting BluetoothAdapter from BluetoothManager
private fun PackageManager.missingSystemFeature(name: String): Boolean = !hasSystemFeature(name)
private var fusedLocationProvider: FusedLocationProviderClient? = null
private val locationRequest: LocationRequest = LocationRequest.create().apply {
interval = 30
fastestInterval = 10
priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
maxWaitTime= 60
}
private var locationCallback: LocationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
val locationList = locationResult.locations
if (locationList.isNotEmpty()) {
val location = locationList.last()
Toast.makeText(this#DeviceScanActivity, "Got Location: " + location.toString(), Toast.LENGTH_LONG).show()
}
}
}
private val bluetoothAdapter: BluetoothAdapter? by lazy(LazyThreadSafetyMode.NONE) {
val bluetoothManager = getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
bluetoothManager.adapter
}
companion object {
const val TAG: String = "Log"
private const val MY_PERMISSIONS_REQUEST_LOCATION = 99
}
private val BluetoothAdapter.isDisabled: Boolean get() = !isEnabled
private val REQUEST_ENABLE_BT = 1000
//On memory
#RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "DeviceScanActivity()")
fusedLocationProvider = LocationServices.getFusedLocationProviderClient(this)
checkLocationPermission()
packageManager.takeIf {
it.missingSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
}?.also {
Toast.makeText(this, "R.string.ble_not_supported", Toast.LENGTH_SHORT).show()
finish()
}
bluetoothAdapter?.takeIf { it.isDisabled }?.apply {
val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
}
finish()
}
override fun onResume() {
super.onResume()
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
fusedLocationProvider?.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
}
}
override fun onPause() {
super.onPause()
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
fusedLocationProvider?.removeLocationUpdates(locationCallback)
}
}
private fun checkLocationPermission() {
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
if(ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.ACCESS_FINE_LOCATION
)
) {
AlertDialog.Builder(this)
.setTitle("Location Permission Needed")
.setMessage("This app needs the Location permission, please accept to use location functionality")
.setPositiveButton(
"OK"
) { _, _ ->
//Prompt the user once explanation has been shown
requestLocationPermission()
}
.create()
.show()
} else {
requestLocationPermission()
}
}
}
private fun requestLocationPermission() {
Log.d(TAG, "requestLocationPermission()")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION
),
MY_PERMISSIONS_REQUEST_LOCATION
)
} else {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
MY_PERMISSIONS_REQUEST_LOCATION
)
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
Log.d(TAG, "result()")
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
MY_PERMISSIONS_REQUEST_LOCATION -> {
// If request is cancelled, the result arrays are empty.
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
fusedLocationProvider?.requestLocationUpdates(
locationRequest,
locationCallback,
Looper.getMainLooper()
)
}
} else {
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show()
}
return
}
}
}
}
To use BLE observing and advertising, I have granted permission at Manifests and also trying to request at runtime manually.
However, my code doesn't look like it is calling onRequestPermissionResult, as it doesn't show "result()" on LogCat, and the advertising/observing is not working properly. What is the problem of my code?
I am trying to place an image from internal storage into the background of a button. There are no error messages. I can open the storage on the emulated device and select and image, but it doesn't get placed/inserted into the button background. I am using Android 4.1 and using API Level 30 (Q) / Android 11. I am coding in Kotlin.
The Log says the photo is selected.
The code in question is this:
RegisterActivity.kt --partial--
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(requestCode == 0 && resultCode == RESULT_OK && data != null){
// proceed and check what the selected image was...
Log.d("RegisterActivity", "Photo was selected")
val uri = data.data
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, uri)
val bitmapDrawable = BitmapDrawable(bitmap)
select_photo_button_register.setBackgroundDrawable(bitmapDrawable)
select_photo_button_register.text = ""
}
}
RegisterActivity.kt --FULL--
package <censored>.kotlinmessenger
import android.content.Intent
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.ActionBar
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.auth.FirebaseAuth
import kotlinx.android.synthetic.main.activity_register.*
class RegisterActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_register)
this.supportActionBar?.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
supportActionBar?.setDisplayShowCustomEnabled(true)
supportActionBar?.setCustomView(R.layout.custom_action_bar)
//getSupportActionBar().setElevation(0);
register_button_register.setOnClickListener {
performRegister()
}
already_have_account_textView.setOnClickListener {
Log.d("RegisterActivity", "Trying to show login activity.")
val intent = Intent(this, LoginActivity::class.java)
startActivity(intent)
}
select_photo_button_register.setOnClickListener {
Log.d("RegisterActivity", "Try to show photo selector")
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
startActivityForResult(intent, 0)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(requestCode == 0 && resultCode == RESULT_OK && data != null){
// proceed and check what the selected image was...
Log.d("RegisterActivity", "Photo was selected")
val uri = data.data
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, uri)
val bitmapDrawable = BitmapDrawable(bitmap)
select_photo_button_register.setBackgroundDrawable(bitmapDrawable)
select_photo_button_register.text = ""
}
}
private fun performRegister() {
val email = email_editText_register.text.toString()
val password = password_editText_register.text.toString()
if (email.isEmpty() || password.isEmpty()) {
Toast.makeText(this, "Please check email/password", Toast.LENGTH_SHORT).show()
return
}
Log.d("RegisterActivity", "Email: $email")
Log.d("RegisterActivity", "Password: $password")
//Firebase Auth
FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password)
.addOnCompleteListener {
if (!it.isSuccessful) return#addOnCompleteListener
// else if successful
val uid = it.result?.user?.uid
Log.d("RegisterActivity", "Successfully created user with uid: $uid")
println("Email: $email\n Password: $password\n UID: $uid")
}
.addOnFailureListener {
Log.d("Main", "Failed to create user: ${it.message}")
Toast.makeText(this, "Failed to create user: ${it.message}", Toast.LENGTH_SHORT)
.show()
}
}
}
activity_register.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="#86B400"
tools:context=".RegisterActivity" >
<EditText
android:id="#+id/username_editText_register"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="36dp"
android:layout_marginLeft="36dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="36dp"
android:layout_marginRight="36dp"
android:background="#drawable/rounded_edittext"
android:ems="10"
android:hint="Username"
android:inputType="textPersonName"
android:paddingLeft="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/select_photo_button_register" />
<EditText
android:id="#+id/email_editText_register"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginTop="8dp"
android:background="#drawable/rounded_edittext"
android:ems="10"
android:hint="Email"
android:inputType="textEmailAddress"
android:paddingLeft="16dp"
app:layout_constraintEnd_toEndOf="#+id/username_editText_register"
app:layout_constraintStart_toStartOf="#+id/username_editText_register"
app:layout_constraintTop_toBottomOf="#+id/username_editText_register" />
<EditText
android:id="#+id/password_editText_register"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginTop="8dp"
android:background="#drawable/rounded_edittext"
android:ems="10"
android:hint="Password"
android:inputType="textPassword"
android:paddingLeft="16dp"
app:layout_constraintEnd_toEndOf="#+id/email_editText_register"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="#+id/email_editText_register"
app:layout_constraintTop_toBottomOf="#+id/email_editText_register"
/>
<Button
android:id="#+id/register_button_register"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="#drawable/rounded_edittext"
android:text="Register"
app:backgroundTint="#android:color/holo_green_dark"
app:layout_constraintEnd_toEndOf="#+id/password_editText_register"
app:layout_constraintStart_toStartOf="#+id/password_editText_register"
app:layout_constraintTop_toBottomOf="#+id/password_editText_register" />
<TextView
android:id="#+id/already_have_account_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Do you already have an account?"
android:textColor="#FFFFFF"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="#+id/register_button_register"
app:layout_constraintStart_toStartOf="#+id/register_button_register"
app:layout_constraintTop_toBottomOf="#+id/register_button_register" />
<Button
android:id="#+id/select_photo_button_register"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_marginTop="32dp"
android:background="#drawable/rounded_select_photo"
android:text="Select photo"
android:textColor="#color/black"
app:backgroundTint="bitmapDrawable"
app:layout_constraintBottom_toTopOf="#+id/username_editText_register"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
RegisterActivity with External Storage permission
package <censroed>.kotlinmessenger
import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.ImageDecoder
import android.graphics.drawable.BitmapDrawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.storage.FirebaseStorage
import kotlinx.android.synthetic.main.activity_register.*
import java.util.*
class RegisterActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_register)
register_button_register.setOnClickListener {
performRegister()
}
already_have_account_textView.setOnClickListener {
Log.d("RegisterActivity", "Trying to show login activity.")
val intent = Intent(this, LoginActivity::class.java)
startActivity(intent)
}
select_photo_button_register.setOnClickListener {
Log.d("RegisterActivity", "Try to show photo selector")
val galleryIntent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(galleryIntent, 0)
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
startActivityForResult(intent, 0)
}
}
var selectedPhotoUri: Uri? = null
#RequiresApi(Build.VERSION_CODES.P)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (ContextCompat.checkSelfPermission(this#RegisterActivity,
Manifest.permission.READ_EXTERNAL_STORAGE) !==
PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this#RegisterActivity,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
ActivityCompat.requestPermissions(this#RegisterActivity,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1)
} else {
ActivityCompat.requestPermissions(this#RegisterActivity,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1)
}
}
selectedPhotoUri = data?.data
// val source = ImageDecoder.createSource(this.contentResolver, selectedPhotoUri!!)
// val bitmap = ImageDecoder.decodeBitmap(source)
//// select_photo_button_register.setBackgroundDrawable(BitmapDrawable(this.resources, bitmap))
// select_photo_button_register.background = BitmapDrawable(resources, bitmap)
// try {
// selectedPhotoUri?.let {{
// val source = ImageDecoder.createSource(this.contentResolver, selectedPhotoUri!!)
// val bitmap = ImageDecoder.decodeBitmap(source)
//
// }
// select_photo_button_register.setBackgroundDrawable(BitmapDrawable(this.resources, bitmap))
//
// }
// } catch (e: Exception) {
// e.printStackTrace()
// }
// if (requestCode == 0 && resultCode == Activity.RESULT_OK && data != null){
// Log.d("RegisterActivity", "Photo was selected")
//
// selectedPhotoUri = data.data
// val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, selectedPhotoUri)
// val bitmapDrawable = BitmapDrawable(bitmap)
// select_photo_button_register.setBackgroundDrawable(bitmapDrawable)
// }
}
#RequiresApi(Build.VERSION_CODES.P)
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
grantResults: IntArray) {
when (requestCode) {
1 -> {
if (grantResults.isNotEmpty() && grantResults[0] ==
PackageManager.PERMISSION_GRANTED) {
if ((ContextCompat.checkSelfPermission(this#RegisterActivity,
Manifest.permission.ACCESS_FINE_LOCATION) ===
PackageManager.PERMISSION_GRANTED)) {
Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show()
val source = ImageDecoder.createSource(this.contentResolver, selectedPhotoUri!!)
val bitmap = ImageDecoder.decodeBitmap(source)
// select_photo_button_register.setBackgroundDrawable(BitmapDrawable(this.resources, bitmap))
select_photo_button_register.background = BitmapDrawable(resources, bitmap)
}
} else {
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show()
}
return
}
}
}
private fun performRegister() {
val email = email_editText_register.text.toString()
val password = password_editText_register.text.toString()
if (email.isEmpty() || password.isEmpty()) {
Toast.makeText(this, "Please check email/password", Toast.LENGTH_SHORT).show()
return
}
Log.d("RegisterActivity", "Email: $email")
Log.d("RegisterActivity", "Password: $password")
//Firebase Auth
FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password)
.addOnCompleteListener {
if (!it.isSuccessful) return#addOnCompleteListener
// else if successful
val uid = it.result?.user?.uid
Log.d("RegisterActivity", "Successfully created user with uid: $uid")
uploadImageToFirebase()
}
.addOnFailureListener {
Log.d("RegisterActivity", "Failed to create user: ${it.message}")
Toast.makeText(this, "Failed to create user: ${it.message}", Toast.LENGTH_SHORT)
.show()
}
}
private fun uploadImageToFirebase() {
if (selectedPhotoUri == null) return
val filename = UUID.randomUUID().toString()
val ref = FirebaseStorage.getInstance().getReference("/images/$filename")
ref.putFile(selectedPhotoUri!!).addOnSuccessListener {
Log.d("RegisterActivity", "Sucessfully uploaded image: ${it.metadata?.path}")
}
}
}
Try using this since MediaStore.Images.Media.getBitmap() is depreceated.
try {
uri?.let {
if(Build.VERSION.SDK_INT < 28) {
val bitmap = MediaStore.Images.Media.getBitmap(
this.contentResolver,
uri
)
} else {
val source = ImageDecoder.createSource(this.contentResolver, uri)
val bitmap = ImageDecoder.decodeBitmap(source)
}
select_photo_button_register.setBackgroundDrawable(new BitmapDrawable(context.getResources(), bitmap));
}
} catch (e: Exception) {
e.printStackTrace()
}
Try this. Replace these two lines:
val bitmapDrawable = BitmapDrawable(bitmap)
select_photo_button_register.setBackgroundDrawable(bitmapDrawable)
with this:
select_photo_button_register.background = BitmapDrawable(resources, bitmap)
I fixed it. I changed the Button to an ImageView and added a TextView over it. I am using Picasso to insert it into the ImageView.
The onActivityResult deals with inserting the image.
Permissions code obtained from here
package <censored>.kotlinmessenger
import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.auth.FirebaseAuth
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.activity_register.*
class RegisterActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_register)
register_button_register.setOnClickListener {
performRegister()
}
already_have_account_textView.setOnClickListener {
Log.d("RegisterActivity", "Trying to show login activity.")
val intent = Intent(this, LoginActivity::class.java)
startActivity(intent)
}
//BUTTON CLICK
select_photo_imageView_register.setOnClickListener {
//check runtime permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_DENIED
) {
//permission denied
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show()
val permissions = arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)
//show popup to request runtime permission
requestPermissions(permissions, PERMISSION_CODE)
} else {
//permission already granted
Toast.makeText(this, "Permission already granted", Toast.LENGTH_SHORT).show()
pickImageFromGallery()
}
} else {
//system OS is < Marshmallow
pickImageFromGallery()
}
}
}
private fun pickImageFromGallery() {
//Intent to pick image
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
startActivityForResult(intent, IMAGE_PICK_CODE)
}
companion object {
//image pick code
private val IMAGE_PICK_CODE = 1000
//Permission code
private val PERMISSION_CODE = 1001
}
//handle requested permission result
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
when (requestCode) {
PERMISSION_CODE -> {
if (grantResults.size > 0 && grantResults[0] ==
PackageManager.PERMISSION_GRANTED
) {
//permission from popup granted
Toast.makeText(this, "Permission from popup granted", Toast.LENGTH_SHORT).show()
pickImageFromGallery()
} else {
//permission from popup denied
Toast.makeText(this, "Permission from popup denied", Toast.LENGTH_SHORT).show()
}
}
}
}
//handle result of picked image
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && requestCode == IMAGE_PICK_CODE && data != null) {
Picasso.get()
.load(data.data)
.fit()
.centerCrop()
.into(select_photo_imageView_register)
select_photo_textView_register.text = ""
}
}
private fun performRegister() {
val email = email_editText_register.text.toString()
val password = password_editText_register.text.toString()
if (email.isEmpty() || password.isEmpty()) {
Toast.makeText(this, "Please check email/password", Toast.LENGTH_SHORT).show()
return
}
Log.d("RegisterActivity", "Email: $email")
Log.d("RegisterActivity", "Password: $password")
//Firebase Auth
FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password)
.addOnCompleteListener {
if (!it.isSuccessful) return#addOnCompleteListener
// else if successful
val uid = it.result?.user?.uid
Log.d("RegisterActivity", "Successfully created user with uid: $uid")
// uploadImageToFirebase()
}
.addOnFailureListener {
Log.d("RegisterActivity", "Failed to create user: ${it.message}")
Toast.makeText(this, "Failed to create user: ${it.message}", Toast.LENGTH_SHORT)
.show()
}
}
}
**Halo I need a little help, so you can see there are 2 button create but I run the app by emulator it only work for the button create for asking the permission , but its not going to Activity 2,any can suggest for 2nd button to work? Am I need using override fun?
**
package com.example.preludeprototpe
import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.core.app.ActivityCompat
import kotlinx.android.synthetic.main.activity1.*
class Activity1 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity1)
// Its a buutton for go to the Activity 2,but its not working
btncreate.setOnClickListener {
Intent(this, Activity2::class.java).also {
startActivity(it)
}
}
// function for asking permission but its the only one worked
btncreate.setOnClickListener {
requestpermisson()
}
//button for go to Activity 3
btnlogin.setOnClickListener {
Intent(this, Activity3::class.java).also {
startActivity(it)
}
}
}
// function for permission
private fun writeExternalStorage() =
ActivityCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
private fun permissionInternet() =
ActivityCompat.checkSelfPermission(this, Manifest.permission.INTERNET) ==
PackageManager.PERMISSION_GRANTED
private fun permissionCamera() =
ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) ==
PackageManager.PERMISSION_GRANTED
private fun permissionExternal() =
ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED
private fun requestpermisson() {
val permissionToRequest = mutableListOf<String>()
if (!writeExternalStorage()) {
permissionToRequest.add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
if (!permissionInternet()) {
permissionToRequest.add(Manifest.permission.INTERNET)
}
if (!permissionCamera()) {
permissionToRequest.add(Manifest.permission.CAMERA)
}
if (!permissionExternal()) {
permissionToRequest.add(Manifest.permission.CAMERA)
}
if(permissionToRequest.isNotEmpty()){
ActivityCompat.requestPermissions(this,permissionToRequest.toTypedArray(),0)
}
}
// fun for permission
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if(requestCode == 0 && grantResults.isNotEmpty()) {
for(i in grantResults.indices) {
if(grantResults[i] == PackageManager.PERMISSION_GRANTED) {
Log.d("PermissionRequest","${permissions[i]} granted")
}
}
}
}
}
Tried this
// Its a buutton for go to the Activity 2,but its not working
btncreate.setOnClickListener {
requestpermisson()
val intent = Intent(this, Activity2::class.java)
startActivity(intent)
}
//button for go to Activity 3
btnlogin.setOnClickListener {
val intent = Intent(this, Activity3::class.java)
startActivity(intent)
}
}
Instead of create new
btncreate
you could merge
requestpermission()
in first one
When I overriding function onRequestPermissionsResult is not working.
When I remove the override command Android Studio don't complain anymore but the function remains useless...
I'm requesting permissions for ACCES_FINE_LOCATION
The error message is
Modifier 'override' is not applicable to 'local function'
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
val texto = TextView(this)
val ID_REQUISICAO_ACCESS_FINE = 1
setContentView(texto)
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
ID_REQUISICAO_ACCESS_FINE -> {
// If request is cancelled, the result arrays are empty.
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the location-related task you need to do.
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "permission granted", Toast.LENGTH_LONG).show()
}
} else {
// permission denied, boo! Disable the functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show()
}
return
}
}
}
}
}
You have onRequestPermissionsResult as overriden method of class, not local function of onCreate method. So, just close onCreate method before starting onRequestPermissionsResult one:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
val texto = TextView(this)
val ID_REQUISICAO_ACCESS_FINE = 1
setContentView(texto)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
ID_REQUISICAO_ACCESS_FINE -> {
// If request is cancelled, the result arrays are empty.
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the location-related task you need to do.
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "permission granted", Toast.LENGTH_LONG).show()
} else {
// permission denied, boo! Disable the functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show()
}
return
}
}
}
}
}