mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-16 23:40:10 +08:00
committed by
GitHub
parent
6a75061dbb
commit
d4d9fc3405
@@ -0,0 +1,191 @@
|
||||
package com.example.piliplus;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.app.PictureInPictureParams;
|
||||
import android.app.SearchManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.content.pm.ShortcutManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.Settings;
|
||||
import android.view.WindowManager;
|
||||
import androidx.annotation.Keep;
|
||||
import com.github.dart_lang.jni_flutter.JniFlutterPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@Keep
|
||||
public final class AndroidHelper {
|
||||
public static volatile boolean isFoldable = false;
|
||||
|
||||
private AndroidHelper() {
|
||||
}
|
||||
|
||||
private static Context getContext() {
|
||||
return JniFlutterPlugin.getApplicationContext();
|
||||
}
|
||||
|
||||
public static void back() {
|
||||
Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||
intent.addCategory(Intent.CATEGORY_HOME);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
getContext().startActivity(intent);
|
||||
}
|
||||
|
||||
public static void biliSendCommAntifraud(
|
||||
int action, long oid, int type, long rpId, long root, long parent, long ctime, @NotNull String commentText,
|
||||
String pictures, @NotNull String sourceId, long uid, @NotNull String cookie
|
||||
) {
|
||||
Intent intent = new Intent();
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.setComponent(new ComponentName(
|
||||
"icu.freedomIntrovert.biliSendCommAntifraud",
|
||||
"icu.freedomIntrovert.biliSendCommAntifraud.ByXposedLaunchedActivity"
|
||||
));
|
||||
intent.putExtra("action", action);
|
||||
intent.putExtra("oid", oid);
|
||||
intent.putExtra("type", type);
|
||||
intent.putExtra("rpid", rpId);
|
||||
intent.putExtra("root", root);
|
||||
intent.putExtra("parent", parent);
|
||||
intent.putExtra("ctime", ctime);
|
||||
intent.putExtra("comment_text", commentText);
|
||||
if (pictures != null) {
|
||||
intent.putExtra("pictures", pictures);
|
||||
}
|
||||
intent.putExtra("source_id", sourceId);
|
||||
intent.putExtra("uid", uid);
|
||||
ArrayList<String> cookiesList = new ArrayList<>(1);
|
||||
cookiesList.add(cookie);
|
||||
intent.putStringArrayListExtra("cookies", cookiesList);
|
||||
getContext().startActivity(intent);
|
||||
}
|
||||
|
||||
public static void openLinkVerifySettings() {
|
||||
Context context = getContext();
|
||||
Uri uri = Uri.parse("package:" + context.getPackageName());
|
||||
try {
|
||||
Intent intent;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
intent = new Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS, uri);
|
||||
} else {
|
||||
intent = new Intent(Intent.ACTION_MAIN, uri);
|
||||
intent.setClassName(
|
||||
"com.android.settings",
|
||||
"com.android.settings.applications.InstalledAppOpenByDefaultActivity"
|
||||
);
|
||||
}
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
} catch (Throwable ignored) {
|
||||
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, uri);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean openMusic(@NotNull String title, String artist, String album) {
|
||||
Intent intent = new Intent(MediaStore.INTENT_ACTION_MEDIA_SEARCH);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.putExtra(SearchManager.QUERY, title);
|
||||
intent.putExtra(MediaStore.EXTRA_MEDIA_TITLE, title);
|
||||
if (artist != null) {
|
||||
intent.putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist);
|
||||
}
|
||||
if (album != null) {
|
||||
intent.putExtra(MediaStore.EXTRA_MEDIA_ALBUM, album);
|
||||
}
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
|
||||
Context context = getContext();
|
||||
PackageManager pm = context.getPackageManager();
|
||||
|
||||
try {
|
||||
if (pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
|
||||
context.startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
||||
try {
|
||||
intent.setAction(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH);
|
||||
if (pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
|
||||
context.startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void setPipAutoEnterEnabled(boolean autoEnable, long engineId) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
PictureInPictureParams params = new PictureInPictureParams.Builder().setAutoEnterEnabled(autoEnable).build();
|
||||
android.app.Activity activity = JniFlutterPlugin.getActivity(engineId);
|
||||
if (activity != null) {
|
||||
activity.setPictureInPictureParams(params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int[] maxScreenSize() {
|
||||
Context context = getContext();
|
||||
WindowManager wm = context.getSystemService(WindowManager.class);
|
||||
try {
|
||||
float density = context.getResources().getDisplayMetrics().density;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
Rect maxBounds = wm.getMaximumWindowMetrics().getBounds();
|
||||
return new int[]{Math.round(maxBounds.width() / density), Math.round(maxBounds.height() / density)};
|
||||
} else {
|
||||
Point realSize = new Point();
|
||||
wm.getDefaultDisplay().getRealSize(realSize);
|
||||
return new int[]{Math.round(realSize.x / density), Math.round(realSize.y / density)};
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void createShortcut(@NotNull String id, @NotNull String uri, @NotNull String label, @NotNull String icon) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
Context context = getContext();
|
||||
ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class);
|
||||
if (shortcutManager != null && shortcutManager.isRequestPinShortcutSupported()) {
|
||||
Bitmap bitmap = BitmapFactory.decodeFile(icon);
|
||||
ShortcutInfo shortcut = new ShortcutInfo.Builder(context, id)
|
||||
.setShortLabel(label)
|
||||
.setIcon(Icon.createWithAdaptiveBitmap(bitmap))
|
||||
.setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(uri)))
|
||||
.build();
|
||||
// TODO: WorkerThread
|
||||
Intent pinIntent = shortcutManager.createShortcutResultIntent(shortcut);
|
||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(
|
||||
context, 0, pinIntent, PendingIntent.FLAG_IMMUTABLE
|
||||
);
|
||||
shortcutManager.requestPinShortcut(shortcut, pendingIntent.getIntentSender());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
public static final class ToDart {
|
||||
public static volatile Runnable onUserLeaveHint;
|
||||
public static volatile Runnable onConfigurationChanged;
|
||||
|
||||
private ToDart() {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,19 @@
|
||||
package com.example.piliplus
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.app.PictureInPictureParams
|
||||
import android.app.SearchManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.content.pm.ShortcutManager
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Point
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.MediaStore
|
||||
import android.provider.Settings
|
||||
import android.view.WindowManager.LayoutParams
|
||||
import androidx.core.net.toUri
|
||||
import com.ryanheise.audioservice.AudioServiceActivity
|
||||
import io.flutter.SystemChrome
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import io.flutter.SystemChrome
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class MainActivity : AudioServiceActivity() {
|
||||
// TODO: remove
|
||||
private lateinit var methodChannel: MethodChannel
|
||||
private var isFoldable = false
|
||||
|
||||
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||
super.configureFlutterEngine(flutterEngine)
|
||||
@@ -34,169 +21,15 @@ class MainActivity : AudioServiceActivity() {
|
||||
methodChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "PiliPlus")
|
||||
methodChannel.setMethodCallHandler { call, result ->
|
||||
when (call.method) {
|
||||
"back" -> back()
|
||||
|
||||
"biliSendCommAntifraud" -> {
|
||||
try {
|
||||
val action = call.argument<Int>("action") ?: 0
|
||||
val oid = call.argument<Number>("oid") ?: 0L
|
||||
val type = call.argument<Int>("type") ?: 0
|
||||
val rpid = call.argument<Number>("rpid") ?: 0L
|
||||
val root = call.argument<Number>("root") ?: 0L
|
||||
val parent = call.argument<Number>("parent") ?: 0L
|
||||
val ctime = call.argument<Number>("ctime") ?: 0L
|
||||
val commentText = call.argument<String>("comment_text") ?: ""
|
||||
val pictures = call.argument<String?>("pictures")
|
||||
val sourceId = call.argument<String>("source_id") ?: ""
|
||||
val uid = call.argument<Number>("uid") ?: 0L
|
||||
val cookies = call.argument<List<String>>("cookies") ?: emptyList()
|
||||
|
||||
val intent = Intent().apply {
|
||||
component = ComponentName(
|
||||
"icu.freedomIntrovert.biliSendCommAntifraud",
|
||||
"icu.freedomIntrovert.biliSendCommAntifraud.ByXposedLaunchedActivity"
|
||||
)
|
||||
putExtra("action", action)
|
||||
putExtra("oid", oid.toLong())
|
||||
putExtra("type", type)
|
||||
putExtra("rpid", rpid.toLong())
|
||||
putExtra("root", root.toLong())
|
||||
putExtra("parent", parent.toLong())
|
||||
putExtra("ctime", ctime.toLong())
|
||||
putExtra("comment_text", commentText)
|
||||
if (pictures != null)
|
||||
putExtra("pictures", pictures)
|
||||
putExtra("source_id", sourceId)
|
||||
putExtra("uid", uid.toLong())
|
||||
putStringArrayListExtra("cookies", ArrayList(cookies))
|
||||
}
|
||||
startActivity(intent)
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
}
|
||||
|
||||
"linkVerifySettings" -> {
|
||||
val uri = ("package:" + context.packageName).toUri()
|
||||
try {
|
||||
val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS, uri)
|
||||
} else {
|
||||
Intent("android.intent.action.MAIN", uri).setClassName(
|
||||
"com.android.settings",
|
||||
"com.android.settings.applications.InstalledAppOpenByDefaultActivity"
|
||||
)
|
||||
}
|
||||
context.startActivity(intent)
|
||||
} catch (_: Throwable) {
|
||||
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, uri)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
"music" -> {
|
||||
val title = call.argument<String>("title")
|
||||
val intent = Intent(MediaStore.INTENT_ACTION_MEDIA_SEARCH).apply {
|
||||
putExtra(SearchManager.QUERY, title)
|
||||
putExtra(MediaStore.EXTRA_MEDIA_TITLE, title)
|
||||
call.argument<String?>("artist")
|
||||
?.let { putExtra(MediaStore.EXTRA_MEDIA_ARTIST, it) }
|
||||
call.argument<String?>("album")
|
||||
?.let { putExtra(MediaStore.EXTRA_MEDIA_ALBUM, it) }
|
||||
|
||||
addCategory(Intent.CATEGORY_DEFAULT)
|
||||
}
|
||||
try {
|
||||
if (packageManager.resolveActivity(
|
||||
intent,
|
||||
PackageManager.MATCH_DEFAULT_ONLY
|
||||
) != null
|
||||
) {
|
||||
startActivity(intent)
|
||||
result.success(true)
|
||||
return@setMethodCallHandler
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
try {
|
||||
intent.action = MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
|
||||
if (packageManager.resolveActivity(
|
||||
intent,
|
||||
PackageManager.MATCH_DEFAULT_ONLY
|
||||
) != null
|
||||
) {
|
||||
startActivity(intent)
|
||||
result.success(true)
|
||||
return@setMethodCallHandler
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
result.success(false)
|
||||
}
|
||||
|
||||
"setPipAutoEnterEnabled" -> {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
val params = PictureInPictureParams.Builder()
|
||||
.setAutoEnterEnabled(call.argument<Boolean>("autoEnable") ?: false)
|
||||
.build()
|
||||
setPictureInPictureParams(params)
|
||||
}
|
||||
}
|
||||
|
||||
"createShortcut" -> {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
try {
|
||||
val shortcutManager =
|
||||
context.getSystemService(ShortcutManager::class.java)
|
||||
if (shortcutManager.isRequestPinShortcutSupported) {
|
||||
val id = call.argument<String>("id")!!
|
||||
val uri = call.argument<String>("uri")!!
|
||||
val label = call.argument<String>("label")!!
|
||||
val icon = call.argument<String>("icon")!!
|
||||
val bitmap = BitmapFactory.decodeFile(icon)
|
||||
val shortcut =
|
||||
ShortcutInfo.Builder(context, id)
|
||||
.setShortLabel(label)
|
||||
.setIcon(Icon.createWithAdaptiveBitmap(bitmap))
|
||||
.setIntent(Intent(Intent.ACTION_VIEW, uri.toUri()))
|
||||
.build()
|
||||
val pinIntent =
|
||||
shortcutManager.createShortcutResultIntent(shortcut)
|
||||
val pendingIntent = PendingIntent.getBroadcast(
|
||||
context, 0, pinIntent, PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
shortcutManager.requestPinShortcut(
|
||||
shortcut,
|
||||
pendingIntent.intentSender
|
||||
)
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"maxScreenSize" -> {
|
||||
maxScreenSize()?.let {
|
||||
result.success(it)
|
||||
}
|
||||
}
|
||||
|
||||
"isFoldable" -> {
|
||||
result.success(isFoldable)
|
||||
}
|
||||
|
||||
"SystemChrome.setEnabledSystemUIMode" -> {
|
||||
SystemChrome.onMethodCall(
|
||||
this,
|
||||
"SystemChrome.setEnabledSystemUIMode",
|
||||
call.argument("arguments")
|
||||
this, "SystemChrome.setEnabledSystemUIMode", call.argument("arguments")
|
||||
)
|
||||
}
|
||||
|
||||
"SystemChrome.setEnabledSystemUIOverlays" -> {
|
||||
SystemChrome.onMethodCall(
|
||||
this,
|
||||
"SystemChrome.setEnabledSystemUIOverlays",
|
||||
call.argument("arguments")
|
||||
this, "SystemChrome.setEnabledSystemUIOverlays", call.argument("arguments")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -207,57 +40,20 @@ class MainActivity : AudioServiceActivity() {
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
super.onConfigurationChanged(newConfig)
|
||||
if (isFoldable) {
|
||||
maxScreenSize()?.let {
|
||||
MethodChannel(
|
||||
flutterEngine!!.dartExecutor.binaryMessenger,
|
||||
"ScreenChannel"
|
||||
).invokeMethod("onConfigChanged", it)
|
||||
}
|
||||
if (AndroidHelper.isFoldable) {
|
||||
AndroidHelper.ToDart.onConfigurationChanged?.run()
|
||||
}
|
||||
}
|
||||
|
||||
private fun maxScreenSize(): Map<String, Int>? {
|
||||
try {
|
||||
val density = resources.displayMetrics.density
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val maxBounds = windowManager.maximumWindowMetrics.bounds
|
||||
return mapOf(
|
||||
"maxWidth" to (maxBounds.width() / density).roundToInt(),
|
||||
"maxHeight" to (maxBounds.height() / density).roundToInt(),
|
||||
)
|
||||
} else {
|
||||
val realSizePoint = Point()
|
||||
windowManager.defaultDisplay.getRealSize(realSizePoint)
|
||||
return mapOf(
|
||||
"maxWidth" to (realSizePoint.x / density).roundToInt(),
|
||||
"maxHeight" to (realSizePoint.y / density).roundToInt(),
|
||||
)
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private fun back() {
|
||||
val intent = Intent(Intent.ACTION_MAIN).apply {
|
||||
addCategory(Intent.CATEGORY_HOME)
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
}
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
window.attributes.layoutInDisplayCutoutMode =
|
||||
LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
||||
window.attributes.layoutInDisplayCutoutMode = LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
try {
|
||||
isFoldable =
|
||||
packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_HINGE_ANGLE)
|
||||
AndroidHelper.isFoldable = packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_HINGE_ANGLE)
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
}
|
||||
@@ -270,17 +66,15 @@ class MainActivity : AudioServiceActivity() {
|
||||
|
||||
override fun onUserLeaveHint() {
|
||||
super.onUserLeaveHint()
|
||||
methodChannel.invokeMethod("onUserLeaveHint", null)
|
||||
AndroidHelper.ToDart.onUserLeaveHint?.run()
|
||||
}
|
||||
|
||||
override fun onPictureInPictureModeChanged(
|
||||
isInPictureInPictureMode: Boolean,
|
||||
newConfig: Configuration?
|
||||
isInPictureInPictureMode: Boolean, newConfig: Configuration?
|
||||
) {
|
||||
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
|
||||
MethodChannel(
|
||||
flutterEngine!!.dartExecutor.binaryMessenger,
|
||||
"floating"
|
||||
).invokeMethod("onPipChanged", isInPictureInPictureMode)
|
||||
MethodChannel(flutterEngine!!.dartExecutor.binaryMessenger, "floating").invokeMethod(
|
||||
"onPipChanged", isInPictureInPictureMode
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-all.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
11
jnigen.yaml
Normal file
11
jnigen.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
output:
|
||||
dart:
|
||||
path: lib/utils/android/bindings.g.dart
|
||||
structure: single_file
|
||||
|
||||
class_path:
|
||||
- android/app/src/main/java
|
||||
|
||||
classes:
|
||||
- 'com.example.piliplus.AndroidHelper'
|
||||
- 'java.lang.Runnable'
|
||||
@@ -115,8 +115,9 @@ void main() async {
|
||||
CacheManager.autoClearCache();
|
||||
|
||||
if (PlatformUtils.isMobile) {
|
||||
if (Platform.isAndroid) MaxScreenSize.init();
|
||||
await Future.wait([
|
||||
if (Platform.isAndroid) ...[_initSdkInt(), MaxScreenSize.init()],
|
||||
if (Platform.isAndroid) _initSdkInt(),
|
||||
if (Pref.horizontalScreen) ?fullMode() else ?portraitUpMode(),
|
||||
setupServiceLocator(),
|
||||
]);
|
||||
|
||||
@@ -12,6 +12,7 @@ import 'package:PiliPlus/pages/mine/controller.dart';
|
||||
import 'package:PiliPlus/services/logger.dart';
|
||||
import 'package:PiliPlus/utils/accounts.dart';
|
||||
import 'package:PiliPlus/utils/accounts/account.dart';
|
||||
import 'package:PiliPlus/utils/android/android_helper.dart';
|
||||
import 'package:PiliPlus/utils/cache_manager.dart';
|
||||
import 'package:PiliPlus/utils/date_utils.dart';
|
||||
import 'package:PiliPlus/utils/device_utils.dart';
|
||||
@@ -177,7 +178,7 @@ Commit Hash: ${BuildConfig.commitHash}''',
|
||||
),
|
||||
if (Platform.isAndroid)
|
||||
ListTile(
|
||||
onTap: () => Utils.channel.invokeMethod('linkVerifySettings'),
|
||||
onTap: PiliAndroidHelper.openLinkVerifySettings,
|
||||
leading: const Icon(MdiIcons.linkBoxOutline),
|
||||
title: const Text('打开受支持的链接'),
|
||||
trailing: Icon(
|
||||
|
||||
@@ -13,6 +13,7 @@ import 'package:PiliPlus/pages/home/view.dart';
|
||||
import 'package:PiliPlus/pages/main/controller.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/controller.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/play_status.dart';
|
||||
import 'package:PiliPlus/utils/android/android_helper.dart';
|
||||
import 'package:PiliPlus/utils/app_scheme.dart';
|
||||
import 'package:PiliPlus/utils/extension/context_ext.dart';
|
||||
import 'package:PiliPlus/utils/extension/size_ext.dart';
|
||||
@@ -21,7 +22,6 @@ import 'package:PiliPlus/utils/mobile_observer.dart';
|
||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
import 'package:PiliPlus/utils/storage_key.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -249,9 +249,10 @@ class _MainAppState extends PopScopeState<MainApp>
|
||||
await trayManager.setContextMenu(trayMenu);
|
||||
}
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
static void _onBack() {
|
||||
if (Platform.isAndroid) {
|
||||
Utils.channel.invokeMethod('back');
|
||||
PiliAndroidHelper.back();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import 'package:PiliPlus/pages/member_pgc/view.dart';
|
||||
import 'package:PiliPlus/pages/member_shop/view.dart';
|
||||
import 'package:PiliPlus/pages/member_video_web/archive/view.dart';
|
||||
import 'package:PiliPlus/pages/member_video_web/season_series/view.dart';
|
||||
import 'package:PiliPlus/utils/android/android_helper.dart';
|
||||
import 'package:PiliPlus/utils/date_utils.dart';
|
||||
import 'package:PiliPlus/utils/extension/context_ext.dart';
|
||||
import 'package:PiliPlus/utils/extension/string_ext.dart';
|
||||
@@ -706,14 +707,11 @@ class _MemberPageState extends State<MemberPage> {
|
||||
'${_userController.userAvatar!}@200w_200h.webp'.http2https,
|
||||
));
|
||||
SmartDialog.dismiss();
|
||||
await Utils.channel.invokeMethod(
|
||||
'createShortcut',
|
||||
<String, String>{
|
||||
'id': _userController.mid.toString(),
|
||||
'uri': 'bilibili://space/${_userController.mid}',
|
||||
'label': _userController.username!,
|
||||
'icon': file.path,
|
||||
},
|
||||
PiliAndroidHelper.createShortcut(
|
||||
_userController.mid.toString(),
|
||||
'bilibili://space/${_userController.mid}',
|
||||
_userController.username!,
|
||||
file.path,
|
||||
);
|
||||
} catch (e) {
|
||||
SmartDialog.showToast(e.toString());
|
||||
|
||||
@@ -17,6 +17,7 @@ import 'package:PiliPlus/pages/common/dyn/common_dyn_page.dart';
|
||||
import 'package:PiliPlus/pages/music/controller.dart';
|
||||
import 'package:PiliPlus/pages/music/video/view.dart';
|
||||
import 'package:PiliPlus/utils/accounts.dart';
|
||||
import 'package:PiliPlus/utils/android/android_helper.dart';
|
||||
import 'package:PiliPlus/utils/date_utils.dart';
|
||||
import 'package:PiliPlus/utils/extension/get_ext.dart';
|
||||
import 'package:PiliPlus/utils/extension/iterable_ext.dart';
|
||||
@@ -691,16 +692,13 @@ class _MusicDetailPageState extends CommonDynPageState<MusicDetailPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _searchMusic(MusicDetail item) async {
|
||||
final res =
|
||||
Platform.isAndroid &&
|
||||
(await Utils.channel.invokeMethod<bool>('music', {
|
||||
'title': item.musicTitle,
|
||||
'artist': item.originArtist ?? item.originArtistList,
|
||||
'album': item.album,
|
||||
}) ??
|
||||
false);
|
||||
if (!res) {
|
||||
void _searchMusic(MusicDetail item) {
|
||||
if (!Platform.isAndroid ||
|
||||
!PiliAndroidHelper.openMusic(
|
||||
item.musicTitle!,
|
||||
item.originArtist ?? item.originArtistList,
|
||||
item.album,
|
||||
)) {
|
||||
Utils.copyText(item.musicTitle!);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ import 'package:PiliPlus/plugin/pl_player/models/video_fit_type.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart';
|
||||
import 'package:PiliPlus/services/service_locator.dart';
|
||||
import 'package:PiliPlus/utils/accounts.dart';
|
||||
import 'package:PiliPlus/utils/android/android_helper.dart';
|
||||
import 'package:PiliPlus/utils/android/bindings.g.dart';
|
||||
import 'package:PiliPlus/utils/asset_utils.dart';
|
||||
import 'package:PiliPlus/utils/device_utils.dart';
|
||||
import 'package:PiliPlus/utils/extension/box_ext.dart';
|
||||
@@ -302,9 +304,7 @@ class PlPlayerController with BlockConfigMixin {
|
||||
|
||||
void _disableAutoEnterPip() {
|
||||
if (_shouldSetPip) {
|
||||
Utils.channel.invokeMethod('setPipAutoEnterEnabled', {
|
||||
'autoEnable': false,
|
||||
});
|
||||
PiliAndroidHelper.setPipAutoEnterEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,19 +580,21 @@ class PlPlayerController with BlockConfigMixin {
|
||||
|
||||
if (Platform.isAndroid && autoPiP) {
|
||||
if (DeviceUtils.sdkInt < 36) {
|
||||
Utils.channel.setMethodCallHandler((call) async {
|
||||
if (call.method == 'onUserLeaveHint') {
|
||||
if (playerStatus.isPlaying && _isCurrVideoPage) {
|
||||
enterPip();
|
||||
}
|
||||
}
|
||||
});
|
||||
AndroidHelper$ToDart.onUserLeaveHint = Runnable.implement(
|
||||
$Runnable(run: _onUserLeaveHint),
|
||||
);
|
||||
} else {
|
||||
_shouldSetPip = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _onUserLeaveHint() {
|
||||
if (playerStatus.isPlaying && _isCurrVideoPage) {
|
||||
enterPip();
|
||||
}
|
||||
}
|
||||
|
||||
// 获取实例 传参
|
||||
static PlPlayerController getInstance({bool isLive = false}) {
|
||||
// 如果实例尚未创建,则创建一个新实例
|
||||
@@ -1631,7 +1633,8 @@ class PlPlayerController with BlockConfigMixin {
|
||||
if (showSeekPreview) {
|
||||
_clearPreview();
|
||||
}
|
||||
Utils.channel.setMethodCallHandler(null);
|
||||
AndroidHelper$ToDart.onUserLeaveHint?.release();
|
||||
AndroidHelper$ToDart.onUserLeaveHint = null;
|
||||
_timer?.cancel();
|
||||
// _position.close();
|
||||
// _playerEventSubs?.cancel();
|
||||
|
||||
108
lib/utils/android/android_helper.dart
Normal file
108
lib/utils/android/android_helper.dart
Normal file
@@ -0,0 +1,108 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:PiliPlus/utils/android/bindings.g.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:jni/jni.dart';
|
||||
|
||||
abstract final class PiliAndroidHelper {
|
||||
@pragma('vm:prefer-inline')
|
||||
static void back() => AndroidHelper.back();
|
||||
|
||||
static void biliSendCommAntifraud(
|
||||
int action,
|
||||
int oid,
|
||||
int type,
|
||||
int rpId,
|
||||
int root,
|
||||
int parent,
|
||||
int ctime,
|
||||
String commentText,
|
||||
List pictures,
|
||||
String sourceId,
|
||||
int uid,
|
||||
String cookie,
|
||||
) {
|
||||
final jCommentText = commentText.toJString();
|
||||
final jSourceId = sourceId.toJString();
|
||||
final jCookie = cookie.toJString();
|
||||
final jPictures = pictures.isEmpty
|
||||
? null
|
||||
: jsonEncode(pictures).toJString();
|
||||
|
||||
try {
|
||||
AndroidHelper.biliSendCommAntifraud(
|
||||
action,
|
||||
oid,
|
||||
type,
|
||||
rpId,
|
||||
root,
|
||||
parent,
|
||||
ctime,
|
||||
jCommentText,
|
||||
jPictures,
|
||||
jSourceId,
|
||||
uid,
|
||||
jCookie,
|
||||
);
|
||||
} catch (e) {
|
||||
Utils.reportError(e);
|
||||
} finally {
|
||||
jCommentText.release();
|
||||
jSourceId.release();
|
||||
jCookie.release();
|
||||
jPictures?.release();
|
||||
}
|
||||
}
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
static void openLinkVerifySettings() =>
|
||||
AndroidHelper.openLinkVerifySettings();
|
||||
|
||||
static bool openMusic(String title, String? artist, String? album) {
|
||||
final jTitle = title.toJString();
|
||||
final jArtist = artist?.toJString();
|
||||
final jAlbum = album?.toJString();
|
||||
try {
|
||||
return AndroidHelper.openMusic(jTitle, jArtist, jAlbum);
|
||||
} finally {
|
||||
jTitle.release();
|
||||
jArtist?.release();
|
||||
jAlbum?.release();
|
||||
}
|
||||
}
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
static void setPipAutoEnterEnabled(bool autoEnable) =>
|
||||
AndroidHelper.setPipAutoEnterEnabled(
|
||||
autoEnable,
|
||||
PlatformDispatcher.instance.engineId!,
|
||||
);
|
||||
|
||||
static (int, int)? maxScreenSize() {
|
||||
final jIArr = AndroidHelper.maxScreenSize();
|
||||
if (jIArr != null) {
|
||||
try {
|
||||
return (jIArr[0], jIArr[1]);
|
||||
} finally {
|
||||
jIArr.release();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static void createShortcut(String id, String uri, String label, String path) {
|
||||
final jId = id.toJString();
|
||||
final jUri = uri.toJString();
|
||||
final jLabel = label.toJString();
|
||||
final jPath = path.toJString();
|
||||
try {
|
||||
AndroidHelper.createShortcut(jId, jUri, jLabel, jPath);
|
||||
} finally {
|
||||
jId.release();
|
||||
jUri.release();
|
||||
jLabel.release();
|
||||
jPath.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
586
lib/utils/android/bindings.g.dart
Normal file
586
lib/utils/android/bindings.g.dart
Normal file
@@ -0,0 +1,586 @@
|
||||
// AUTO GENERATED BY JNIGEN 0.17.0. DO NOT EDIT!
|
||||
|
||||
// ignore_for_file: annotate_overrides
|
||||
// ignore_for_file: argument_type_not_assignable
|
||||
// ignore_for_file: camel_case_extensions
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: comment_references
|
||||
// ignore_for_file: doc_directive_unknown
|
||||
// ignore_for_file: file_names
|
||||
// ignore_for_file: inference_failure_on_untyped_parameter
|
||||
// ignore_for_file: invalid_internal_annotation
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
// ignore_for_file: library_prefixes
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
// ignore_for_file: no_leading_underscores_for_local_identifiers
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: only_throw_errors
|
||||
// ignore_for_file: overridden_fields
|
||||
// ignore_for_file: prefer_double_quotes
|
||||
// ignore_for_file: unintended_html_in_doc_comment
|
||||
// ignore_for_file: unnecessary_cast
|
||||
// ignore_for_file: unnecessary_non_null_assertion
|
||||
// ignore_for_file: unnecessary_parenthesis
|
||||
// ignore_for_file: unused_element
|
||||
// ignore_for_file: unused_field
|
||||
// ignore_for_file: unused_import
|
||||
// ignore_for_file: unused_local_variable
|
||||
// ignore_for_file: unused_shown_name
|
||||
// ignore_for_file: use_super_parameters
|
||||
|
||||
import 'dart:core' as core$_;
|
||||
import 'dart:core' show Object, String;
|
||||
|
||||
import 'package:jni/_internal.dart' as jni$_;
|
||||
import 'package:jni/jni.dart' as jni$_;
|
||||
|
||||
const _$jniVersionCheck = jni$_.JniVersionCheck(1, 0);
|
||||
|
||||
/// from: `com.example.piliplus.AndroidHelper$ToDart`
|
||||
extension type AndroidHelper$ToDart._(jni$_.JObject _$this)
|
||||
implements jni$_.JObject {
|
||||
static final _class = jni$_.JClass.forName(
|
||||
r'com/example/piliplus/AndroidHelper$ToDart',
|
||||
);
|
||||
|
||||
/// The type which includes information such as the signature of this class.
|
||||
static const jni$_.JType<AndroidHelper$ToDart> type =
|
||||
$AndroidHelper$ToDart$Type$();
|
||||
static final _id_onUserLeaveHint = _class.staticFieldId(
|
||||
r'onUserLeaveHint',
|
||||
r'Ljava/lang/Runnable;',
|
||||
);
|
||||
|
||||
/// from: `static public bridge java.lang.Runnable onUserLeaveHint`
|
||||
/// The returned object must be released after use, by calling the [release] method.
|
||||
static Runnable? get onUserLeaveHint =>
|
||||
_id_onUserLeaveHint.getNullable(_class, Runnable.type) as Runnable?;
|
||||
|
||||
/// from: `static public bridge java.lang.Runnable onUserLeaveHint`
|
||||
/// The returned object must be released after use, by calling the [release] method.
|
||||
static set onUserLeaveHint(Runnable? value) =>
|
||||
_id_onUserLeaveHint.set(_class, Runnable.type, value);
|
||||
|
||||
static final _id_onConfigurationChanged = _class.staticFieldId(
|
||||
r'onConfigurationChanged',
|
||||
r'Ljava/lang/Runnable;',
|
||||
);
|
||||
|
||||
/// from: `static public bridge java.lang.Runnable onConfigurationChanged`
|
||||
/// The returned object must be released after use, by calling the [release] method.
|
||||
static Runnable? get onConfigurationChanged =>
|
||||
_id_onConfigurationChanged.getNullable(_class, Runnable.type)
|
||||
as Runnable?;
|
||||
|
||||
/// from: `static public bridge java.lang.Runnable onConfigurationChanged`
|
||||
/// The returned object must be released after use, by calling the [release] method.
|
||||
static set onConfigurationChanged(Runnable? value) =>
|
||||
_id_onConfigurationChanged.set(_class, Runnable.type, value);
|
||||
}
|
||||
|
||||
final class $AndroidHelper$ToDart$Type$
|
||||
extends jni$_.JType<AndroidHelper$ToDart> {
|
||||
@jni$_.internal
|
||||
const $AndroidHelper$ToDart$Type$();
|
||||
|
||||
@jni$_.internal
|
||||
@core$_.override
|
||||
String get signature => r'Lcom/example/piliplus/AndroidHelper$ToDart;';
|
||||
}
|
||||
|
||||
/// from: `com.example.piliplus.AndroidHelper`
|
||||
extension type AndroidHelper._(jni$_.JObject _$this) implements jni$_.JObject {
|
||||
static final _class = jni$_.JClass.forName(
|
||||
r'com/example/piliplus/AndroidHelper',
|
||||
);
|
||||
|
||||
/// The type which includes information such as the signature of this class.
|
||||
static const jni$_.JType<AndroidHelper> type = $AndroidHelper$Type$();
|
||||
static final _id_isFoldable = _class.staticFieldId(
|
||||
r'isFoldable',
|
||||
r'Z',
|
||||
);
|
||||
|
||||
/// from: `static public bridge boolean isFoldable`
|
||||
static core$_.bool get isFoldable =>
|
||||
_id_isFoldable.getNullable(_class, jni$_.jboolean.type) as core$_.bool;
|
||||
|
||||
/// from: `static public bridge boolean isFoldable`
|
||||
static set isFoldable(core$_.bool value) =>
|
||||
_id_isFoldable.set(_class, jni$_.jboolean.type, value);
|
||||
|
||||
static final _id_back = _class.staticMethodId(
|
||||
r'back',
|
||||
r'()V',
|
||||
);
|
||||
|
||||
static final _back =
|
||||
jni$_.ProtectedJniExtensions.lookup<
|
||||
jni$_.NativeFunction<
|
||||
jni$_.JThrowablePtr Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
)
|
||||
>
|
||||
>('globalEnv_CallStaticVoidMethod')
|
||||
.asFunction<
|
||||
jni$_.JThrowablePtr Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
)
|
||||
>();
|
||||
|
||||
/// from: `static public void back()`
|
||||
static void back() {
|
||||
final _$$classRef = _class.reference;
|
||||
_back(_$$classRef.pointer, _id_back.pointer).check();
|
||||
}
|
||||
|
||||
static final _id_biliSendCommAntifraud = _class.staticMethodId(
|
||||
r'biliSendCommAntifraud',
|
||||
r'(IJIJJJJLjava/lang/String;Ljava/lang/String;Ljava/lang/String;JLjava/lang/String;)V',
|
||||
);
|
||||
|
||||
static final _biliSendCommAntifraud =
|
||||
jni$_.ProtectedJniExtensions.lookup<
|
||||
jni$_.NativeFunction<
|
||||
jni$_.JThrowablePtr Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
jni$_.VarArgs<
|
||||
(
|
||||
jni$_.Int32,
|
||||
jni$_.Int64,
|
||||
jni$_.Int32,
|
||||
jni$_.Int64,
|
||||
jni$_.Int64,
|
||||
jni$_.Int64,
|
||||
jni$_.Int64,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.Int64,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
)
|
||||
>,
|
||||
)
|
||||
>
|
||||
>('globalEnv_CallStaticVoidMethod')
|
||||
.asFunction<
|
||||
jni$_.JThrowablePtr Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
core$_.int,
|
||||
core$_.int,
|
||||
core$_.int,
|
||||
core$_.int,
|
||||
core$_.int,
|
||||
core$_.int,
|
||||
core$_.int,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
core$_.int,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
)
|
||||
>();
|
||||
|
||||
/// from: `static public void biliSendCommAntifraud(int i, long j, int i1, long j1, long j2, long j3, long j4, java.lang.String string, java.lang.String string1, java.lang.String string2, long j5, java.lang.String string3)`
|
||||
static void biliSendCommAntifraud(
|
||||
core$_.int i,
|
||||
core$_.int j,
|
||||
core$_.int i1,
|
||||
core$_.int j1,
|
||||
core$_.int j2,
|
||||
core$_.int j3,
|
||||
core$_.int j4,
|
||||
jni$_.JString string,
|
||||
jni$_.JString? string1,
|
||||
jni$_.JString string2,
|
||||
core$_.int j5,
|
||||
jni$_.JString string3,
|
||||
) {
|
||||
final _$$classRef = _class.reference;
|
||||
final _$string = string.reference;
|
||||
final _$string1 = string1?.reference ?? jni$_.jNullReference;
|
||||
final _$string2 = string2.reference;
|
||||
final _$string3 = string3.reference;
|
||||
_biliSendCommAntifraud(
|
||||
_$$classRef.pointer,
|
||||
_id_biliSendCommAntifraud.pointer,
|
||||
i,
|
||||
j,
|
||||
i1,
|
||||
j1,
|
||||
j2,
|
||||
j3,
|
||||
j4,
|
||||
_$string.pointer,
|
||||
_$string1.pointer,
|
||||
_$string2.pointer,
|
||||
j5,
|
||||
_$string3.pointer,
|
||||
).check();
|
||||
}
|
||||
|
||||
static final _id_openLinkVerifySettings = _class.staticMethodId(
|
||||
r'openLinkVerifySettings',
|
||||
r'()V',
|
||||
);
|
||||
|
||||
static final _openLinkVerifySettings =
|
||||
jni$_.ProtectedJniExtensions.lookup<
|
||||
jni$_.NativeFunction<
|
||||
jni$_.JThrowablePtr Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
)
|
||||
>
|
||||
>('globalEnv_CallStaticVoidMethod')
|
||||
.asFunction<
|
||||
jni$_.JThrowablePtr Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
)
|
||||
>();
|
||||
|
||||
/// from: `static public void openLinkVerifySettings()`
|
||||
static void openLinkVerifySettings() {
|
||||
final _$$classRef = _class.reference;
|
||||
_openLinkVerifySettings(
|
||||
_$$classRef.pointer,
|
||||
_id_openLinkVerifySettings.pointer,
|
||||
).check();
|
||||
}
|
||||
|
||||
static final _id_openMusic = _class.staticMethodId(
|
||||
r'openMusic',
|
||||
r'(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z',
|
||||
);
|
||||
|
||||
static final _openMusic =
|
||||
jni$_.ProtectedJniExtensions.lookup<
|
||||
jni$_.NativeFunction<
|
||||
jni$_.JniResult Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
jni$_.VarArgs<
|
||||
(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
)
|
||||
>,
|
||||
)
|
||||
>
|
||||
>('globalEnv_CallStaticBooleanMethod')
|
||||
.asFunction<
|
||||
jni$_.JniResult Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
)
|
||||
>();
|
||||
|
||||
/// from: `static public boolean openMusic(java.lang.String string, java.lang.String string1, java.lang.String string2)`
|
||||
static core$_.bool openMusic(
|
||||
jni$_.JString string,
|
||||
jni$_.JString? string1,
|
||||
jni$_.JString? string2,
|
||||
) {
|
||||
final _$$classRef = _class.reference;
|
||||
final _$string = string.reference;
|
||||
final _$string1 = string1?.reference ?? jni$_.jNullReference;
|
||||
final _$string2 = string2?.reference ?? jni$_.jNullReference;
|
||||
return _openMusic(
|
||||
_$$classRef.pointer,
|
||||
_id_openMusic.pointer,
|
||||
_$string.pointer,
|
||||
_$string1.pointer,
|
||||
_$string2.pointer,
|
||||
).boolean;
|
||||
}
|
||||
|
||||
static final _id_setPipAutoEnterEnabled = _class.staticMethodId(
|
||||
r'setPipAutoEnterEnabled',
|
||||
r'(ZJ)V',
|
||||
);
|
||||
|
||||
static final _setPipAutoEnterEnabled =
|
||||
jni$_.ProtectedJniExtensions.lookup<
|
||||
jni$_.NativeFunction<
|
||||
jni$_.JThrowablePtr Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
jni$_.VarArgs<(jni$_.Int32, jni$_.Int64)>,
|
||||
)
|
||||
>
|
||||
>('globalEnv_CallStaticVoidMethod')
|
||||
.asFunction<
|
||||
jni$_.JThrowablePtr Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
core$_.int,
|
||||
core$_.int,
|
||||
)
|
||||
>();
|
||||
|
||||
/// from: `static public void setPipAutoEnterEnabled(boolean z, long j)`
|
||||
static void setPipAutoEnterEnabled(
|
||||
core$_.bool z,
|
||||
core$_.int j,
|
||||
) {
|
||||
final _$$classRef = _class.reference;
|
||||
_setPipAutoEnterEnabled(
|
||||
_$$classRef.pointer,
|
||||
_id_setPipAutoEnterEnabled.pointer,
|
||||
z ? 1 : 0,
|
||||
j,
|
||||
).check();
|
||||
}
|
||||
|
||||
static final _id_maxScreenSize = _class.staticMethodId(
|
||||
r'maxScreenSize',
|
||||
r'()[I',
|
||||
);
|
||||
|
||||
static final _maxScreenSize =
|
||||
jni$_.ProtectedJniExtensions.lookup<
|
||||
jni$_.NativeFunction<
|
||||
jni$_.JniResult Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
)
|
||||
>
|
||||
>('globalEnv_CallStaticObjectMethod')
|
||||
.asFunction<
|
||||
jni$_.JniResult Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
)
|
||||
>();
|
||||
|
||||
/// from: `static public int[] maxScreenSize()`
|
||||
/// The returned object must be released after use, by calling the [release] method.
|
||||
static jni$_.JIntArray? maxScreenSize() {
|
||||
final _$$classRef = _class.reference;
|
||||
return _maxScreenSize(
|
||||
_$$classRef.pointer,
|
||||
_id_maxScreenSize.pointer,
|
||||
).object<jni$_.JIntArray?>();
|
||||
}
|
||||
|
||||
static final _id_createShortcut = _class.staticMethodId(
|
||||
r'createShortcut',
|
||||
r'(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V',
|
||||
);
|
||||
|
||||
static final _createShortcut =
|
||||
jni$_.ProtectedJniExtensions.lookup<
|
||||
jni$_.NativeFunction<
|
||||
jni$_.JThrowablePtr Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
jni$_.VarArgs<
|
||||
(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
)
|
||||
>,
|
||||
)
|
||||
>
|
||||
>('globalEnv_CallStaticVoidMethod')
|
||||
.asFunction<
|
||||
jni$_.JThrowablePtr Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
)
|
||||
>();
|
||||
|
||||
/// from: `static public void createShortcut(java.lang.String string, java.lang.String string1, java.lang.String string2, java.lang.String string3)`
|
||||
static void createShortcut(
|
||||
jni$_.JString string,
|
||||
jni$_.JString string1,
|
||||
jni$_.JString string2,
|
||||
jni$_.JString string3,
|
||||
) {
|
||||
final _$$classRef = _class.reference;
|
||||
final _$string = string.reference;
|
||||
final _$string1 = string1.reference;
|
||||
final _$string2 = string2.reference;
|
||||
final _$string3 = string3.reference;
|
||||
_createShortcut(
|
||||
_$$classRef.pointer,
|
||||
_id_createShortcut.pointer,
|
||||
_$string.pointer,
|
||||
_$string1.pointer,
|
||||
_$string2.pointer,
|
||||
_$string3.pointer,
|
||||
).check();
|
||||
}
|
||||
}
|
||||
|
||||
final class $AndroidHelper$Type$ extends jni$_.JType<AndroidHelper> {
|
||||
@jni$_.internal
|
||||
const $AndroidHelper$Type$();
|
||||
|
||||
@jni$_.internal
|
||||
@core$_.override
|
||||
String get signature => r'Lcom/example/piliplus/AndroidHelper;';
|
||||
}
|
||||
|
||||
/// from: `java.lang.Runnable`
|
||||
extension type Runnable._(jni$_.JObject _$this) implements jni$_.JObject {
|
||||
static final _class = jni$_.JClass.forName(r'java/lang/Runnable');
|
||||
|
||||
/// The type which includes information such as the signature of this class.
|
||||
static const jni$_.JType<Runnable> type = $Runnable$Type$();
|
||||
|
||||
/// Maps a specific port to the implemented interface.
|
||||
static final core$_.Map<core$_.int, $Runnable> _$impls = {};
|
||||
static jni$_.JObjectPtr _$invoke(
|
||||
core$_.int port,
|
||||
jni$_.JObjectPtr descriptor,
|
||||
jni$_.JObjectPtr args,
|
||||
) {
|
||||
return _$invokeMethod(
|
||||
port,
|
||||
jni$_.MethodInvocation.fromAddresses(
|
||||
0,
|
||||
descriptor.address,
|
||||
args.address,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static final jni$_.Pointer<
|
||||
jni$_.NativeFunction<
|
||||
jni$_.JObjectPtr Function(jni$_.Int64, jni$_.JObjectPtr, jni$_.JObjectPtr)
|
||||
>
|
||||
>
|
||||
_$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
|
||||
|
||||
static jni$_.Pointer<jni$_.Void> _$invokeMethod(
|
||||
core$_.int $p,
|
||||
jni$_.MethodInvocation $i,
|
||||
) {
|
||||
try {
|
||||
final $d = $i.methodDescriptor.toDartString(releaseOriginal: true);
|
||||
final $a = $i.args;
|
||||
if ($d == r'run()V') {
|
||||
_$impls[$p]!.run();
|
||||
return jni$_.nullptr;
|
||||
}
|
||||
} catch (e) {
|
||||
return jni$_.ProtectedJniExtensions.newDartException(e);
|
||||
}
|
||||
return jni$_.nullptr;
|
||||
}
|
||||
|
||||
static void implementIn(
|
||||
jni$_.JImplementer implementer,
|
||||
$Runnable $impl,
|
||||
) {
|
||||
late final jni$_.RawReceivePort $p;
|
||||
$p = jni$_.RawReceivePort(($m) {
|
||||
if ($m == null) {
|
||||
_$impls.remove($p.sendPort.nativePort);
|
||||
$p.close();
|
||||
return;
|
||||
}
|
||||
final $i = jni$_.MethodInvocation.fromMessage($m);
|
||||
final $r = _$invokeMethod($p.sendPort.nativePort, $i);
|
||||
jni$_.ProtectedJniExtensions.returnResult($i.result, $r);
|
||||
});
|
||||
implementer.add(
|
||||
r'java.lang.Runnable',
|
||||
$p,
|
||||
_$invokePointer,
|
||||
[
|
||||
if ($impl.run$async) r'run()V',
|
||||
],
|
||||
);
|
||||
final $a = $p.sendPort.nativePort;
|
||||
_$impls[$a] = $impl;
|
||||
}
|
||||
|
||||
factory Runnable.implement(
|
||||
$Runnable $impl,
|
||||
) {
|
||||
final $i = jni$_.JImplementer();
|
||||
implementIn($i, $impl);
|
||||
return $i.implement<Runnable>();
|
||||
}
|
||||
}
|
||||
|
||||
extension Runnable$$Methods on Runnable {
|
||||
static final _id_run = Runnable._class.instanceMethodId(
|
||||
r'run',
|
||||
r'()V',
|
||||
);
|
||||
|
||||
static final _run =
|
||||
jni$_.ProtectedJniExtensions.lookup<
|
||||
jni$_.NativeFunction<
|
||||
jni$_.JThrowablePtr Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
)
|
||||
>
|
||||
>('globalEnv_CallVoidMethod')
|
||||
.asFunction<
|
||||
jni$_.JThrowablePtr Function(
|
||||
jni$_.Pointer<jni$_.Void>,
|
||||
jni$_.JMethodIDPtr,
|
||||
)
|
||||
>();
|
||||
|
||||
/// from: `public abstract void run()`
|
||||
void run() {
|
||||
final _$$selfRef = reference;
|
||||
_run(_$$selfRef.pointer, _id_run.pointer).check();
|
||||
}
|
||||
}
|
||||
|
||||
abstract base mixin class $Runnable {
|
||||
factory $Runnable({
|
||||
required void Function() run,
|
||||
core$_.bool run$async,
|
||||
}) = _$Runnable;
|
||||
|
||||
void run();
|
||||
core$_.bool get run$async => false;
|
||||
}
|
||||
|
||||
final class _$Runnable with $Runnable {
|
||||
_$Runnable({
|
||||
required void Function() run,
|
||||
this.run$async = false,
|
||||
}) : _run = run;
|
||||
|
||||
final void Function() _run;
|
||||
final core$_.bool run$async;
|
||||
|
||||
void run() {
|
||||
return _run();
|
||||
}
|
||||
}
|
||||
|
||||
final class $Runnable$Type$ extends jni$_.JType<Runnable> {
|
||||
@jni$_.internal
|
||||
const $Runnable$Type$();
|
||||
|
||||
@jni$_.internal
|
||||
@core$_.override
|
||||
String get signature => r'Ljava/lang/Runnable;';
|
||||
}
|
||||
@@ -1,36 +1,26 @@
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:flutter/services.dart' show MethodChannel;
|
||||
import 'package:PiliPlus/utils/android/android_helper.dart';
|
||||
import 'package:PiliPlus/utils/android/bindings.g.dart';
|
||||
|
||||
abstract final class MaxScreenSize {
|
||||
static int? _maxWidth;
|
||||
static int? _maxHeight;
|
||||
|
||||
static Future<void> init() {
|
||||
return Future.wait([_initFoldable(), _initScreenSize()]);
|
||||
}
|
||||
|
||||
static Future<void> _initFoldable() async {
|
||||
final isFoldable = await Utils.channel.invokeMethod('isFoldable');
|
||||
if (isFoldable == true) {
|
||||
const MethodChannel('ScreenChannel').setMethodCallHandler((call) {
|
||||
if (call.method == 'onConfigChanged') {
|
||||
_handleRes(call.arguments);
|
||||
}
|
||||
return Future.syncValue(null);
|
||||
});
|
||||
static void init() {
|
||||
_initScreenSize();
|
||||
if (AndroidHelper.isFoldable) {
|
||||
AndroidHelper$ToDart.onUserLeaveHint = Runnable.implement(
|
||||
$Runnable(run: _initScreenSize),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> _initScreenSize() {
|
||||
return Utils.channel.invokeMethod('maxScreenSize').then(_handleRes);
|
||||
}
|
||||
|
||||
static void _handleRes(dynamic res) {
|
||||
if (res is Map) {
|
||||
_maxWidth = res['maxWidth'];
|
||||
_maxHeight = res['maxHeight'];
|
||||
static void _initScreenSize() {
|
||||
final size = PiliAndroidHelper.maxScreenSize();
|
||||
if (size != null) {
|
||||
_maxWidth = size.$1;
|
||||
_maxHeight = size.$2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'dart:convert' show jsonEncode;
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
import 'package:PiliPlus/grpc/bilibili/main/community/reply/v1.pb.dart'
|
||||
@@ -8,6 +7,7 @@ import 'package:PiliPlus/http/reply.dart';
|
||||
import 'package:PiliPlus/models/common/reply/reply_sort_type.dart';
|
||||
import 'package:PiliPlus/utils/accounts.dart';
|
||||
import 'package:PiliPlus/utils/accounts/account.dart';
|
||||
import 'package:PiliPlus/utils/android/android_helper.dart';
|
||||
import 'package:PiliPlus/utils/extension/iterable_ext.dart';
|
||||
import 'package:PiliPlus/utils/extension/theme_ext.dart';
|
||||
import 'package:PiliPlus/utils/id_utils.dart';
|
||||
@@ -55,11 +55,11 @@ abstract final class ReplyUtils {
|
||||
required int type,
|
||||
required int id,
|
||||
required String message,
|
||||
dynamic root,
|
||||
dynamic parent,
|
||||
dynamic ctime,
|
||||
List? pictures,
|
||||
dynamic mid,
|
||||
required int root,
|
||||
required int parent,
|
||||
required int ctime,
|
||||
required List pictures,
|
||||
required int mid,
|
||||
bool isManual = false,
|
||||
required bool biliSendCommAntifraud,
|
||||
required sourceId,
|
||||
@@ -67,27 +67,24 @@ abstract final class ReplyUtils {
|
||||
// biliSendCommAntifraud
|
||||
if (Platform.isAndroid && biliSendCommAntifraud) {
|
||||
try {
|
||||
final String cookieString = Accounts.main.cookieJar
|
||||
final cookieString = Accounts.main.cookieJar
|
||||
.toJson()
|
||||
.entries
|
||||
.map((i) => '${i.key}=${i.value}')
|
||||
.join(';');
|
||||
Utils.channel.invokeMethod(
|
||||
'biliSendCommAntifraud',
|
||||
{
|
||||
'action': 0,
|
||||
'oid': oid,
|
||||
'type': type,
|
||||
'rpid': id,
|
||||
'root': root,
|
||||
'parent': parent,
|
||||
'ctime': ctime,
|
||||
'comment_text': message,
|
||||
if (pictures?.isNotEmpty == true) 'pictures': jsonEncode(pictures),
|
||||
'source_id': '$sourceId',
|
||||
'uid': mid,
|
||||
'cookies': [cookieString],
|
||||
},
|
||||
PiliAndroidHelper.biliSendCommAntifraud(
|
||||
0,
|
||||
oid,
|
||||
type,
|
||||
id,
|
||||
root,
|
||||
parent,
|
||||
ctime,
|
||||
message,
|
||||
pictures,
|
||||
sourceId,
|
||||
mid,
|
||||
cookieString,
|
||||
);
|
||||
} catch (e) {
|
||||
if (kDebugMode) debugPrint('biliSendCommAntifraud: $e');
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
import 'dart:convert' show JsonEncoder, base64;
|
||||
import 'dart:math' show Random;
|
||||
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:catcher_2/catcher_2.dart';
|
||||
import 'package:flutter/services.dart'
|
||||
show Clipboard, ClipboardData, MethodChannel;
|
||||
import 'package:flutter/services.dart' show Clipboard, ClipboardData;
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
|
||||
abstract final class Utils {
|
||||
static final random = Random();
|
||||
|
||||
static const channel = MethodChannel(Constants.appName);
|
||||
|
||||
static const jsonEncoder = JsonEncoder.withIndent(' ');
|
||||
|
||||
static final numericRegex = RegExp(r'^[\d\.]+$');
|
||||
|
||||
19
pubspec.lock
19
pubspec.lock
@@ -268,6 +268,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
cli_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_config
|
||||
sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -994,7 +1002,7 @@ packages:
|
||||
source: hosted
|
||||
version: "0.6.1"
|
||||
jni:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: jni
|
||||
sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f
|
||||
@@ -1009,6 +1017,15 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
jnigen:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
path: "pkgs/jnigen"
|
||||
ref: HEAD
|
||||
resolved-ref: "14f4ce655c0cebb203777b8200303a9bc1f0b04e"
|
||||
url: "https://github.com/dart-lang/native.git"
|
||||
source: git
|
||||
version: "0.17.0-wip"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -116,6 +116,7 @@ dependencies:
|
||||
image_cropper: ^12.0.0
|
||||
image_picker: ^1.1.2
|
||||
intl: ^0.20.2
|
||||
jni: ^1.0.0
|
||||
json_annotation: ^4.11.0
|
||||
live_photo_maker: ^0.0.6
|
||||
logger: ^2.5.0
|
||||
@@ -219,6 +220,10 @@ dev_dependencies:
|
||||
flutter_launcher_icons: ^0.14.4
|
||||
flutter_lints: ^6.0.0
|
||||
flutter_native_splash: ^2.4.6
|
||||
jnigen:
|
||||
git:
|
||||
url: https://github.com/dart-lang/native.git
|
||||
path: pkgs/jnigen
|
||||
|
||||
flutter_launcher_icons:
|
||||
android: true
|
||||
|
||||
Reference in New Issue
Block a user