今天引入第三方aar后使用录屏功能直接报错Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PRO 。网上查了查问题说是直接targetSdk降到29以下就行,试了试的确解决了问题,但是这样改不用等发版,代码review的时候就已经被组长掐死了。看来还是得另寻方案。
这个问题说白了就是在使用系统录屏服务时在29版本以上需要开启一个前台通知,搜了搜aar包的AndroidManifest文件,发现了service的名字
<service android:name="com.hpplay.mirr.mirr.ScreenCastService" />
顺着包名找到了对应的类,完全没考虑到高级版本的事情嘛
public class ScreenCastService extends Service {
public void onStart(Intent var1, int var2) {
g.a("ScreenCastService", "-------onStart--- " + (HpplayLinkControl.getInstance().getContext() == null) + "-------" + (this.myMessageEvtReceiver == null));
if (HpplayLinkControl.getInstance().getContext() != null && this.myMessageEvtReceiver == null) {
this.myMessageEvtReceiver = new i(this);
PowerManager var3 = (PowerManager)HpplayLinkControl.getInstance().getContext().getSystemService("power");
this.mWakeLock = var3.newWakeLock(1, "com.hpplay.happycast.ScreenCastService");
this.mWakeLock.acquire();
IntentFilter var4 = new IntentFilter();
var4.addAction("com.hpplaysdk.happycast.startmirror");
HpplayLinkControl.getInstance().getContext().registerReceiver(this.myMessageEvtReceiver, var4);
if (j.n) {
this.startMirror();
}
}
}
public void onCreate() {
g.a("ScreenCastService", "-------onCreate--- " + (HpplayLinkControl.getInstance().getContext() == null));
}
}
好了,问题发现了但是这个文件在aar中如何修改呢,第一反应是我在src/main下建一个同包名的java类能不能覆盖他呢?说弄就弄,直接new + copy + build一气呵成,🐂🐸。然而编译器直接重拳出击
Type com.hpplay.mirr.mirr.ScreenCastService is defined multiple times:
TouYingProjector-master/app/build/intermediates/project_dex_archive/debug/out/com/hpplay/mirr/mirr/ScreenCastService.dex,
TouYingProjector-master/app/build/intermediates/external_libs_dex/debug/mergeExtDexDebug/classes.dex
哦吼,包名重复,看下build文件夹中生成的文件
看起来只成功了一半,那有没有什么办法解决冲突还能把我的代码放进去呢。要不直接对他使用override吧。直接一套解压->覆盖->压缩组合拳,很快啊,看看现在aar中的class文件
很好,我们的代码已经打入aar内了,接着就是运行,结果当然是是很完美的。当然这种方法只适用于放在本地的aar包,对于每次都需要远程下载的依赖是无法修改的,只能依靠Transformer在编译时插桩。
最后放上关键代码,在Service#onStart()最后调用就好了
public void createNotification() {
if (VERSION.SDK_INT >= 26) {
Intent notificationIntent = new Intent(this, ScreenCastService.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Builder notificationBuilder = (new Builder(this, this.NOTIFICATION_CHANNEL_ID)).setLargeIcon(BitmapFactory.decodeResource(this.getResources(), 2131232992)).setSmallIcon(2131232992).setContentTitle(this.getResources().getString(2131820673)).setContentText(this.getResources().getString(2131821333)).setTicker("test").setContentIntent(pendingIntent);
Notification notification = notificationBuilder.build();
NotificationChannel channel = new NotificationChannel(this.NOTIFICATION_CHANNEL_ID, this.NOTIFICATION_CHANNEL_NAME, 3);
channel.setDescription(this.NOTIFICATION_CHANNEL_DESC);
NotificationManager notificationManager = (NotificationManager)this.getSystemService("notification");
notificationManager.createNotificationChannel(channel);
this.startForeground(this.NOTIFICATION_ID, notification);
}
}