Android MediaPlayer没有播放声音

时间:2017-03-28 09:09:01

标签: android audio android-mediaplayer

在我的Android应用中,我希望在显示特定活动时播放振动和声音。我创建了两个VibrationManager和SoundManager单例类,并在" onCreate"中启动振动和声音。活动的方法。 活动有一个停止振动和声音的按钮,并在点击时关闭活动。一切似乎都有效,除了没有播放的声音,即使" playSound()"方法已输入。此外,有时会播放声音,显然是随机逻辑......我的声音代码有什么问题?

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:

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;
        }
    }

清单中的权限:

    <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"/>

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

停止()后,您应该再次准备下一个播放声音。此外,playSound应该移动到onResume而不是onCreate。如果可能,请不要忘记在使用后释放MediaPlayer。

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

注意:在MediaPlayer.create()中自动调用第一个prepare()。

答案 1 :(得分:1)

现在它工作了,我用这种方式修改了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;
        }
    }