Android P系统禁止闲置APP在后台使用麦克风的问题

知识共享许可协议 版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons

android P的系统为了进一步提高用户的安全隐私,禁止了后台闲置应用使用麦克风。

所以当一个app进入后台后,变成闲置idle状态,是无法在使用麦克风录音的。

下面的分析是从系统framework层代码入手,libaudiopolicyservice.so文件源码,来了解后台闲置app无法使用麦克风的原理,并从系统的角度,屏蔽了后台app无法使用麦克风的限制。

逻辑分析

代码路径:frameworks\av\services\audiopolicy\service\AudioPolicyService.cpp

禁止闲置app使用麦克风的逻辑是在AudioPolicyService中处理的。

安卓应用在后台一段时间后,就会被置为闲置状态(Idel),下面是几个监听应用激活,闲置状态的方法:

void AudioPolicyService::UidPolicy::onUidActive(uid_t uid) {
    updateUidCache(uid, true, true);
}

void AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) {
    updateUidCache(uid, false, false);
}

void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) {
    updateUidCache(uid, false, true);
}

都执行了updateUidCache(),当闲置Idle状态时,传入的参数是false,true.我们在来看看updateUidCache。

void AudioPolicyService::UidPolicy::updateUidCache(uid_t uid, bool active, bool insert) {
    if (isServiceUid(uid)) return;
    bool wasActive = false;
    {
        Mutex::Autolock _l(mLock);
        updateUidLocked(&mCachedUids, uid, active, insert, nullptr, &wasActive);
        // Do not notify service if currently overridden.
        if (mOverrideUids.find(uid) != mOverrideUids.end()) return;
    }
    bool nowActive = active && insert;
    if (wasActive != nowActive) notifyService(uid, nowActive);
}

updateUidCache中调用了notifyService,并把nowActive的表示传给了notifyService,Idle状态传入的nowActive是false.

void AudioPolicyService::UidPolicy::notifyService(uid_t uid, bool active) {
    sp<AudioPolicyService> service = mService.promote();
    if (service != nullptr) {
        service->setRecordSilenced(uid, !active);
    }
}

关键的函数: service->setRecordSilenced(uid, !active);

setRecordSilenced函数就是将麦克风mute掉,导致应用无法在使用麦克风进行录音了。

从系统角度解决问题:

修改notifyService为以下:

扫描二维码关注公众号,回复: 6753955 查看本文章
void AudioPolicyService::UidPolicy::notifyService(uid_t uid, bool active) {
    sp<AudioPolicyService> service = mService.promote();
    if (service != nullptr) {
    	//将active标志置为true,这样不管是闲置idle状态还是active状态,都可以使用麦克风录音
		active = true;
        service->setRecordSilenced(uid, !active);
    }
}

但是这样安卓为了保护用户隐私的初衷就改变了。

从APP角度解决问题

上述的分析中得知,系统只对后台闲置服务进行闲置,不让后台服务偷偷使用麦克风。

那么我的应用程序中,把后台服务改成前台服务,就可以解决这个问题。

目前Android9.0的前台服务中,必须弹出一个通知,告知用户,某个前台服务正在运行。

猜你喜欢

转载自blog.csdn.net/Sunxiaolin2016/article/details/92153500