首先获取权限,使用到的权限不需要动态获取,仅需在Manifest.xml中定义申请即可
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
闪光灯的实现
闪光灯的实现肯定是手机的手电筒功能,隶属于Camera类控制,使用时需要检查设备是否支持手电筒,而且也需要分Android版本处理。
通过代码定时控制手电筒的开关来实现闪光灯,通过调节开关间隔来实现闪光灯调速,定时间隔控制通过rxjava3来实现,下面直接贴代码。注意在页面销毁时关闭闪光灯及释放timeDispose
private var cameraManager: CameraManager? = null
private var camera: Camera? = null
private var timeDispose: Disposable? = null
override fun onCreate(savedInstanceState: Bundle?) {
...
cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager?
setLight()
}
private fun setLight(){
timeDispose?.dispose()
if (mainStatus == STATU_OPEN) {
//开启
val lightFlashTime = when (lightType) {
TYPE_SLOWER -> {
600L
}
TYPE_FASTER -> {
150
}
else -> {
300
}
}
Observable
.interval(lightFlashTime, TimeUnit.MILLISECONDS)
.compose(SchedulerTransformer())
.subscribe(object : BaseObserver<Long>() {
override fun onSubscribe(d: Disposable) {
super.onSubscribe(d)
timeDispose = d
}
override fun onSuccess(t: Long) {
//区分android版本
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (lightIsOn) {
//关闭
try {
cameraManager?.setTorchMode("0", false)
lightIsOn = false
} catch (e: java.lang.Exception) {
e.printStackTrace()
//不支持闪光灯,提示并重置页面
ToastUtils.showShort("The current device does not support flash!")
//关闭开关
mainStatus = STATU_CLOSE
}
} else {
//打开
try {
cameraManager?.setTorchMode("0", true)
lightIsOn = true
} catch (e: java.lang.Exception) {
e.printStackTrace()
//不支持闪光灯,提示并重置页面
ToastUtils.showShort("The current device does not support flash!")
//关闭开关
mainStatus = STATU_CLOSE
}
}
} else {
val features = packageManager.systemAvailableFeatures
for (f in features) {
if (PackageManager.FEATURE_CAMERA_FLASH == f.name) { // 判断设备是否支持闪光灯
camera = Camera.open()
val parameters = camera?.parameters;
parameters?.flashMode = Camera.Parameters.FLASH_MODE_TORCH
camera?.parameters = parameters
camera?.startPreview()
} else {
//不支持闪光灯,提示并重置页面
ToastUtils.showShort("The current device does not support flash!")
//关闭开关
mainStatus = STATU_CLOSE
}
}
}
}
})
} else {
//关闭手电筒
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
timeDispose = null
try {
cameraManager?.setTorchMode("0", false)
} catch (e: Exception) {
e.printStackTrace()
}
} else {
camera?.stopPreview()
camera?.release()
camera = null
}
}
}
震动的实现
private var vibrator: Vibrator? = null
override fun onCreate(savedInstanceState: Bundle?) {
...
vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
setVibrator()
}
private fun setVibrator() {
if (mainStatus == STATU_OPEN) {
val pattern = // 指定震动模式,以毫秒为单位
when (vibratorType) {
TYPE_SLOWER -> {
longArrayOf(600, 300)
}
TYPE_FASTER -> {
longArrayOf(150, 300)
}
else -> {
longArrayOf(300, 300)
}
}
val repeat = 0 // -1表示不重复,0表示从pattern的第一个元素开始重复
vibrator?.vibrate(pattern, repeat)
} else {
vibrator?.cancel()
}
}
音频的播放
首先写了一个通用的音频播放类
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.PlaybackParams;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ToastUtils;
public class MediaPlayerHelpNoInstance {
private static MediaPlayerHelpNoInstance instance;
private Context mContext;
private MediaPlayer mMediaPlayer;
private String mPath;
private OnMediaPlayerHelperListener onMeidaPlayerHelperListener;
private OnProgressListener onProgressListener;
private boolean isPause;
private boolean isComplete = false;
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
int progress = msg.what;
if (onProgressListener != null && msg.what != -1) {
onProgressListener.onProgress(progress);
}
}
};
public MediaPlayerHelpNoInstance setOnMediaPlayerHelperListener(OnMediaPlayerHelperListener onMediaPlayerHelperListener) {
this.onMeidaPlayerHelperListener = onMediaPlayerHelperListener;
return this;
}
public void setOnProgressListener(OnProgressListener onProgressListener) {
this.onProgressListener = onProgressListener;
}
/**
* @param context 全局上下文
*/
public MediaPlayerHelpNoInstance(Context context) {
mContext = context;
mMediaPlayer = new MediaPlayer();
}
/**
* 设置 asset文件下的资源文件播放
*
* @param descriptor
*/
public void setPath(AssetFileDescriptor descriptor) {
// mMediaPlayer.stop();
// mMediaPlayer.reset();
// try {
// mMediaPlayer.setDataSource(descriptor.getFileDescriptor(),
// descriptor.getStartOffset(), descriptor.getLength());
// mMediaPlayer.prepare();
// mMediaPlayer.start();
// } catch (IOException e) {
// e.printStackTrace();
// }
/**
* 1、音乐正在播放,重置音乐播放状态
* 2、设置播放音乐路径
* 3、准备播放
*/
if (mMediaPlayer == null) {
mMediaPlayer = new MediaPlayer();
}
// 1、音乐正在播放,重置音乐播放状态
mMediaPlayer.reset();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
LogUtils.dTag("听力文件加载失败:what" + what);
mMediaPlayer.reset();
return true;
}
});
// 2、设置播放音乐路径
try {
mMediaPlayer.setDataSource(descriptor.getFileDescriptor(),
descriptor.getStartOffset(), descriptor.getLength());
} catch (Exception e) {
e.printStackTrace();
}
// 3、准备播放
try {
mMediaPlayer.prepareAsync();
} catch (IllegalStateException e) {
e.printStackTrace();
ToastUtils.showShort(e.getMessage());
}
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
start();
if (onMeidaPlayerHelperListener != null) { //取整
int time = (1000 - mp.getDuration() / 1000) + mp.getDuration();
onMeidaPlayerHelperListener.onPrepared(time);
}
}
});
// 监听音乐播放完成
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
isComplete = true;
// mMediaPlayer.reset();
if (onMeidaPlayerHelperListener != null) {
onMeidaPlayerHelperListener.onPlayComplete();
}
handler.sendEmptyMessage(-1);
}
});
}
/**
* 1、setPath:当前需要播放的音乐
* 2、start:播放音乐
* 3、pause:暂停播放
*/
/**
* 当前需要播放的音乐
*
* @param path
*/
public MediaPlayerHelpNoInstance setPath(final String path, final boolean isAutoPlay) {
/**
* 1、音乐正在播放,重置音乐播放状态
* 2、设置播放音乐路径
* 3、准备播放
*/
if (mMediaPlayer == null) {
mMediaPlayer = new MediaPlayer();
}
// 1、音乐正在播放,重置音乐播放状态
mMediaPlayer.reset();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
LogUtils.dTag("听力文件加载失败:what" + what);
mMediaPlayer.reset();
if (onMeidaPlayerHelperListener != null) {
onMeidaPlayerHelperListener.onPlayError(path);
}
return true;
}
});
mPath = path;
// 2、设置播放音乐路径
try {
String proxyUrl = mPath.replace(" ", "%20");
LogUtils.i(getClass().getSimpleName(), proxyUrl);
mMediaPlayer.setDataSource(proxyUrl);
} catch (Exception e) {
e.printStackTrace();
if (onMeidaPlayerHelperListener != null) {
onMeidaPlayerHelperListener.onPlayError(path);
}
}
// 3、准备播放
try {
mMediaPlayer.prepareAsync();
} catch (IllegalStateException e) {
e.printStackTrace();
ToastUtils.showShort(e.getMessage());
}
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
if (isAutoPlay) {
start();
}
if (onMeidaPlayerHelperListener != null) { //取整
int time = (1000 - mp.getDuration() / 1000) + mp.getDuration();
onMeidaPlayerHelperListener.onPrepared(time);
}
}
});
// 监听音乐播放完成
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
isComplete = true;
// mMediaPlayer.reset();
if (onMeidaPlayerHelperListener != null) {
onMeidaPlayerHelperListener.onPlayComplete();
}
handler.sendEmptyMessage(-1);
}
});
return this;
}
/**
*
*/
public void resume() {
isPause = false;
if (mMediaPlayer != null)
mMediaPlayer.start();
if (onMeidaPlayerHelperListener != null) {
onMeidaPlayerHelperListener.onPlayResume();
}
}
/**
* 返回正在播放的音乐路径
*
* @return
*/
public String getPath() {
return mPath;
}
/**
* 播放音乐
*/
public void start() {
if (mMediaPlayer.isPlaying()) return;
if (isComplete)
mMediaPlayer.seekTo(0);
isComplete = false;
mMediaPlayer.start();
if (onMeidaPlayerHelperListener != null) {
onMeidaPlayerHelperListener.onPlayStart();
}
isPause = false;
if (onProgressListener != null) {
startListenerProgress();
}
}
private void startListenerProgress() {
AudioThread run = new AudioThread();
Thread thread = new Thread(run);
thread.start();
}
public boolean isPlaying() {
if (mMediaPlayer != null)
return mMediaPlayer.isPlaying();
else
return false;
}
public boolean isLoop() {
if (mMediaPlayer != null)
return mMediaPlayer.isLooping();
else
return false;
}
public int getCurrPosition() {
if (mMediaPlayer != null)
return mMediaPlayer.getCurrentPosition();
else
return 0;
}
public boolean isLooping() {
if (mMediaPlayer != null)
return mMediaPlayer.isLooping();
else
return false;
}
/**
* 不涉及拖动
*/
class AudioThread implements Runnable {
@Override
public void run() {
while (true) {
try {
// 每100毫秒更新一次位置
Thread.sleep(100);
if (mMediaPlayer != null && mMediaPlayer.isPlaying() && condition()) {
handler.sendEmptyMessage(mMediaPlayer.getCurrentPosition());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/**
* 用作拖动的进度条的条件设置
*/
private boolean condition = true;
private boolean condition() {
return condition;
}
private void setCondition(boolean condition) {
this.condition = condition;
}
/**
* 暂停播放
*/
public void pause() {
isPause = true;
if (mMediaPlayer != null)
mMediaPlayer.pause();
if (onMeidaPlayerHelperListener != null) {
onMeidaPlayerHelperListener.onPlayPause();
}
}
public void destory() {
if (mMediaPlayer != null) {
if (mMediaPlayer.isPlaying())
mMediaPlayer.pause();
mMediaPlayer.reset();
mMediaPlayer.release();
mMediaPlayer = null;
mPath = null;
}
handler.removeCallbacksAndMessages(null);
}
public void stop() {
mPath = null;
if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
mMediaPlayer.seekTo(0);
}
if (onMeidaPlayerHelperListener != null) {
onMeidaPlayerHelperListener.onPlayStop();
}
}
/**
* 快进
*
* @param progress
*/
public void seekTo(int progress) {
if (mMediaPlayer != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mMediaPlayer.seekTo(progress, MediaPlayer.SEEK_CLOSEST);
} else {
mMediaPlayer.seekTo(progress);
}
}
}
/**
* 设置倍数播放
*
* @param mSpeed
*/
public void setSpeed(float mSpeed) {
if (mMediaPlayer == null)
return;
if (Build.VERSION.SDK_INT >=
Build.VERSION_CODES.M) {
PlaybackParams playbackParams = mMediaPlayer.getPlaybackParams();
playbackParams.setSpeed(mSpeed);
mMediaPlayer.setPlaybackParams(playbackParams);
}
}
/**
* 设置倍循环
*/
public void setLoop(boolean isLoop) {
if (mMediaPlayer == null)
return;
mMediaPlayer.setLooping(isLoop);
}
}
再调用帮助类来实现播放
private var audioManager: AudioManager? = null
private lateinit var playerHelp: MediaPlayerHelpNoInstance
override fun onCreate(savedInstanceState: Bundle?) {
...
audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
setAudio()
}
private fun setAudio() {
if (mainStatus == STATU_OPEN) {
//播放录音
if (playerHelp.isPlaying) {
return
}
playerHelp.isLoop = true
playerHelp.setPath(assets.openFd("warnning.mp3"))
playerHelp.setOnMediaPlayerHelperListener(object :
OnMediaPlayerHelperListener {
override fun onPrepared(duration: Int) {
}
override fun onPlayStart() {
}
override fun onPlayPause() {
}
override fun onPlayComplete() {
playerHelp.start()
}
override fun onPlayError(path: String?) {
}
override fun onPlayResume() {
}
override fun onPlayStop() {
}
})
} else {
if (playerHelp.isPlaying) {
playerHelp.pause()
}
}
}