Android 播放音频
例子1:
放置音频资源文件
右键src,new,Folder,Assets Folder
然后将音频文件复制到assets文件夹下
界面上2个按钮,对应点击函数为PlayMusic 和StopMusic
点击播放开始循环播放,
public class LoginActivity extends AppCompatActivity { AssetManager am; MediaPlayer player; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.test_login); am=getAssets(); } public void PlayMusic(View view) { try { player=new MediaPlayer(); AssetFileDescriptor afd = am.openFd("WarningShort.mp3"); player.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength()); player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mediaPlayer) { player.start(); } }); player.prepare(); player.start(); } catch (Exception e) { } } public void StopMusic(View view) { if (player != null) { player.stop(); } } }
额外:AssetManager可以使用open方法返回InputStream
另外一种放置资源的方法
res,New,Android Resource Directory
类型和名称都为raw
复制黏贴mp3文件。
例子2 :在Service中播放音乐
新建MyService
public class MyService extends Service { public AssetFileDescriptor afdWarning; public AssetFileDescriptor afdSheduleDone; public static final String SERVICE_LOG = "SERVICE_LOG"; public MediaPlayer player; public MyService() { } @Override public void onCreate() { try { afdSheduleDone = getAssets().openFd("sheduleDoneShort.mp3"); afdWarning = getAssets().openFd("WarningShort.mp3"); player = new MediaPlayer(); } catch (Exception e) { Log.d(SERVICE_LOG, "open resource exception"); e.printStackTrace(); } } @Override public IBinder onBind(Intent intent) { return new MyBinder(); } //生成Notification,保证后台音乐的播放 public void startForeground() { PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, LoginActivity.class),PendingIntent.FLAG_CANCEL_CURRENT); Notification notification = new Notification.Builder(this) .setContentTitle("hello").setContentText("My Service Music") .setSmallIcon(R.mipmap.ic_launcher_round) .setContentIntent(pendingIntent) .build(); startForeground(1,notification); } public class MyBinder extends Binder { public MyBinder() { startForeground(); } public void PlayMusci(int i) { Log.d(SERVICE_LOG, "Well,In Service PlayMusic called with arg "+i); AssetFileDescriptor afd=null; if(player==null) return; if (i == 1) { afd=afdSheduleDone; } else if (i == 2) { afd = afdWarning; } else { return; } if (afd == null) { return; } player.reset(); try { player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mediaPlayer) { player.start(); } }); player.prepareAsync(); player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { player.start(); } }); } catch (Exception e) { Log.d(SERVICE_LOG, "playmusic exception"); } } public void StopMusic() { if (player == null) { return; } player.stop(); } } }
界面依然2个按钮
Activity内容
public class LoginActivity extends AppCompatActivity { private MyService.MyBinder binder; private ServiceConnection connection=new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { binder=(MyService.MyBinder)iBinder; } @Override public void onServiceDisconnected(ComponentName componentName) { } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.test_login); Intent intent = new Intent(LoginActivity.this, MyService.class); startService(new Intent(getBaseContext(),MyService.class)); bindService(intent, connection, BIND_AUTO_CREATE); } public void PlayMusic(View view) { binder.PlayMusci(1); } public void StopMusic(View view) { binder.StopMusic(); } }
例子3:Android8.0之后必须使用前台Service的情况
MusicService 中的starForeground修改如下
public void startForeground() { PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class),PendingIntent.FLAG_CANCEL_CURRENT); Notification notification = new NotificationCompat.Builder(this,"foreground") .setContentTitle("hehe").setContentText("信息提示") .setSmallIcon(R.mipmap.ic_launcher_round) .setContentIntent(pendingIntent) .build(); NotificationManager notificationManager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); NotificationChannel channel=null; if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){ channel = new NotificationChannel("foreground", "foregroundName", NotificationManager.IMPORTANCE_HIGH); notificationManager.createNotificationChannel(channel); } startForeground(1,notification); }
启动和绑定服务的代码修改
private void initMusicService() { Intent musicIntent = new Intent(MainActivity.this, MusicService.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { startForegroundService(new Intent(MainActivity.this,MusicService.class)); }else { startService(new Intent(MainActivity.this,MusicService.class)); } bindService(musicIntent, connection, BIND_AUTO_CREATE); }
加上权限
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />