Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-05-31 18:03:13 +08:00
parent fef508ced6
commit 8713af4290
7 changed files with 80 additions and 47 deletions

View File

@@ -1,6 +1,8 @@
package com.example.piliplus; package com.example.piliplus;
import android.app.Activity;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.PictureInPictureParams;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutInfo;
@@ -11,6 +13,7 @@ import android.graphics.drawable.Icon;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.provider.Settings; import android.provider.Settings;
import android.util.Rational;
import androidx.annotation.Keep; import androidx.annotation.Keep;
@@ -85,4 +88,14 @@ public final class AndroidHelper {
} }
} }
} }
public static void enterPip(long engineId, int width, int height) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Activity activity = JniFlutterPlugin.getActivity(engineId);
PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder()
.setAspectRatio(new Rational(width, height));
assert activity != null;
activity.enterPictureInPictureMode(builder.build());
}
}
} }

View File

@@ -255,12 +255,11 @@ class PlPlayerController with BlockConfigMixin {
} }
} }
void enterPip({bool isAuto = false}) { void enterPip() {
if (videoPlayerController != null) { if (videoPlayerController != null) {
controls = false; controls = false;
final state = videoPlayerController!.state; final state = videoPlayerController!.state;
PageUtils.enterPip( PageUtils.enterPip(
isAuto: isAuto,
width: state.width == 0 ? width : state.width, width: state.width == 0 ? width : state.width,
height: state.height == 0 ? height : state.height, height: state.height == 0 ? height : state.height,
); );

View File

@@ -357,6 +357,47 @@ extension type AndroidHelper._(jni$_.JObject _$this) implements jni$_.JObject {
_$icon.pointer, _$icon.pointer,
).check(); ).check();
} }
static final _id_enterPip = _class.staticMethodId(
r'enterPip',
r'(JII)V',
);
static final _enterPip =
jni$_.ProtectedJniExtensions.lookup<
jni$_.NativeFunction<
jni$_.JThrowablePtr Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
jni$_.VarArgs<(jni$_.Int64, jni$_.Int32, jni$_.Int32)>,
)
>
>('globalEnv_CallStaticVoidMethod')
.asFunction<
jni$_.JThrowablePtr Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
core$_.int,
core$_.int,
core$_.int,
)
>();
/// from: `static public void enterPip(long engineId, int width, int height)`
static void enterPip(
core$_.int engineId,
core$_.int width,
core$_.int height,
) {
final _$$classRef = _class.reference;
_enterPip(
_$$classRef.pointer,
_id_enterPip.pointer,
engineId,
width,
height,
).check();
}
} }
final class $AndroidHelper$Type$ extends jni$_.JType<AndroidHelper> { final class $AndroidHelper$Type$ extends jni$_.JType<AndroidHelper> {

View File

@@ -1,14 +0,0 @@
import 'package:floating/floating.dart';
extension RationalExt on Rational {
/// Checks whether given [Rational] instance fits into Android requirements
/// or not.
///
/// Android docs specified boundaries as inclusive.
bool get fitsInAndroidRequirements {
final aspectRatio = numerator / denominator;
const min = 1 / 2.39;
const max = 2.39;
return (min <= aspectRatio) && (aspectRatio <= max);
}
}

View File

@@ -18,9 +18,9 @@ import 'package:PiliPlus/pages/contact/view.dart';
import 'package:PiliPlus/pages/fav_panel/view.dart'; import 'package:PiliPlus/pages/fav_panel/view.dart';
import 'package:PiliPlus/pages/share/view.dart'; import 'package:PiliPlus/pages/share/view.dart';
import 'package:PiliPlus/pages/webview/view.dart'; import 'package:PiliPlus/pages/webview/view.dart';
import 'package:PiliPlus/utils/android/bindings.g.dart';
import 'package:PiliPlus/utils/app_scheme.dart'; import 'package:PiliPlus/utils/app_scheme.dart';
import 'package:PiliPlus/utils/extension/context_ext.dart'; import 'package:PiliPlus/utils/extension/context_ext.dart';
import 'package:PiliPlus/utils/extension/extension.dart';
import 'package:PiliPlus/utils/extension/size_ext.dart'; import 'package:PiliPlus/utils/extension/size_ext.dart';
import 'package:PiliPlus/utils/extension/string_ext.dart'; import 'package:PiliPlus/utils/extension/string_ext.dart';
import 'package:PiliPlus/utils/global_data.dart'; import 'package:PiliPlus/utils/global_data.dart';
@@ -29,8 +29,7 @@ import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/url_utils.dart'; import 'package:PiliPlus/utils/url_utils.dart';
import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/utils.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:floating/floating.dart'; import 'package:flutter/foundation.dart' show kDebugMode, PlatformDispatcher;
import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@@ -183,22 +182,30 @@ abstract final class PageUtils {
WebViewPage.toWebView('https://www.bilibili.com/appeal/?avid=$aid'); WebViewPage.toWebView('https://www.bilibili.com/appeal/?avid=$aid');
} }
static void enterPip({int? width, int? height, bool isAuto = false}) { static bool _fitsInAndroidRequirements(int width, int height) {
if (width != null && height != null) { final aspectRatio = width / height;
Rational aspectRatio = Rational(width, height); const min = 1 / 2.39;
aspectRatio = aspectRatio.fitsInAndroidRequirements const max = 2.39;
? aspectRatio return (min <= aspectRatio) && (aspectRatio <= max);
: height > width }
? const Rational.vertical()
: const Rational.landscape(); static void enterPip({int? width, int? height}) {
Floating.enable( if (width != null &&
isAuto height != null &&
? AutoEnable(aspectRatio: aspectRatio) !_fitsInAndroidRequirements(width, height)) {
: EnableManual(aspectRatio: aspectRatio), if (height > width) {
); width = 9;
} else { height = 16;
Floating.enable(isAuto ? const AutoEnable() : const EnableManual()); } else {
width = 16;
height = 9;
}
} }
AndroidHelper.enterPip(
PlatformDispatcher.instance.engineId!,
width ?? 16,
height ?? 9,
);
} }
static Future<void> pushDynDetail( static Future<void> pushDynDetail(

View File

@@ -559,15 +559,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.1" version: "4.0.1"
floating:
dependency: "direct main"
description:
path: "."
ref: dev
resolved-ref: fdd44a501d9717ebab04e8004fca2818a6bed236
url: "https://github.com/bggRGjQaUbCoE/floating.git"
source: git
version: "3.0.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter

View File

@@ -81,10 +81,6 @@ dependencies:
ref: dev ref: dev
fixnum: ^1.1.1 fixnum: ^1.1.1
flex_seed_scheme: ^4.0.1 flex_seed_scheme: ^4.0.1
floating:
git:
url: https://github.com/bggRGjQaUbCoE/floating.git
ref: dev
flutter_cache_manager: ^3.4.1 flutter_cache_manager: ^3.4.1
flutter_html: ^3.0.0-beta.2 flutter_html: ^3.0.0-beta.2
flutter_inappwebview: ^6.1.5 flutter_inappwebview: ^6.1.5