简体   繁体   English

Android MediaPlayer 不播放声音

[英]Android MediaPlayer not playing sound

in my Android app I want vibration and sound playing when a specific Activity is shown.在我的 Android 应用程序中,我希望在显示特定活动时播放振动和声音。 I created two VibrationManager and SoundManager singleton classes, and I start vibration and sound in the "onCreate" method of the Activity.我创建了两个 VibrationManager 和 SoundManager singleton 类,我在 Activity 的“onCreate”方法中启动振动和声音。 The Activity has got a button that stops vibration and sound, and closes the Activity, when clicked. Activity 有一个停止振动和声音的按钮,并在单击时关闭 Activity。 All seems to work, except for the sound, that is not played, even if the "playSound()" method is entered.一切似乎都有效,除了没有播放的声音,即使输入了“playSound()”方法也是如此。 Further, sometimes the sound is played instead, apparently with random logic... What's wrong with my code for the sound?此外,有时会播放声音,显然是随机逻辑......我的声音代码有什么问题?

MyActivity:我的活动:

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;

import java.util.Calendar;

import it.mypackage.DBHelper;
import it.mypackage.DBManager;
import it.mypackage.R;
import it.mypackage.SoundManager;
import it.mypackage.VibrationManager;
import it.mypackage.listeners.MyActivityStopAlarmButtonClickListener;

public class MyActivity extends AppCompatActivity
    {
     SoundManager soundManager;
     VibrationManager vibrationManager;
     DBManager dbManager;

     TextView alarmTitle, alarmText;
     Button stopButton;

     String title, text;
     boolean okClicked;

     int request_code = -1;

     @Override
     protected void onCreate(Bundle savedInstanceState)
        {
         super.onCreate(savedInstanceState);

         dbManager = new DBManager(getApplicationContext());
         vibrationManager = VibrationManager.getInstance(getApplicationContext());
         soundManager = SoundManager.getInstance(getApplicationContext());

         // Vibrate
         vibrationManager.startVibration();

         // Play sound
         soundManager.playSound();

         setOkClicked(false);

         // Set Activity fullscreen
         this.requestWindowFeature(Window.FEATURE_NO_TITLE);
         this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

         Window window = getWindow();

         // let the window be shown when the screen is locked and the keyguard will be dismissed
         window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                       | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);

         // Turn the device's screen on and keep it turned on and bright
         // as long as this window is visible to the user
         window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                       | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

         setContentView(R.layout.activity_alarm_receiver);

         // Reference all Views of the Activity
         alarmTitle = (TextView) findViewById(R.id.alarm_title_push_notification);
         alarmText = (TextView) findViewById(R.id.alarm_text_push_notification);
         stopButton = (Button) findViewById(R.id.stop_alarm_push_button);

         Bundle extras = getIntent().getExtras();

         title = extras.getString("title");
         text = extras.getString("text");

         // used to snooze the alarm, to cancel the alarm schedule or to stop the alarm
         request_code = extras.getInt("request_code");

         alarmTitle.setText(title);
         alarmText.setText(text);

         // Set all listeners
         stopButton.setOnClickListener(new PatientsValuesCheckStopAlarmButtonClickListener());
        }


     @Override
     protected void onStop()
        {
         super.onStop();

         finish();
        }


     public void setOkClicked(boolean value)
        {
         this.okClicked = value;
        }
    }

MyActivityStopAlarmButtonClickListener: MyActivityStopAlarmButtonClickListener:

package it.mypackage.listeners;

import android.app.Activity;
import android.view.View;

import java.util.Calendar;

import it.mypackage.SoundManager;
import it.mypackage.VibrationManager;
import it.mypackage.alarm.AlarmBroadcastReceiver;
import it.mypackage.alarm.AlarmSettingManager;
import it.mypackage.alarm.PatientsValuesCheckAlarmReceiverActivity;

public class MyActivityStopAlarmButtonClickListener implements View.OnClickListener
    {
     // Constructor
     public MyActivityStopAlarmButtonClickListener()
        {

        }


     @Override
     public void onClick(View v)
        {
         ((MyActivity)v.getContext()).setOkClicked(true);

         // Stop vibration
         VibrationManager vibrationManager = VibrationManager.getInstance(v.getContext().getApplicationContext());
         vibrationManager.stopVibration();

         // Stop the ringtone sound
         SoundManager soundManager = SoundManager.getInstance(v.getContext().getApplicationContext());
         soundManager.stopSound();

         // Close the reminder
         ((Activity)v.getContext()).finish();
        }
    }

VibrationManager:振动管理器:

package it.mypackage;

import android.content.Context;
import android.os.Vibrator;

public class VibrationManager
    {
     private static VibrationManager vibrationManagerInstance = null;
     private Vibrator vibrator;


     public static VibrationManager getInstance(Context context)
        {
         // Use the application context, which will ensure that you
         // don't accidentally leak an Activity's context.
         if(vibrationManagerInstance == null)
            {
             vibrationManagerInstance = new VibrationManager(context.getApplicationContext());
            }

         return vibrationManagerInstance;
        }


     // Constructor
     private VibrationManager(Context context)
        {
         vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
        }


     public void startVibration()
        {
         // vibration pattern
         long pattern[] = {60, 120, 180, 240, 300, 360, 420, 480};

         vibrator.vibrate(pattern, 1);
        }


     public void stopVibration()
        {
         vibrator.cancel();
        }
    }

SoundManager:声音管理器:

package it.mypackage;

import android.content.Context;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
import android.util.Log;

public class SoundManager
    {
     private static SoundManager soundManagerInstance = null;
     private MediaPlayer mediaPlayer;


     public static SoundManager getInstance(Context context)
        {
         // Use the application context, which will ensure that you
         // don't accidentally leak an Activity's context.
         if(soundManagerInstance == null)
            {
             soundManagerInstance = new SoundManager(context.getApplicationContext());
            }

         return soundManagerInstance;
        }


     // Constructor
     private SoundManager(Context context)
        {
         Uri ringtoneUri = getAlarmUri();
         mediaPlayer = MediaPlayer.create(context, ringtoneUri);
        }


     public void playSound()
        {
         Log.d("INFOMESSAGE", "PLAY METHOD CALLED");

         // Play an alarm ringtone
         if(mediaPlayer != null)
            {
             mediaPlayer.setLooping(true);
             mediaPlayer.start();
            }
        }


     public void stopSound()
        {
         if(mediaPlayer != null && mediaPlayer.isPlaying())
            {
             mediaPlayer.stop();
            }
        }


     //Get an alarm sound. Try for an alarm. If none set, try notification, otherwise, ringtone.
     private Uri getAlarmUri()
        {
         Uri alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);

         if(alert == null)
            {
             alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

             if(alert == null)
                {
                 alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
                }
            }

         return alert;
        }
    }

Permissions in manifest:清单中的权限:

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

Thanks for help.感谢帮助。

Now it works, I modified the SoundManager class in this way: I initialize mediaPlayer in the playSound() method, and I release it in the stopSound() method. 现在它起作用了,我以这种方式修改了SoundManager类:我在playSound()方法中初始化mediaPlayer,然后在stopSound()方法中释放它。

package it.mypackage;

import android.content.Context;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
import android.util.Log;

public class SoundManager
    {
     private static SoundManager soundManagerInstance = null;
     private MediaPlayer mediaPlayer;
     private Context context;


     public static SoundManager getInstance(Context context)
        {
         // Use the application context, which will ensure that you
         // don't accidentally leak an Activity's context.
         if(soundManagerInstance == null)
            {
             soundManagerInstance = new SoundManager(context.getApplicationContext());
            }

         return soundManagerInstance;
        }


     // Constructor
     private SoundManager(Context context)
        {
         this.context = context;
        }


     public void playSound()
        {
         Uri ringtoneUri = getAlarmUri();
         mediaPlayer = MediaPlayer.create(context, ringtoneUri);

         // Play an alarm ringtone
         if(mediaPlayer != null)
            {
             Log.d("INFOMESSAGE", "MediaPlayer playing.");

             mediaPlayer.setLooping(true);
             mediaPlayer.start();
            }
        }


     public void stopSound()
        {
         if(mediaPlayer != null && mediaPlayer.isPlaying())
            {
             mediaPlayer.stop();

             mediaPlayer.release();
             mediaPlayer = null;
            }
        }


     // Get an alarm sound. Try for an alarm. If none set, try notification, otherwise, ringtone.
     private Uri getAlarmUri()
        {
         Uri alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);

         if(alert == null)
            {
             alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

             if(alert == null)
                {
                 alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
                }
            }

         return alert;
        }
    }

After stop(), you should prepare again for next playing sound. 在stop()之后,您应该再次准备下一个播放声音。 Also, playSound should be moved to onResume not onCreate. 另外,应该将playSound移到onResume而不是onCreate上。 If possible, don't forget to release MediaPlayer after use. 如果可能,请不要忘记在使用后释放MediaPlayer。

public void stopSound()
{
    if(mediaPlayer != null && mediaPlayer.isPlaying())
    {
        mediaPlayer.stop();
        try {
            mediaPlayer.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Note : The first prepare() is called automatically in MediaPlayer.create(). 注意 :第一个prepare()在MediaPlayer.create()中自动调用。

I suggest to initialise mediaPlayer once:我建议初始化mediaPlayer一次:

if(mediaPlayer == null) 
{
    mediaPlayer = MediaPlayer.create(context, ringtoneUri);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM