AndroidRuntime: FATAL EXCEPTION: main
AndroidRuntime: Process: com.xxx.app, PID: 25339
AndroidRuntime: java.lang.SecurityException: Not allowed to delete channel XXX with a foreground service
AndroidRuntime: at android.os.Parcel.createExceptionOrNull(Parcel.java:2376)
AndroidRuntime: at android.os.Parcel.createException(Parcel.java:2360)
AndroidRuntime: at android.os.Parcel.readException(Parcel.java:2343)
AndroidRuntime: at android.os.Parcel.readException(Parcel.java:2285)
AndroidRuntime: at android.app.INotificationManager$Stub$Proxy.deleteNotificationChannel(INotificationManager.java:4040)
AndroidRuntime: at android.app.NotificationManager.deleteNotificationChannel(NotificationManager.java:909)
AndroidRuntime: at androidx.core.app.NotificationManagerCompat.deleteNotificationChannel(SourceFile:2)
AndroidRuntime: at com.gyf.cactus.ext.c$a.run(SourceFile:1)
AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:938)
AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
AndroidRuntime: at android.os.Looper.loop(Looper.java:236)
AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:8142)
AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
AndroidRuntime: Caused by: android.os.RemoteException: Remote stack trace:
AndroidRuntime: at com.android.server.notification.NotificationManagerService$10.enforceDeletingChannelHasNoFgService(NotificationManagerService.java:3427)
AndroidRuntime: at com.android.server.notification.NotificationManagerService$10.deleteNotificationChannel(NotificationManagerService.java:3440)
AndroidRuntime: at android.app.INotificationManager$Stub.onTransact(INotificationManager.java:1737)
AndroidRuntime: at android.os.Binder.execTransactInternal(Binder.java:1160)
AndroidRuntime: at android.os.Binder.execTransact(Binder.java:1129)
//获取预览窗口的宽高privatefinal TextureView.SurfaceTextureListener mSurfaceTextureListener
= new TextureView.SurfaceTextureListener() {
@Override
publicvoidonSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
openCamera(width, height);
}
@Override
publicvoidonSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
configureTransform(width, height);
}
@Override
publicbooleanonSurfaceTextureDestroyed(SurfaceTexture texture) {
returntrue;
}
@Override
publicvoidonSurfaceTextureUpdated(SurfaceTexture texture) {
}
};
//得到最佳Camera图像输出尺寸privatestatic Size chooseOptimalSize(Size[] choices, int textureViewWidth,
int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {
// Collect the supported resolutions that are at least as big as the preview Surface
List<Size> bigEnough = new ArrayList<>();
// Collect the supported resolutions that are smaller than the preview Surface
List<Size> notBigEnough = new ArrayList<>();
int w = aspectRatio.getWidth();
int h = aspectRatio.getHeight();
for (Size option : choices) {
if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight &&
option.getHeight() == option.getWidth() * h / w) {
if (option.getWidth() >= textureViewWidth &&
option.getHeight() >= textureViewHeight) {
bigEnough.add(option);
} else {
notBigEnough.add(option);
}
}
}
// Pick the smallest of those big enough. If there is no one big enough, pick the// largest of those not big enough.if (bigEnough.size() > 0) {
return Collections.min(bigEnough, new CompareSizesByArea());
} elseif (notBigEnough.size() > 0) {
return Collections.max(notBigEnough, new CompareSizesByArea());
} else {
Log.e(TAG, "Couldn't find any suitable preview size");
return choices[0];
}
}
// true means FOD project
PRODUCT_PROPERTY_OVERRIDES += ro.hardware.fp.fod=true
2.2. 指纹传感器的位置、大小(每次指纹验证都需要重新获取)
以下是 Android O 的接口:
//location of FOD sensor's top left corner in pixel, the top left corner of screen is (0,0)
//persist.sys.fp.fod.location.X_Y 表示sensor区域左上角的坐标,以pixel为单位,以物理屏幕左上角为(0,0)计算。 persist.sys.fp.fod.location.X_Y = 453,1640
//sensor的大小(单位也是pixel)
persist.sys.fp.fod.size.width_height = 173,173
以下是 Android P 的接口(应谷歌要求,需要加入「vendor」字样)
//location of FOD sensor's top left corner in pixel, the top left corner of screen is (0,0)// persist.vendor.sys.fp.fod.location.X_Y 表示sensor区域左上角的坐标,以pixel为单位,以物理屏幕左上角为(0,0)计算。
persist.vendor.sys.fp.fod.location.X_Y = 453,1640
//sensor的大小(单位也是pixel)
persist.vendor.sys.fp.fod.size.width_height = 173,173
因为同一款设备,市场上可能会同时存在 Android O 和 Android P 两个版本,所以开发者需要根据 Android 版本调用不同的接口,以获取正确的位置信息。