I have a problem trying to use a getContent to replace the onActivityResult - kotlin

The problem arises when using the registerForActivityResult, then it gives me an error when trying to make the contract (ActivityResultContacts), although I suppose that this last error derives from the previous error so I will focus on the first problem, that of the registerForActivityResult, I really don't know how to explain the problem itself, so I better leave my code below in case someone wants to take a look and try to help me with the problem, if so, thank you very much in advance.
Have a good day.
private val getContent = registerForActivityResult(ActivityResultContracts.TakePicturePreview()){
bitmap ->
heroBitmap = bitmap
heroImage.setImageBitmap(heroBitmap!!)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.saveButton.setOnClickListener{
val superheroName = binding.heroNameEdit.text.toString()
val alterEgo = binding.alterEgoEdit.text.toString()
val bio = binding.bioEdit.text.toString()
val power = binding.powerBar.rating
val hero = Superhero(superheroName, alterEgo, bio, power)
openDetailActivity(hero)
}
heroImage = binding.heroImage
heroImage.setOnClickListener{
openCamera()
}
}
private fun openCamera() {
getContent.launch(null)
}
private fun openDetailActivity(hero: Superhero){
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra(DetailActivity.HERO_KEY, hero)
intent.putExtra(DetailActivity.BITMAP_KEY, heroBitmap)
startActivity(intent)
}
}

Related

Kotlin Composable: How to return data from a called activity

In my Jetpack Compose project I have two activities: ActivityA and ActivityB. I can pass data from ActivityA to ActivityB easily, as follows:
private fun showContinueDialog(indexSent: Int, messageSent: String){
val intent = Intent(this, ActivityB::class.java)
intent.putExtra("indexSent", indexSent)
intent.putExtra("messageSent", messageSent)
startForResult.launch(intent)
}
and:
private val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
val intent = result.data
if (intent != null) {
//I expect to receive data here
}
}
}
In ActivityB I have:
lateinit var intent2: Intent
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
.......
intent2 = intent}
#Composable
fun ContinueClicked(indexReturn: Int) {
intent2.putExtra("indexSent", indexReturn)
setResult(Activity.RESULT_OK, intent2)
startActivity(intent2)
this.finish()
}
When ActivityB closes, I expect to receive the result (an Integer) to appear in the ActivityResult block of ActivityA, but it does not happen. How can I return data from ActivityB to the ActivityResult block of ActivityA? Thanks!
I figured it out:
In the second activity, add something like this where the activity terminates:
intent.putExtra("indexSent", 7788)
setResult(Activity.RESULT_OK, intent)
this.finish()

android livedata not working in Activity , viewmodel

Hello I have recently encountered a situation where observing is not possible in livedata, so I am going to ask a question
It's too basic, but I don't know why it doesn't work, so I need your help.
If you give me a little teaching, I would be grateful
my SignUpActivity
class SignUpActivity : BaseKotlinActivity<ActivitySignUpBindingImpl, SignUpViewModel>() {
override val layoutResourceId: Int get() = R.layout.activity_sign_up
override val viewModel: SignUpViewModel by viewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivitySignUpBindingImpl>(this, layoutResourceId)
binding.apply {
lifecycleOwner = this#SignUpActivity
signUpViewModel = viewModel
}
viewModel?.apply {
signUpStep.observe(this#SignUpActivity, Observer {
when (it) {
SignUpStep.SIGN_UP -> supportFragmentManager.beginTransaction().replace(R.id.fragment, SignUpFragment(), "SignUpFragment").commit()
SignUpStep.PASSWORD -> supportFragmentManager.beginTransaction().replace(R.id.fragment, SignUpPasswordFragment(), "SignUpPasswordFragment").commit()
SignUpStep.PHONE_CERTIFICATION -> supportFragmentManager.beginTransaction().replace(R.id.fragment, SignUpPhoneCertificationFragment(), "SignUpPhoneCertificationFragment").commit()
else -> Unit
}
Log.d("Test Checked1", "${signUpStep.value}")
})
}
}
}
my viewModel
private val _signUpStep = MutableLiveData<SignUpStep>(SignUpStep.SIGN_UP)
val signUpStep: LiveData<SignUpStep>
get() = _signUpStep
fun moveStep(view: View, newSignUpStep: SignUpStep) {
val oldSignUpStep = _signUpStep.value
_signUpStep.value = newSignUpStep
Log.d( "Test Checked","moveStep: $oldSignUpStep -> $newSignUpStep")
}
log
Test Checked1: SIGN_UP
moveStep: SIGN_UP -> PASSWORD
moveStep: PASSWORD -> PASSWORD
moveStep: PASSWORD -> PASSWORD
If you check the log, you can see that the moveStep changes normally. Then signUpSteop has changed normally, but it is not received in the observe of livedata, because the screen does not move and the log does not appear.
I'm just wondering if the code is wrong or what's wrong. Can you help me?
For reference, signUpStep is changing in Fragment and livedata is constantly being observed in activity.

How can I do the kotlin mediaPlayer shuffle play

I am trying to create shuffle mode for the music-player application. The problem is; The sound on my list only plays once and stops when finished. but I want all the sounds on my list to be shuffled and played automatically. I am very new to Android programming, I tried hard but failed. I also tried the setOnCompletionListener {} method but it didn't work. I need help. thanks everyone
here are my sample codes;
class MainActivity : AppCompatActivity() {
var mediaPlayer = MediaPlayer()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val Sound1 = R.raw.sound01
val Sound2 = R.raw.sound02
val Sound3 = R.raw.sound03
val Sound4 = R.raw.sound04
val Sound5 = R.raw.sound05
val soundList = ArrayList<Int>()
soundList.add(Sound1)
soundList.add(Sound2)
soundList.add(Sound3)
soundList.add(Sound4)
soundList.add(Sound5)
shuffleBtn.setOnClickListener {
val randomList = Random.nextInt(soundList.size)
val sound = soundList.get(randomList)
mediaPlayer = MediaPlayer.create(this, sound)
mediaPlayer.start()
}
}
}
Add a completion listener that releases the original player and creates a new one.
If you want to play shuffled, you need a variable to store the shuffled list and remove tracks as you play them so you know when to reshuffle. The way you're picking random sounds, you could play the same sound twice in a row sometimes.
By the way, you can create your list more concisely.
I didn't test this code. Sorry for any errors.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val sounds = listOf(
R.raw.sound01,
R.raw.sound02,
R.raw.sound03,
R.raw.sound04,
R.raw.sound05
)
var shuffledSounds = sounds.shuffled()
fun newTrack() {
if (shuffledSounds.isEmpty()) {
shuffledSounds = sounds.shuffled()
}
val nextSound = shuffledSounds.first()
shuffledSounds = shuffledSounds - nextSound
mediaPlayer = MediaPlayer.create(this, nextSound).apply {
setOnCompletionListener{
it.release()
newTrack()
}
start()
}
}
shuffleBtn.setOnClickListener {
newTrack()
}
}

Looking for the proper syntax to set setmaxlifecycle on my tabbed application

I'm just a hack and a newbie...I've received a lot of good information on this site but can't seem to find the answer to setting the max life cycle of a fragment, such that when it is selected, the onResume() for that fragment is executed.
I've created a simple 3-tab application from the help of youTube videos and haven't figured out to properly set the lifecycle. I'm not sure how much information I should include, so i'll start with this:
val tabLayout: TabLayout = findViewById(R.id.tab_layout)
val viewPager: ViewPager = findViewById(R.id.view_pager)
val viewPagerAdpater = ViewPagerAdapter(supportFragmentManager)
viewPagerAdpater.addFragment(SummaryFragment(), "Summary")
viewPagerAdpater.addFragment(BoxFragment(), "Box")
viewPagerAdpater.addFragment(SettingsFragment(), "Settings")
viewPager.adapter = viewPagerAdpater
tabLayout.setupWithViewPager(viewPager)
I've tried this, which crashes:
supportFragmentManager.beginTransaction().setMaxLifecycle(viewPagerAdpater.getItem(1),Lifecycle.State.RESUMED)
There is also this code:
internal class ViewPagerAdapter(fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager) {
private val fragments: ArrayList<Fragment>
private val titles: ArrayList<String>
init{
fragments = ArrayList<Fragment>()
titles = ArrayList<String>()
}
override fun getItem(position: Int): Fragment {
return fragments[position]
}
override fun getCount(): Int {
return fragments.size
}
fun addFragment(fragment: Fragment, title: String){
fragments.add(fragment)
titles.add(title)
}
override fun getPageTitle(i: Int): CharSequence? {
return titles[i]
}
}
Thanks and let me know if more information is required...

How to open same Activity with different data in Android Kotlin?

class FirstActivity : AppCompatActivity() {
companion object{
val USER_KEY="FirstActivity"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_first)
button_firstActivity.setOnClickListener {
val string:String=textView_first.text.toString()
val intent=Intent(this,MainActivity::class.java)
intent.putExtra(USER_KEY,string)
startActivity(intent)
}
}
}
class MainActivity : AppCompatActivity() {
companion object{
val MAINUSERKEY="MainActivity"
var str:String=""
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
str=intent.getStringExtra(FirstActivity.USER_KEY)
textview_main.text=str
button_Run.setOnClickListener {
val edittextstring=editText1.text.toString()
val intent=Intent(this,MainActivity::class.java)
intent.putExtra(MAINUSERKEY,edittextstring)
startActivity(intent)
}
}
}
Hello every one! I am new to Android programming with Kotlin.
I have two activities, suppose A and B. I want to start activity B from A and when B starts, it will display the TextView string of A into TextView_Main.
It is working fine now. I want to start activity B again on clicking button_Run which is on Activity B and passing a string again which I entered in edittext of Activity B. And now it should be displayed on textview of Activity B, when it opens again.
Please help me do this.
The problem is that the edittext string is being stored as an intent extra with name MAINUSERKEY="MainActivity”, which is different from the extra you are currently extracting on your MainActivity, the one with name USER_KEY="FirstActivity”. So I would do something like this to ensure I get the correct string extra:
str = with(intent) {
getStringExtra(FirstActivity.USER_KEY) ?: getStringExtra(MainActivity.MAINUSERKEY) ?: "No string extra was found"
}
it is more clear to startActivity like code below, add this code in ActivityB
companion object{
private const val EXTRA_ MAIN_USERKEY = "EXTRA.MAIN_USERKEY"
fun getIntent(context:Context, userKey:String): Intent
{
val intent = Intent(context,ActivityB::class.java)
intent.putExtra(EXTRA_ MAIN_USERKEY, userKey)
return intent
}
}
and this code in ActivityA:
startActivity(ActivityB.getIntent(this,"some key"))
so every time you start activityB you should pass the string