Passing extras with Intent.createChooser - android

I am using following code to select picture from gallery. I want to track the int value from this intent.
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
intent.putExtra("Position", 1)
startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE)
But I am getting only default value[0] when trying to get the passed value from intent in onActivityResult.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
val selectedImageURI = data?.data
val position = data?.getIntExtra("Position", 0)
}
}
}
So my doubt is, is it possible to track the values through intent chooser? If yes, how?

you have to use requestCode in this line:
startActivityForResult(Intent.createChooser(intent, "Select Picture"), requestCode)
// for example use SELECT_PICTURE_POSITION_1 as requestCode
then you get it back here:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
when (requestCode) {// use your request code here
SELECT_PICTURE_POSITION_0 -> {
val selectedImageURI = data?.data
val position = data?.getIntExtra("Position", 0)
}
SELECT_PICTURE_POSITION_1 -> {
val selectedImageURI = data?.data
val position = data?.getIntExtra("Position", 1)
}
SELECT_PICTURE_POSITION_2 -> {
val selectedImageURI = data?.data
val position = data?.getIntExtra("Position", 2)
}
//other conditions here
}
}
}
use multiple request codes for your needs.

is it possible to track the values through intent chooser?
No. Your problem has nothing to do with the chooser. You would have the same results with startActivityForResult(intent), SELECT_PICTURE).
There is no requirement for the activity being started by startActivityForResult() to return to you any extras that you happen to have put in that Intent.

Related

onActivityResult deprecated, is there alternative (KOTLIN)

Currently I am working on a project for my college, and i have discovered that onActivityResult is deprecated. What can be done to handle it?
This is my code that troubles me
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
val result = CropImage.getActivityResult(data)
if (resultCode == RESULT_OK) {
image = result.uri
Glide.with(this).load(image).into(binding.imgPick)
} else {
Snackbar.make(
binding.root,
"Image not selected",
Snackbar.LENGTH_SHORT
).show()
}
}
}
I tried to find a solution on stackoverflow and already tried to implement couple of thing but with no luck.
You can use the following way :
fun openActivityForResult() {
startForResult.launch(Intent(this, AnotherActivity::class.java))
}
val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
val intent = result.data
// Handle the Intent
//do stuff here
}
}
You can use this in activity or fragment.
First define intent result launcher.
var picker: ActivityResultLauncher<Intent>
then
picker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK && it.data != null) {
//add your code here
}
}
And now launch your activity.
val intent = Intent(context, ImagePickerActivity::class.java)
picker.launch(intent)

How to load audio file in ListView?

I need to load random audio files from storage, into my ListView, on a button click. But I don't understand how can I do this. When I call intent, file manager open to pick file. My song must have title, artist name and url. But after clicking it doesn't add. This is my code. Don't scold me for a possibly dull question. I'm new at android developing.
private fun loadSong() {
val intent: Intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
type = "audio/*"
action = Intent.ACTION_GET_CONTENT
}
startActivityForResult(Intent.createChooser(intent, "Select Audio"), PICK_AUDIO)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == PICK_AUDIO && resultCode == RESULT_OK){
if (data != null) {
audioUri = data.data
}
}
adapter = SongsAdapter(listSongs)
twoTracksListView.adapter = adapter
}

uploading image from gallery and camera to server

I need to save the image that is taken from camera or image taken from gallery in kotlin. for now I've done this part and i'm finding other examples in kotlin but i'm unable to find. In other examples, images were send in multipart which was coded in java.
These are listeners
private val cameraRequest = 1888
private val pickImage = 100
private var imageUri: Uri? = null
takePhoto.setOnClickListener {
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(cameraIntent, cameraRequest)
}
choosePicture.setOnClickListener {
val gallery = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
startActivityForResult(gallery, pickImage)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == cameraRequest) {
val photo: Bitmap = data?.extras?.get("data") as Bitmap
takePhoto.setImageBitmap(photo)
}
if (resultCode == RESULT_OK && requestCode == pickImage) {
imageUri = data?.data
if (imageUri != null) {
choosePicture.setImageURI(imageUri)
}
}
}
You can use this library for making a multipart request: https://github.com/gotev/android-upload-service
Also, it will handle app behaviour for you which includes upload-retry on slow internet connection and many more.

How to pass data in startActivityForResult() and get it back inside onActivityResult()?

Here's my startActivityForResult():
val initialPosition = frame.tag as Int
val currentPosition = constraint.indexOfChild(frame)
Log.d(TAG, "initial position: $initialPosition") // prints initial position: 2
Log.d(TAG, "current position: $currentPosition") // prints current position: 2
val galleryIntent = Intent().apply {
type = "image/*"
action = Intent.ACTION_PICK
putExtra("initialPosition", initialPosition)
putExtra("currentPosition", currentPosition)
setResult(5)
}
startActivityForResult(Intent.createChooser(galleryIntent, "Pick image"), PICK_IMAGE_REQUEST_CODE)
However, I'm unable to retrieve the data here:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK){
Log.d(TAG, "ResultCode: $resultCode SUCCESS") // prints -1 SUCCESS
}
when (requestCode){
PICK_IMAGE_REQUEST_CODE -> {
Log.d(TAG, "${data?.getIntExtra("initialPosition", 0)}") // prints 0
Log.d(TAG, "${data?.extras?.getInt("initialPosition")}") // prints 0
Log.d(TAG, "${data?.extras?.getInt("currentPosition")}") // prints 0
}
}
super.onActivityResult(requestCode, resultCode, data)
}
Any idea why?
setResult() will not set galleryIntent's result code. The one that will set that result is the activity that you picked during Intent.ACTION_PICK.
Assuming you picked the system image picker. It will return RESULT_OK(which is -1) if you select an image, and return RESULT_CANCELED(which is 0) if you backpress.
Note that you cannot change what other activity returns for resultCode if you use an Implicit Intent, which is what you just did.

android camera: onActivityResult() intent is null if it had extras

After searching a lot in all the related issues at Stack Overflow and finding nothing, please try to help me.
I created an intent for capture a picture. Then I saw different behavior at onActivityResult(): if I don't put any extra in the Intent (for small pics) the Intent in onActivityResult is ok, but when I put extras in the intent for writing the pic to a file, the intent in onActivityResult is null!
The Intent creation:
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// without the following line the intent is ok
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(takePictureIntent, actionCode);
Why is it null, and how can I solve it?
It happens the same to me, if you are providing MediaStore.EXTRA_OUTPUT, then the intent is null, but you will have the photo in the file you provided (Uri.fromFile(f)).
If you don't specify MediaStore.EXTRA_OUTPUT then you will have an intent which contains the uri from the file where the camera has saved the photo.
Don't know if it as a bug, but it works that way.
EDIT: So in onActivityResult() you no longer need to check for data if null. The following worked with me:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PICK_IMAGE_REQUEST://actionCode
if (resultCode == RESULT_OK && data != null && data.getData() != null) {
//For Image Gallery
}
return;
case CAPTURE_IMAGE_REQUEST://actionCode
if (resultCode == RESULT_OK) {
//For CAMERA
//You can use image PATH that you already created its file by the intent that launched the CAMERA (MediaStore.EXTRA_OUTPUT)
return;
}
}
}
Hope it helps
A sample written in Kotlin. You create a Uri for camera app, CameraFragment holds it until camera returns from saving your picture and gives it back to you in onActivityResult as you would expect.
CameraFragment.kt
Acts as an intermediary between consumer and camera app. Takes Uri as input and returns it in data Intent.
class CameraFragment : Fragment() {
companion object {
val TAG = CameraFragment::class.java.simpleName
private val KEY_URI = ".URI"
fun newInstance(uri: Uri, targetFragment: Fragment, requestCode: Int): CameraFragment {
val args = Bundle()
args.putParcelable(KEY_URI, uri)
val fragment = CameraFragment()
fragment.arguments = args
fragment.setTargetFragment(targetFragment, requestCode)
return fragment
}
}
private lateinit var uri: Uri
private var fired = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
retainInstance = true
fired = savedInstanceState?.getBoolean("fired") ?: false
if (!fired) {
val args = arguments
uri = args.getParcelable(KEY_URI)
val i = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
i.putExtra(MediaStore.EXTRA_OUTPUT, uri)
i.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
context.grantUriPermission(i, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
startActivityForResult(i, targetRequestCode)
fired = true
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putBoolean("fired", fired)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == targetRequestCode) {
context.revokeUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
val newData = Intent()
newData.data = uri
targetFragment.onActivityResult(requestCode, resultCode, newData)
dismiss()
}
}
private fun dismiss() {
fragmentManager.beginTransaction().remove(this).commit()
}
}
/** Grant Uri permissions for all camera apps. */
fun Context.grantUriPermission(intent: Intent, uri: Uri, modeFlags: Int) {
val resolvedIntentActivities = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (resolvedIntentInfo in resolvedIntentActivities) {
val packageName = resolvedIntentInfo.activityInfo.packageName;
grantUriPermission(packageName, uri, modeFlags);
}
}
Invoke camera intent
this is a fragment in your app which will trigger the camera. RC_CAMERA is your request code for this action.
val uri = /* Your output Uri. */
val f = CameraFragment.newInstance(uri, this, RC_CAMERA)
fragmentManager.beginTransaction().add(f, CameraFragment.TAG).commit()
Handle camera result
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when(requestCode) {
RC_CAMERA -> {
if (resultCode == Activity.RESULT_OK) {
val uri = data?.data
// Do whatever you need.
}
}
}
}
Where did you create the ffor the Uri.fromFile(f)?
It must be a valid File object. Try to create it before the EXTRA_OUTPUT line.
File f = new File("valid path");
Try with something like this:
File file = new File(dataFile);
Uri outFileUri = Uri.fromFile(file);
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, outFileUri);
startActivityForResult(intent, TAKE_PHOTO);
use the following:
Bitmap bitmap = data.getExtras().getParcelable("data");
it works.

Categories

Resources