一、序言
对于一名移动开发者而言或或少都会遇到过系统铃声的开发,要么是自定义铃声震动,要么是调用系统铃声,要么获取系统的情景模式,对于情景模式这个来说我个人比较喜欢苹果和一加这种有快捷键的手机。
二、获取系统情景模式
/**
* 根据系统的情景模式
* @param isStart
*/
public static void showSystemDefaultRing(boolean isStart) {
// 获取手机情景模式
AudioManager audioManager = (AudioManager) App.getInstance().getSystemService(Context.AUDIO_SERVICE);
int ringerMode = audioManager.getRingerMode();
switch (ringerMode) {
case AudioManager.RINGER_MODE_NORMAL:
// 标准模式(铃声和震动)
startSystemLongRing(isStart);
startLongVibrate(isStart);
break;
case AudioManager.RINGER_MODE_SILENT:
// 静音模式
break;
case AudioManager.RINGER_MODE_VIBRATE:
// 震动模式【开启震动不要忘记系统震动权限】
startLongVibrate(isStart);
break;
default:
break;
}
}
三、播放系统铃声
有时候需要播放系统铃声,来达到一些消息显示通知
/**
* 开始长时间播放系统铃声
*
* @param isStart
*/
public static void startSystemLongRing(boolean isStart) {
if (isStart) {
Uri uri = RingtoneManager.getActualDefaultRingtoneUri(App.getInstance().getApplicationContext(), RingtoneManager.TYPE_RINGTONE);
mediaPlayer = MediaPlayer.create(App.getInstance().getApplicationContext(), uri);
mediaPlayer.setOnCompletionListener(mp -> {
mp.stop();
mp.release();
});
mediaPlayer.start();
} else if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
}
四、MediaPlayer兼容性 创建
有些机型或者API对MediaPlayer创建会出现一些错误
/**
* 消除错误日志
*
* @param context
* @return
*/
public static MediaPlayer getMediaPlayer(Context context) {
MediaPlayer mediaplayer = new MediaPlayer();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
return mediaplayer;
}
try {
Class> cMediaTimeProvider = Class.forName("android.media.MediaTimeProvider");
Class> cSubtitleController = Class.forName("android.media.SubtitleController");
Class> iSubtitleControllerAnchor = Class.forName("android.media.SubtitleController$Anchor");
Class> iSubtitleControllerListener = Class.forName("android.media.SubtitleController$Listener");
Constructor constructor = cSubtitleController.getConstructor(Context.class, cMediaTimeProvider, iSubtitleControllerListener);
Object subtitleInstance = constructor.newInstance(context, null, null);
Field f = cSubtitleController.getDeclaredField("mHandler");
f.setAccessible(true);
try {
f.set(subtitleInstance, new Handler());
} catch (IllegalAccessException e) {
return mediaplayer;
} finally {
f.setAccessible(false);
}
Method setSubtitleAnchor = mediaplayer.getClass().getMethod("setSubtitleAnchor", cSubtitleController, iSubtitleControllerAnchor);
setSubtitleAnchor.invoke(mediaplayer, subtitleInstance, null);
} catch (Exception e) {
}
return mediaplayer;
}
五、系统震动
vibrator.vibrate(longs, -1);其中long[]数组是用来表示震动的频率,-1表示不循环,大于0表示相应的循环次数
public static void startVibrate(boolean isStart) {
if (isStart) {
// 震动
vibrator = (Vibrator) App.getInstance().getSystemService(Service.VIBRATOR_SERVICE);
if (vibrator.hasVibrator()) {
long[] longs = {0, 1400};
vibrator.vibrate(longs, -1);
}
} else if (vibrator != null) {
vibrator.cancel();
vibrator = null;
}
}
private static Vibrator vibrator;
/**
* 15s震动
*/
public static void startLongVibrate(boolean isStart) {
if (isStart) {
vibrator = (Vibrator) App.getInstance().getSystemService(Service.VIBRATOR_SERVICE);
if (vibrator.hasVibrator()) {
long[] longs = {1000, 1400,
1000, 1400,
1000, 1400,
1000, 1400,
1000, 1400,
1000, 1400,
1000, 1400,
1000, 1400,
1000, 1400,
1000, 1400,
1000, 1400,
1000, 1400,
1000, 1400,
1000, 1400,
1000, 1400};
vibrator.vibrate(longs, -1);
}
} else if (vibrator != null) {
vibrator.cancel();
vibrator = null;
}
}