E/MediaRecorder: setOutputFormat 在无效状态下调用:32 on Android 11

E/MediaRecorder: setOutputFormat called in an invalid state: 32 on Android 11

从未见过此错误,它开始出现在 Android 11 设备刚启动时从自动启动的前台服务开始视频录制时(BOOT_COMPLTED 广播)

E/MediaRecorder: setOutputFormat called in an invalid state: 32
W/System.err: java.lang.IllegalStateException
W/System.err:     at android.media.MediaRecorder.setOutputFormat(Native Method)

mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)

这里有一个有趣的事实,当服务启动时,它可以成功开始第一个视频录制,并且可以正常完成和停止视频录制(视频文件是好的并且可以播放),但是当它尝试录制下一个视频文件时,就会出现这个错误出现。

所以我检查了一下,我只有一个视频文件(来自日志的是设备启动时前台服务启动时重新排序的第一个文件)

所以服务无法录制下一个视频文件,直到我点击前台服务通知(打开我的应用程序),然后它工作正常

它在所有以前的 Android 版本 (<= 10)

上运行良好

对于Android 11,只有一个视频文件(第一个)被成功重新排序是荒谬的

是的,我知道它必须与 Android 11 https://developer.android.com/guide/components/foreground-services#bg-access-restrictions

上的那些限制有关

但我不使用录音(没有微型)MediaRecorder

我绕过了Camera从前台服务启动的限制,方法是在BOOT_COMPETED广播activity上启动此类服务,并授予SYSTEM_ALERT_WINDOW权限(绘制所有应用程序) 因为如果没有这样的许可,前台服务无法在最新的 Android 上没有用户交互的情况下启动 activity。

所以相机工作正常(因为有些黑客仍然可以在没有用户交互的情况下使用,是的......Google......),没有使用微型但仍然MediaRecorder成功记录一个视频文件,无法录制下一个。

他们没有在新的限制中提到它,Google...?

如果相机出现错误,它会显示类似这样的内容CAMERA_DISABLED (1): connectHelper:1578: Camera "0" disabled by policy

但是没有这个问题(已经绕过了这个限制),是E/MediaRecorder: setOutputFormat called in an invalid state: 32 - 你甚至在网上找不到这样的错误,哈哈:)

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

BOOT_COMPLETED 接收者

<receiver android:name=".service.BootReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>
override fun onReceive(context: Context?, intent: Intent?) {
    context ?: return
    if (intent?.action == Intent.ACTION_BOOT_COMPLETED) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (Settings.canDrawOverlays(context)) {
                Intent(context, ServiceHackActivity::class.java).apply {
                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    context.startActivity(this)
                }
            } else {
                // show error to a user: Android 11 is bad, can't do anything automatically for you
                // try to start app manually to start service to use camera for video recording
            }
        } else {
            AppForegroundService.startService(context)
        }
    }
}

p.s。除了 Settings.canDrawOverlays(context) 我们还必须检查设备是否已解锁且屏幕是否打开

activity

class ServiceHackActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        AppForegroundService.startService(this)
        finish()
    }
}

经过这些步骤后,相机可以在 Android 11 上正常打开 :) 但是在第一次录制后 MediaRecorder 出现错误,荒谬...

真烦人!他们添加了 ACCESS_BACKGROUND_LOCATION,但没有添加 ACCESS_BACKGROUND_CAMERA 等等...

现在如何实现行车记录仪应用程序?

一辆车的driver只是想启动他的设备而已,视频录制必须自动开始,没有用户交互!

行车记录仪录像机应用的自动开始录像选项:

所有这些选项都不需要用户交互...

更新

另一个有趣的事实是,当使用我的方法启动前台服务时,相机可以正常打开,但如果我们将其停止一次并尝试再次打开,那么我们将收到 Camera "0" disabled by policy 错误。

所以基本上 MediaRecorderCameraMicrophone 在 Android 11 上只工作一次,首先在前台服务中使用,但如果其中任何一个被重新启动然后你不能再使用它,直到有来自用户的交互(他必须至少启动你的应用程序一次,使 activity 可见)。

似乎 Google 犯了一个错误,它一开始就不应该工作...或者他们想做什么...

由于 Android 11 的背景限制,我决定开始正常启动 activity 而不是在 BOOT_COMPLETED 广播时完成它 当设备未锁定时,没有黑客,当这个activity 启动它还会在后台启动视频录制所需的服务。

这是 Android 11+ 设备启动时正常工作的唯一方法。