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
}
Related
I want create a file to specify folder ,my file type is zip,I want use
FileOutStream to create.
It sends an intent, you can see the code below:
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
startActivityForResult(mContext,intent, 9999,null)
then it gets the returned data, you can see the code below:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
when (requestCode) {
9999 -> {
Log.v("Test", "Result URI " + data!!.getData())
// FileInputStream(data!!.getData())
}
}
}
}
}
the log is
V/Test: Result URI content://com.android.externalstorage.documents/tree/primary%3ATestFile
I want to create file with the Uri,but use FileOutStream will crash,have any way to create file in specify folder?
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.
I have a program that allows me to store data(pictures and metadata with the taken picture) during the execution of a picture being taking with the android system camera activity... but I have code in place to make sure that the user enters data into a popup activity before the camera activity is displayed by using the OnActivityResult function(this way the user's photo has information that is stored as metadata in my firebase database). I was wondering If I can set a request code that wouldn't be equal to the REQUESTCODE2 so that under the condition that my back button is pressed(which will still result in the REQUESTCODE2 being returned for the com.example.myapplication.nameofphoto activity, which then will trigger takepic()) I can purposely make sure that the request code is faulty so that takepic() does not trigger and I don't store null data into my database.
for your information: nameofpersonvar , and nameofphotovar are both in a different class and is the information from the popup activity
private const val REQUESTCODE = 2
private const val REQUESTCODE2 = 3
fun take_pic(){
val takephotoIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (takephotoIntent.resolveActivity(this.packageManager) != null) {
startActivityForResult(takephotoIntent, REQUESTCODE)
} else {
Toast.makeText(this, "Unable To access Camera... ", Toast.LENGTH_LONG)
.show()
}
}
photoButton.setOnClickListener {
val action3 = Intent(this , com.example.myapplication.nameofphoto::class.java)
startActivityForResult(action3, REQUESTCODE2 )
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (REQUESTCODE == requestCode && resultCode == Activity.RESULT_OK) {
//Compressing the bitmap(image) into a byte[] to match the input of the .putbytes method
val userimage = data?.extras?.get("data") as Bitmap
val byteoutput = ByteArrayOutputStream()
userimage.compress(Bitmap.CompressFormat.JPEG,100 , byteoutput)
val data = byteoutput.toByteArray()
//ref to the firebase "bucket" database
val storageinfo = FirebaseStorage.getInstance().getReference("/Images" )
//extra data that shows who the images belong to (users)
val metadatastoreage = storageMetadata {
setCustomMetadata("Name of person" , nameofpersonvar)
setCustomMetadata("Name of photo" , nameofphotovar)}
storageinfo.putBytes(data, metadatastoreage)
}else if (requestCode ==REQUESTCODE2) {
take_pic()
}
else {
super.onActivityResult(requestCode, resultCode, data)
}
}
Then why don't you send some result code different from the back press method of the current activity opened and check if the result is successful then take pick otherwise do something.
send this as result code from back press method. RESULT_CANCELED
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (REQUESTCODE == requestCode && resultCode == Activity.RESULT_OK) {
//Compressing the bitmap(image) into a byte[] to match the input of the .putbytes method
val userimage = data?.extras?.get("data") as Bitmap
val byteoutput = ByteArrayOutputStream()
userimage.compress(Bitmap.CompressFormat.JPEG,100 , byteoutput)
val data = byteoutput.toByteArray()
//ref to the firebase "bucket" database
val storageinfo = FirebaseStorage.getInstance().getReference("/Images" )
//extra data that shows who the images belong to (users)
val metadatastoreage = storageMetadata {
setCustomMetadata("Name of person" , nameofpersonvar)
setCustomMetadata("Name of photo" , nameofphotovar)}
storageinfo.putBytes(data, metadatastoreage)
return
}
if (requestCode ==REQUESTCODE2 && resultcode == Activity.RESULT_OK) {
take_pic()
} else {
//back pressed do something.
//finish etc
}
}
Edit: You can override the onBackPressed() in the popup activity and send some data using intent to the parent activity. for ex.
Intent resultIntent = new Intent();
// TODO Add extras or a data URI to this intent as appropriate.
resultIntent.putExtra("user_pic_click", "some data");
setResult(Activity.RESULT_OK, resultIntent);
finish();
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.
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.