这种写法无法实现, 而且会抛出 异常: FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION , 请再次思考一下,应该怎么写,请给出比较完整的代码示例
时间: 2024-04-16 22:24:22 浏览: 188
非常抱歉给出的之前的代码存在问题。在 Android 11录制系统声音是一个比较杂的任务,并且需要使用到较低级别的 API。以下是一个较完整的代码示例,演示如何在 Android 11 上录制系统声音:
首先,在你的 AndroidManifest.xml 文件中添加以下权限:
```xml
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
```
然后,创建一个 Service 类来处理录制系统声音的逻辑。在 Service 类中,我们将使用 MediaProjectionManager 和 MediaRecorder 来进行录制。
```java
public class RecordService extends Service {
private MediaProjectionManager mediaProjectionManager;
private MediaRecorder mediaRecorder;
private VirtualDisplay virtualDisplay;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals("start")) {
startRecording();
} else if (intent.getAction().equals("stop")) {
stopRecording();
}
return START_STICKY;
}
private void startRecording() {
mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
Intent permissionIntent = mediaProjectionManager.createScreenCaptureIntent();
permissionIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(permissionIntent);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PERMISSION_CODE) {
if (resultCode == RESULT_OK) {
MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.REMOTE_SUBMIX);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/recorded_audio.3gp";
mediaRecorder.setOutputFile(filePath);
try {
mediaRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
virtualDisplay = mediaProjection.createVirtualDisplay("RecordScreen",
getWindowManager().getDefaultDisplay().getWidth(),
getWindowManager().getDefaultDisplay().getHeight(),
getResources().getDisplayMetrics().densityDpi,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mediaRecorder.getSurface(),
null);
mediaRecorder.start();
}
}
}
private void stopRecording() {
if (virtualDisplay != null) {
virtualDisplay.release();
}
if (mediaRecorder != null) {
mediaRecorder.stop();
mediaRecorder.reset();
}
}
}
```
然后,在你的 Activity 中启动 Service:
```java
Intent serviceIntent = new Intent(this, RecordService.class);
serviceIntent.setAction("start");
startService(serviceIntent);
```
以及停止录制:
```java
Intent serviceIntent = new Intent(this, RecordService.class);
serviceIntent.setAction("stop");
stopService(serviceIntent);
```
请注意,由于安全性和隐私方面的考虑,Android 11 不再允许直接录制系统声音。因此,你需要在设备上启用 “开发者选项” 中的 “录制音频” 选项,或者使用模拟器来测试这段代码。
此外,为了在 Android 11 上启动前台服务,你还需要在你的应用中请求 `FOREGROUND_SERVICE` 权限,并在 Service 的 onStartCommand 方法中使用 `startForeground` 方法。关于前台服务的详细信息,请参考 Android 官方文档。
阅读全文