How to fix sound? - java

I have been stuck on this for way too long now. In my main menu screen, I have a mute button. I want it to call a method in my background service, which mutes all of the MediaPlayer audio that would be played in the background of my game.
Here I am calling mute from my Main_Menu (x starts as 0):
if ((x%2) == 0) { //If it's even
TwentySeconds.unMute();
Toast.makeText(Main_Menu.this, "UNMUTED", Toast.LENGTH_SHORT).show();
x++;
} else { //If its odd
TwentySeconds.myMute();
Toast.makeText(Main_Menu.this, "MUTED", Toast.LENGTH_SHORT).show();
x++;
}
Here are the methods in the service which actually do the muting:
public static void myMute() {
ten.setVolume(0, 0);
three.setVolume(0, 0);
}
public static void unMute() {
ten.setVolume(1, 1);
three.setVolume(1, 1);
}
Here are the actual media players, which play at intervals:
static MediaPlayer ten;
static MediaPlayer three;
The problem is, I am getting a null pointer exception here:
TwentySeconds.myMute();
and
ten.setVolume(0, 0);
By the way, manager is instantiated like so:
AudioManager manager;
and later on:
manager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
Here is something that might be causing the issue:
I am getting the error whenever the audio plays (which plays fine):
QCMediaPlayer mediaplayer NOT present
E/MediaPlayer﹕ Should have subtitle controller already set
I would really appreciate any feedback (positive or negative)!
Let me know if you need any more code.

You must start your service first
In the method in Main_Menu
Intent svIntent = new Intent(this, TwentySeconds.class);
startService(svIntent);
And then you call TwentySeconds.myMute();
Remember add service to manifest file:
<service android:enabled="true" android:name=".TwentySeconds" />

Related

How can I stop youtube music?

I am using AudioManager in order to make this work.
This is what I have done:
private AudioManager isPlaying = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
if(isPlaying.isMusicActive()) {
isPlaying.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
} else{
Toast.makeText(getApplicationContext() , "There is no music playing..", Toast.LENGTH_SHORT).show();
}
I want to stop the music playing from youtube or any other app. In addition, how can I pause it and resume it?
In Stop MediaPlayer when an other app play music
A person answer
AudioManager manager = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
if(manager.isMusicActive())
{
// do something - or don't
}

Is it possible to ignore plugged in Headset and still use phone speakers?

I would like to use the Phone Speakers while a Headset is plugged-in, instead of the Headset-Speakers.
Is it possible to do that? if yes, how can I achieve it?
I'm developing an App in Java for Android 9.
Detection if Headset is Plugged in works so far:
public class HeadsetIntentReceiver extends BroadcastReceiver {
private String TAG = "HeadSet";
public HeadsetIntentReceiver() {
Log.d(TAG, "Created");
}
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
int state = intent.getIntExtra("state", -1);
switch(state) {
case(0):
Log.d(TAG, "Headset unplugged");
break;
case(1):
Log.d(TAG, "Headset plugged");
break;
default:
Log.d(TAG, "Error");
}
}
}
}
EDIT:
I tried the following Solutions, but Nothing happend:
How to mute audio in headset but let it play on speaker programmatically?
How to disable the wired headset programmatically in Java
Thanks in Advance for any helpful advice.
(Please don't answer "Unplug the Headset")
I think you are looking for AudioManager
Attach AUDIO_SERVICE to AudioManager, set AudioManager as MODE_IN_COMMUNICATION and then set your speaker phone on. You can use the speaker as if you were talking on the phone.
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
audioManager.setSpeakerphoneOn(true);
Remember to restore it after use.
for example,
protected void onPause() {
super.onPause();
audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.setSpeakerphoneOn(false);
}

calling BroadcastReceiver from Activity

I am newbie in android programming; sorry if my question is easy :)
I'm trying to write code that monitors the battery level on the phone and if it is, lower some level for example (%15), create a message that asks user to plug the charger. I know that I need to use BroadcastReceiverclass and I want to use it in my MainActivity class. Here is the code I have:
public class MainActivity extends Activity{
BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, Intent intent) {
String intentAction = intent.getAction();
Log.d("receiver", intentAction);
int level = intent.getIntExtra("level", 0);
if (level < 15){
Log.d("receiver", "battery level low");
}
if (Intent.ACTION_BATTERY_OKAY.equalsIgnoreCase(intentAction)) {
Log.d("receiver", "battery level okay");
}
}
};
......
but it seems that the onReceivemethod is never called since I never see the Log.d("receiver", intentAction) message on Android Studio debug window.
I also have registered br in onResume and unregistered it in onPause:
public void onResume() {
super.onResume();
filter.addAction("receiver");
registerReceiver(br, filter);
}
public void onPause() {
super.onPause();
unregisterReceiver(br);
}
But still I am not getting any message.
Can anybody please help me? Should I also add something to AndroidManifest.xml?
If you dont want to use BroadcastReceiver simply dont use it. Battery intent is sticky intent so you can check it without need of BroadcastReceiver and i also dont think its good idea to put receiver in activity. You can check battery stuff in your activity like this and you dont need to edit your manifest
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, filter);
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
float batteryPct = level / (float)scale;
if(batteryPct < 15){
//do your stuff
}
Your code in onResume() is wrong. You will have to update it as follows.
filter.addAction(Intent.ACTION_BATTERY_LOW);
filter.addAction(Intent.ACTION_BATTERY_OKAY);
registerReceiver(br, filter);
to include the ACTION_BATTERY_LOW and ACTION_BATTERY_OKAY filters as mentioned in the docs.

How to stop sound in Android after

I am trying to build an alarm application. When the alarm turns on, the user has to scan a matching QR code before it is turned off. I've taken a look at this link to get the sound playing: How to play ringtone/alarm sound in Android and I am using the ScanningViaIntent from the zxing library for the QR code scanner: https://code.google.com/p/zxing/.
So I start the sound in the onStart() activity:
#Override
public void onStart(){
super.onStart();
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
}
The user then starts the scanner by pressing a button:
private class HandleClick implements OnClickListener{
public void onClick(View arg0) {
IntentIntegrator integrator = new IntentIntegrator(AlarmRequirementsActivity.this);
integrator.initiateScan();
}
}
The result of the scanner is returned here:
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
if (scanResult != null) {
System.out.println("scanREsult" + scanResult);
System.out.println("requestCode: " + requestCode);
TextView result =(TextView)findViewById(R.id.scanResult);
if (resultCode == RESULT_OK) {
String scanResultString = intent.getStringExtra("SCAN_RESULT");
if(scanResultString .equals(matchString))
{
result.setText("You found it!");
r.stop();
}
else
{
result.setText("\"" + scanResultString + "\""+ " did not match");
}
System.out.println(intent.getStringExtra("SCAN_RESULT"));
} else if (resultCode == RESULT_CANCELED) {
}
}
// else continue with any other code you need in the method
}
As you can see, I call r.stop() after a successful match. However these are my problems:
The activity is restarted after coming back from the scanner. It doesn't matter if the match was successful or not.
This results in two alarm tones being played now
I've tried putting it in the onCreate() method but to no avail as well.
UPDATE:
I've tried:
#Override
public void onStart(){
super.onStart();
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
r = RingtoneManager.getRingtone(getApplicationContext(), notification);
if(!r.isPlaying())
{
r.play();
}
}
and this below. Both of which with the same problems
if(scanResultString .equals(matchString))
{
result.setText("You found it!");
if(r.isPlaying())
{
r.stop();
}
}
The activity is restarted after coming back from the scanner. It doesn't matter if the match was successful or not.
I assume that you need to start another activity to do the scan, which means that your activity will (at least) need to be paused and more likely stopped to allow that other activity to run (as per the Android activity lifecycle).
Therefore, you will have to expect onStart() to be called when returning from the scanner.
This results in two alarm tones being played now
You should be able to avoid this and your code to check if the ringtone is already playing seems like a good start. However, I suspect you are creating a new ringtone object each time onStart() is executed.
It is hard for me to guess at all of the things you will need to do to fully resolve your problems (not to mention problems you will only see when your activity is fully recreated by Android - for example when the screen orientation changes - as this needs further handling in your code; see the Android doc for the activity lifecycle, particularly onSaveInstanceState()).
My guess at the next step would be to move the line:
r = RingtoneManager.getRingtone(getApplicationContext(), notification);
into your onCreate() method. My hope is that this, combined with the if (!r.isPlaying()) code should prevent the double-alarm issue in most cases.

MediaPlayer Volume issue-AudioStream issue

I am trying to provide a custom beep sound when I get a message in my Application. This beep sound should respect the master phone notification volume level(not ringer volume). Which means if phone notification vol =3/10 , then beep intensity should be 3/10.
I am not able to achieve this,
AudioManager audioMan = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
int volume;
if (mPlayer == null) {
mPlayer = MediaPlayer.create(context, R.raw.mytone);
}
if (mPlayer.isPlaying()) {
mPlayer.stop();
mPlayer.release();
mPlayer = MediaPlayer.create(context, R.raw.mytone);
}
volume = audioMan.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
mPlayer.setVolume(volume, volume);//this doesn't work for me, beep sound is taking media player volume by default.
mPlayer.setOnErrorListener(new OnErrorListener() {
#Override
public boolean onError(MediaPlayer player, int what, int extra) {
player.stop();
player.reset();
return true;
}
});
if (mVibrator == null)
mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mVibrator.cancel();
Can you please share your knowledge and give me directions. Thank you.
It looks like you are playing your sound over the music stream going by the reference to AudioManager.STREAM_MUSIC. Modifying the volume level modifies the level for everything played on that stream. This is why music/media playback is 'mucked up'.
If you want to use the ringer stream (and its volume setting) then you should be using AudioManager.STREAM_RING instead. You say you've tried this but the code snippet you've given just adjusts the volume - you've not shown how you create and configure your MediaPlayer before you ask it to play your sound.
You've got to select the appropriate stream when you set up your MediaPlayer instance. As I've successfully used different streams in the kind of scenario you are describing, this is where your problem lies. To select the audio stream over which your custom beep is played, use setAudioStream on your MediaPlayer instance like this:
// Get a reference to the MP3 file to play
AssetFileDescriptor afd = getContext().getResources().openRawResourceFd(R.raw.my_mp3);
// Create the media player
MediaPlayer mediaPlayer = new MediaPlayer();
// Give it the MP3 you want played
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
// Set the audio stream to play over
mediaPlayer.setAudioStreamType(AudioManager.STREAM_RING);
// Now play the sound
mediaPlayer.prepare();
mediaPlayer.start();
Its good practice to offer your users the option to choose the stream for themselves - in addition to the music and ringer streams there are alarm and notification streams, each with an independent volume level (there are others too, but these are the core ones). Have a look at the Android documentation on AudioManager here.

Categories