How can I implement android media controls for the Notification Center when using MediaPlayer?
I tried to use the offical documentation right here and this article but I couldn't implement it correctly.
I tried to call this method when I start my media player mediaPlayer?.start(), but nothing is showing up in the notification center:
val mSession: MediaSession by lazy { MediaSession(requireContext(), "MusicService") }
fun createMediaControls() {
mSession.isActive = true
mSession.setCallback(object : MediaSession.Callback() {
override fun onMediaButtonEvent(mediaButtonIntent: Intent): Boolean {
print("onMediaButtonEvent called: $mediaButtonIntent")
return false
}
override fun onPause() {
print("onPause called (media button pressed)")
super.onPause()
}
override fun onPlay() {
print("onPlay called (media button pressed)")
super.onPlay()
}
override fun onStop() {
print("onStop called (media button pressed)")
super.onStop()
}
})
mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS or MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS)
mSession.setMetadata(
MediaMetadata.Builder()
.putString(MediaMetadata.METADATA_KEY_TITLE, "titleee")
.putString(MediaMetadata.METADATA_KEY_ARTIST, "artist")
.putString(MediaMetadata.METADATA_KEY_ALBUM_ART_URI, "albumArtUri")
.build()
)
}
Related
I've seen plenty of answers explaining how to override and add functionality to a back button press via user's interaction, but almost none of the answers explain how to programmatically trigger a back button press without any user input. Answers that do address it give somewhat deprecated code samples that don't really compute.
From your activity just call => onBackPressed(),
or form your fragment => activity?.onBackPressed()
//simply put this code where you want to make back intent
super.onBackPressed();
According to official docs onBackPressed is deprecated in Api level 33.
you can now use onBackPressedDispatcher please follow these steps:
Add android:enableOnBackInvokedCallBack="true” inside application tag
in manifest folder.
Kotlin code :
class YourActivity : AppCompatActivity() {
lateinit var button: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button = findViewById(R.id.txt)
button.setOnClickListener {
onBackPressedCallback.handleOnBackPressed()
}
}
private val onBackPressedCallback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
finish() //this finishes the current activity
// Your business logic to handle the back pressed event
}
}
}
And here is old way of implementation:
Java :
buttonBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
YourActivity.super.onBackPressed();
}
});
Kotlin :
buttonBack.setOnClickListener{
super.onBackPressed()
}
I'm using PreferenceFragmentCompat to display and set SharedPreferences. This all works fine. However, I keep getting "W/InputEventReceiver: Attempted to finish an input event but the input event receiver has already been disposed." in my logs, because the standard dialog used by PreferencesFragmentCompat does not seem to use the .setCancelable(false) in its showDialog method. I guess I could build my own custom dialog, but that seems a bit of an overkill just to solve this one small problem. Is there any way to simply overwrite the method?
Update:
It was enough to add this to my PreferencesFragmet (removed MultiSelectListPreferenceDialogFragmentCompat, as I don't use it)
#Override
public void onDisplayPreferenceDialog(Preference pref) {
DialogFragment dialogFragment = null;
String DIALOG_FRAGMENT_TAG = "androidx.preference.PreferenceFragment.DIALOG";
if (pref instanceof EditTextPreference) {
dialogFragment = EditTextPreferenceDialogFragmentCompat.newInstance(pref.getKey());
} else if (pref instanceof ListPreference) {
dialogFragment = ListPreferenceDialogFragmentCompat.newInstance(pref.getKey());
}
if (dialogFragment != null) {
dialogFragment.setTargetFragment(this, 0);
dialogFragment.setCancelable(false); //adding this!
if (this.getFragmentManager() != null) {
dialogFragment.show(this.getFragmentManager(), DIALOG_FRAGMENT_TAG);
}
} else {
super.onDisplayPreferenceDialog(pref);
}
}
I sorted though PreferenceFramgnetCompat source code to solve this issue.
Unfortunately, you can't execute '.setCancelable(false)' to dialog without callback or override.
I'll explain it with callback.
You should implement 'PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback' interface on activity which contains PreferenceFragmentCompat fragment.
When user press a preference one of EditTextPreference, ListPreference or AbstractMultiSelectListPreference, the onPreferenceDisplayDialog method will be executed.
When onPreferenceDisplayDialog method is executed, you should open dialog.
Fortunately, there are three type dialog and Google provide it by public so you don't need to make a custom dialog for them.
Just create instance of dialog and call setCancelable(false) and show it!
Please refer below codes.
class SettingsActivity : FragmentActivity(), PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback {
private val DIALOG_FRAGMENT_TAG = "android.support.v7.preference.PreferenceFragment.DIALOG"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportFragmentManager.beginTransaction()
.replace(android.R.id.content, SettingsFragment(), "setting_fragment").commit()
}
override fun onPreferenceDisplayDialog(caller: PreferenceFragmentCompat, preference: Preference?): Boolean {
// check if dialog is already showing
if (supportFragmentManager!!.findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) {
return true
}
val f: DialogFragment
if (preference is EditTextPreference) {
f = EditTextPreferenceDialogFragmentCompat.newInstance(preference.getKey())
} else if (preference is ListPreference) {
f = ListPreferenceDialogFragmentCompat.newInstance(preference.getKey())
} else if (preference is AbstractMultiSelectListPreference) {
f = MultiSelectListPreferenceDialogFragmentCompat.newInstance(preference.getKey())
} else {
throw IllegalArgumentException("Tried to display dialog for unknown " + "preference type. Did you forget to override onDisplayPreferenceDialog()?")
}
f.setTargetFragment(supportFragmentManager.findFragmentByTag("setting_fragment"), 0)
f.isCancelable = false // !! HERE !!
f.show(supportFragmentManager!!, DIALOG_FRAGMENT_TAG)
return true
}
}
How can I display panel states of SlidingUpPanel in Kotlin?
I want to use https://github.com/umano/AndroidSlidingUpPanel library, following this tutorial:
http://www.devexchanges.info/2015/05/making-sliding-up-panel-like-google.html
and the result should look like this:
https://www.youtube.com/watch?v=g464fp-2dQU
The code in Java from tutorial link:
private SlidingUpPanelLayout.PanelSlideListener onSlideListener() {
return new SlidingUpPanelLayout.PanelSlideListener() {
#Override
public void onPanelSlide(View view, float v) {
textView.setText("panel is sliding");
}
#Override
public void onPanelCollapsed(View view) {
textView.setText("panel Collapse");
}
#Override
public void onPanelExpanded(View view) {
textView.setText("panel expand");
}
#Override
public void onPanelAnchored(View view) {
textView.setText("panel anchored");
}
#Override
public void onPanelHidden(View view) {
textView.setText("panel is Hidden");
}
};
}
The converted code from Java to Kotlin (I put toast from anko library instead of textView):
private fun onSlideListener(): SlidingUpPanelLayout.PanelSlideListener {
return object : SlidingUpPanelLayout.PanelSlideListener {
override fun onPanelSlide(view: View, v: Float) {
toast("panel is sliding")
}
override fun onPanelCollapsed(view: View) {
toast("panel Collapse")
}
override fun onPanelExpanded(view: View) {
toast("panel expand")
}
override fun onPanelAnchored(view: View) {
toast("panel anchored")
}
override fun onPanelHidden(view: View) {
toast("panel is Hidden")
}
}
}
In Java code, in onCreate method, I have:
slidingLayout.setPanelSlideListener(onSlideListener());
which doesn't seems to work in Kotlin, because the methods I have are Click, Drag, Hover, Key and Touch (listeners).
I guess other good approach could be to implement
SlidingPaneLayout.PanelSlideListener
on my class, but I still couldn't make it work.
Any solution to find up if the panel is displayed or hidden in Kotlin?
You need to load up the Slidinglayout.
private lateinit var slidingLayout: SlidingUpPanelLayout
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.activity_main, container, false).also {
slidingLayout = it.findViewById(R.id.sliding_Layout)
}
}
than you check for the PanelState
if (slidingLayout.panelState == SlidingUpPanelLayout.PanelState.HIDDEN)
You also have the states ANCHORED, EXPANDED, COLLAPSED, DRAGGING
If you want to set up the Listener in Kotlin I have done it like This.
slidingLayout.addPanelSlideListener(object : SlidingUpPanelLayout.PanelSlideListener {
override fun onPanelSlide(panel: View?, slideOffset: Float) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onPanelStateChanged(panel: View?, previousState: SlidingUpPanelLayout.PanelState?, newState: SlidingUpPanelLayout.PanelState?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
})
After migrating from android.support to androidx, all the functions like onBackPressed(), setSupportActionBar and other default functions has stopped working.
How to fix this error?
Dagger 2.17 isn't compatible with Androidx. Use 2.16
After changing version perform clean build and if it's still not working then perform Invalidate Caches / Restart from the File menu
Ok. The issue was with dagger version 2.14. Which uses support version for AppCompatActivity instead of androidx. Upgrading to latest version of dagger will solve this problem
We are using both these function will post code and a fancy onBackPressed fun
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_person)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
initViews()
}
Here is the Option Selected code we have a Menu here as well
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
if (item != null) {
when (item.itemId) {
R.id.addNote -> {
val intent = Intent(this, MainActivity::class.java)
intent.putExtra("FROM","N")// ADD NEW NOTE
startActivity(intent)
}
}
// CODE below manages HOME Button
val id = item.itemId
if (id == android.R.id.home) {
val intent = Intent(this, MainActivity::class.java)
intent.putExtra("FROM","N")// ADD NEW NOTE
startActivity(intent)
}
}
return super.onOptionsItemSelected(item)
}
And now that fancy onBackPressed with GLOBAL TOAST
override fun onBackPressed(){
theTOAST()
}
fun theTOAST(){
val toast = Toast.makeText(this#PersonActivity, "USE <-- to go back",Toast.LENGTH_LONG)
val view = toast.view
view.setBackgroundColor(Color.TRANSPARENT)
val text = view.findViewById(android.R.id.message) as TextView
text.setTextColor(Color.BLUE)
text.textSize = (20F)
toast.show()
}
To make the Toast Global you need a var toastSTR = "" at top level
Then put that var in the Toast where the string would go and set the value and call the fun wrom any fun you want a custom toast
How would you add an alarm to the CountDownTimer class? I guess it would be in the onFinish() method that comes with it, but just how would you go about that? Some code would help a lot.
Create a class that extends CountDownTimer, then override the on finish method and add a alarm function there.
object : NewCountDownTimer(3000, 1000) {
override fun onFinish() {
super.onFinish()
Timber.d("Test new countdowntimer2")
}
override fun onTick(millisUntilFinished: Long) {
}
}.start()
open class NewCountDownTimer(millisInFuture: Long, millisUntilFinished:Long) : CountDownTimer(millisInFuture, millisUntilFinished)
{
override fun onFinish() {
Timber.d("Test new countdowntimer")
//Add alarm function Here
}
override fun onTick(millisUntilFinished: Long) {
}
}