mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-07-27 22:10:14 +08:00
@@ -0,0 +1,84 @@
|
|||||||
|
package com.example.piliplus;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ShortcutInfo;
|
||||||
|
import android.content.pm.ShortcutManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.drawable.Icon;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.provider.Settings;
|
||||||
|
|
||||||
|
import androidx.annotation.Keep;
|
||||||
|
|
||||||
|
import com.github.dart_lang.jni_flutter.JniFlutterPlugin;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
public final class AndroidHelper {
|
||||||
|
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 int sdkInt() {
|
||||||
|
return Build.VERSION.SDK_INT;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,22 +1,15 @@
|
|||||||
package com.example.piliplus
|
package com.example.piliplus
|
||||||
|
|
||||||
import android.app.PendingIntent
|
|
||||||
import android.app.SearchManager
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.pm.ShortcutInfo
|
|
||||||
import android.content.pm.ShortcutManager
|
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.graphics.drawable.Icon
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.provider.MediaStore
|
import android.os.Bundle
|
||||||
import android.provider.Settings
|
import android.view.WindowManager.LayoutParams
|
||||||
import androidx.core.net.toUri
|
|
||||||
import com.ryanheise.audioservice.AudioServiceActivity
|
import com.ryanheise.audioservice.AudioServiceActivity
|
||||||
|
import io.flutter.SystemChrome
|
||||||
import io.flutter.embedding.engine.FlutterEngine
|
import io.flutter.embedding.engine.FlutterEngine
|
||||||
import io.flutter.plugin.common.MethodChannel
|
import io.flutter.plugin.common.MethodChannel
|
||||||
import io.flutter.SystemChrome
|
|
||||||
|
|
||||||
class MainActivity : AudioServiceActivity() {
|
class MainActivity : AudioServiceActivity() {
|
||||||
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||||
@@ -25,115 +18,15 @@ class MainActivity : AudioServiceActivity() {
|
|||||||
val methodChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "PiliPlus")
|
val methodChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "PiliPlus")
|
||||||
methodChannel.setMethodCallHandler { call, result ->
|
methodChannel.setMethodCallHandler { call, result ->
|
||||||
when (call.method) {
|
when (call.method) {
|
||||||
"back" -> back()
|
|
||||||
|
|
||||||
"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)
|
|
||||||
}
|
|
||||||
|
|
||||||
"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) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"sdkInt" -> {
|
|
||||||
result.success(Build.VERSION.SDK_INT)
|
|
||||||
}
|
|
||||||
|
|
||||||
"SystemChrome.setEnabledSystemUIMode" -> {
|
"SystemChrome.setEnabledSystemUIMode" -> {
|
||||||
SystemChrome.onMethodCall(
|
SystemChrome.onMethodCall(
|
||||||
this,
|
this, "SystemChrome.setEnabledSystemUIMode", call.argument("arguments")
|
||||||
"SystemChrome.setEnabledSystemUIMode",
|
|
||||||
call.argument("arguments")
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
"SystemChrome.setEnabledSystemUIOverlays" -> {
|
"SystemChrome.setEnabledSystemUIOverlays" -> {
|
||||||
SystemChrome.onMethodCall(
|
SystemChrome.onMethodCall(
|
||||||
this,
|
this, "SystemChrome.setEnabledSystemUIOverlays", call.argument("arguments")
|
||||||
"SystemChrome.setEnabledSystemUIOverlays",
|
|
||||||
call.argument("arguments")
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,12 +35,12 @@ class MainActivity : AudioServiceActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun back() {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
val intent = Intent(Intent.ACTION_MAIN).apply {
|
super.onCreate(savedInstanceState)
|
||||||
addCategory(Intent.CATEGORY_HOME)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
window.attributes.layoutInDisplayCutoutMode =
|
||||||
|
LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
||||||
}
|
}
|
||||||
startActivity(intent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
@@ -156,13 +49,11 @@ class MainActivity : AudioServiceActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onPictureInPictureModeChanged(
|
override fun onPictureInPictureModeChanged(
|
||||||
isInPictureInPictureMode: Boolean,
|
isInPictureInPictureMode: Boolean, newConfig: Configuration?
|
||||||
newConfig: Configuration?
|
|
||||||
) {
|
) {
|
||||||
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
|
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
|
||||||
MethodChannel(
|
MethodChannel(flutterEngine!!.dartExecutor.binaryMessenger, "floating").invokeMethod(
|
||||||
flutterEngine!!.dartExecutor.binaryMessenger,
|
"onPipChanged", isInPictureInPictureMode
|
||||||
"floating"
|
)
|
||||||
).invokeMethod("onPipChanged", isInPictureInPictureMode)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
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
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import 'package:PiliPlus/services/service_locator.dart';
|
|||||||
import 'package:PiliPlus/utils/cache_manager.dart';
|
import 'package:PiliPlus/utils/cache_manager.dart';
|
||||||
import 'package:PiliPlus/utils/calc_window_position.dart';
|
import 'package:PiliPlus/utils/calc_window_position.dart';
|
||||||
import 'package:PiliPlus/utils/date_utils.dart';
|
import 'package:PiliPlus/utils/date_utils.dart';
|
||||||
import 'package:PiliPlus/utils/device_utils.dart';
|
|
||||||
import 'package:PiliPlus/utils/extension/theme_ext.dart';
|
import 'package:PiliPlus/utils/extension/theme_ext.dart';
|
||||||
import 'package:PiliPlus/utils/json_file_handler.dart';
|
import 'package:PiliPlus/utils/json_file_handler.dart';
|
||||||
import 'package:PiliPlus/utils/path_utils.dart';
|
import 'package:PiliPlus/utils/path_utils.dart';
|
||||||
@@ -84,10 +83,6 @@ Future<void> _initAppPath() async {
|
|||||||
appSupportDirPath = (await getApplicationSupportDirectory()).path;
|
appSupportDirPath = (await getApplicationSupportDirectory()).path;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _initSdkInt() async {
|
|
||||||
DeviceUtils.sdkInt = await Utils.channel.invokeMethod('sdkInt');
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
MediaKit.ensureInitialized();
|
MediaKit.ensureInitialized();
|
||||||
@@ -109,7 +104,6 @@ void main() async {
|
|||||||
|
|
||||||
if (PlatformUtils.isMobile) {
|
if (PlatformUtils.isMobile) {
|
||||||
await Future.wait([
|
await Future.wait([
|
||||||
if (Platform.isAndroid) _initSdkInt(),
|
|
||||||
if (Pref.horizontalScreen) ?fullMode() else ?portraitUpMode(),
|
if (Pref.horizontalScreen) ?fullMode() else ?portraitUpMode(),
|
||||||
setupServiceLocator(),
|
setupServiceLocator(),
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import 'package:PiliPlus/pages/mine/controller.dart';
|
|||||||
import 'package:PiliPlus/services/logger.dart';
|
import 'package:PiliPlus/services/logger.dart';
|
||||||
import 'package:PiliPlus/utils/accounts.dart';
|
import 'package:PiliPlus/utils/accounts.dart';
|
||||||
import 'package:PiliPlus/utils/accounts/account.dart';
|
import 'package:PiliPlus/utils/accounts/account.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/cache_manager.dart';
|
import 'package:PiliPlus/utils/cache_manager.dart';
|
||||||
import 'package:PiliPlus/utils/date_utils.dart';
|
import 'package:PiliPlus/utils/date_utils.dart';
|
||||||
@@ -179,7 +180,7 @@ Commit Hash: ${BuildConfig.commitHash}''',
|
|||||||
),
|
),
|
||||||
if (Platform.isAndroid)
|
if (Platform.isAndroid)
|
||||||
ListTile(
|
ListTile(
|
||||||
onTap: () => Utils.channel.invokeMethod('linkVerifySettings'),
|
onTap: AndroidHelper.openLinkVerifySettings,
|
||||||
leading: const Icon(MdiIcons.linkBoxOutline),
|
leading: const Icon(MdiIcons.linkBoxOutline),
|
||||||
title: const Text('打开受支持的链接'),
|
title: const Text('打开受支持的链接'),
|
||||||
trailing: Icon(
|
trailing: Icon(
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import 'package:PiliPlus/models/common/nav_bar_config.dart';
|
|||||||
import 'package:PiliPlus/pages/home/view.dart';
|
import 'package:PiliPlus/pages/home/view.dart';
|
||||||
import 'package:PiliPlus/pages/main/controller.dart';
|
import 'package:PiliPlus/pages/main/controller.dart';
|
||||||
import 'package:PiliPlus/plugin/pl_player/controller.dart';
|
import 'package:PiliPlus/plugin/pl_player/controller.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/size_ext.dart';
|
import 'package:PiliPlus/utils/extension/size_ext.dart';
|
||||||
@@ -18,7 +19,6 @@ import 'package:PiliPlus/utils/mobile_observer.dart';
|
|||||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||||
import 'package:PiliPlus/utils/storage.dart';
|
import 'package:PiliPlus/utils/storage.dart';
|
||||||
import 'package:PiliPlus/utils/storage_key.dart';
|
import 'package:PiliPlus/utils/storage_key.dart';
|
||||||
import 'package:PiliPlus/utils/utils.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@@ -202,9 +202,10 @@ class _MainAppState extends PopScopeState<MainApp>
|
|||||||
await trayManager.setContextMenu(trayMenu);
|
await trayManager.setContextMenu(trayMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
static void _onBack() {
|
static void _onBack() {
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
Utils.channel.invokeMethod('back');
|
AndroidHelper.back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ 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/archive/view.dart';
|
||||||
import 'package:PiliPlus/pages/member_video_web/season_series/view.dart';
|
import 'package:PiliPlus/pages/member_video_web/season_series/view.dart';
|
||||||
import 'package:PiliPlus/pages/webview/view.dart';
|
import 'package:PiliPlus/pages/webview/view.dart';
|
||||||
|
import 'package:PiliPlus/utils/android/android_helper.dart';
|
||||||
import 'package:PiliPlus/utils/date_utils.dart';
|
import 'package:PiliPlus/utils/date_utils.dart';
|
||||||
import 'package:PiliPlus/utils/extension/context_ext.dart';
|
import 'package:PiliPlus/utils/extension/context_ext.dart';
|
||||||
import 'package:PiliPlus/utils/extension/string_ext.dart';
|
import 'package:PiliPlus/utils/extension/string_ext.dart';
|
||||||
@@ -704,14 +705,11 @@ class _MemberPageState extends State<MemberPage> {
|
|||||||
'${_userController.userAvatar!}@200w_200h.webp'.http2https,
|
'${_userController.userAvatar!}@200w_200h.webp'.http2https,
|
||||||
));
|
));
|
||||||
SmartDialog.dismiss();
|
SmartDialog.dismiss();
|
||||||
await Utils.channel.invokeMethod(
|
PiliAndroidHelper.createShortcut(
|
||||||
'createShortcut',
|
_userController.mid.toString(),
|
||||||
<String, String>{
|
'bilibili://space/${_userController.mid}',
|
||||||
'id': _userController.mid.toString(),
|
_userController.username!,
|
||||||
'uri': 'bilibili://space/${_userController.mid}',
|
file.path,
|
||||||
'label': _userController.username!,
|
|
||||||
'icon': file.path,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
SmartDialog.showToast(e.toString());
|
SmartDialog.showToast(e.toString());
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import 'dart:io' show Platform;
|
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:PiliPlus/common/widgets/badge.dart';
|
import 'package:PiliPlus/common/widgets/badge.dart';
|
||||||
@@ -428,15 +427,10 @@ class _MusicDetailPageState extends CommonDynPageState<MusicDetailPage> {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
MarqueeText(
|
||||||
onTap: () => _searchMusic(item),
|
item.musicTitle!,
|
||||||
onLongPress: () => Utils.copyText(item.musicTitle!),
|
spacing: 30,
|
||||||
behavior: HitTestBehavior.opaque,
|
style: textTheme.titleMedium,
|
||||||
child: MarqueeText(
|
|
||||||
item.musicTitle!,
|
|
||||||
spacing: 30,
|
|
||||||
style: textTheme.titleMedium,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Wrap(
|
Wrap(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
@@ -558,18 +552,4 @@ 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) {
|
|
||||||
Utils.copyText(item.musicTitle!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
19
lib/utils/android/android_helper.dart
Normal file
19
lib/utils/android/android_helper.dart
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import 'package:PiliPlus/utils/android/bindings.g.dart';
|
||||||
|
import 'package:jni/jni.dart';
|
||||||
|
|
||||||
|
abstract final class PiliAndroidHelper {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
342
lib/utils/android/bindings.g.dart
Normal file
342
lib/utils/android/bindings.g.dart
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
// 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: `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;';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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_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_sdkInt = _class.staticMethodId(
|
||||||
|
r'sdkInt',
|
||||||
|
r'()I',
|
||||||
|
);
|
||||||
|
|
||||||
|
static final _sdkInt =
|
||||||
|
jni$_.ProtectedJniExtensions.lookup<
|
||||||
|
jni$_.NativeFunction<
|
||||||
|
jni$_.JniResult Function(
|
||||||
|
jni$_.Pointer<jni$_.Void>,
|
||||||
|
jni$_.JMethodIDPtr,
|
||||||
|
)
|
||||||
|
>
|
||||||
|
>('globalEnv_CallStaticIntMethod')
|
||||||
|
.asFunction<
|
||||||
|
jni$_.JniResult Function(
|
||||||
|
jni$_.Pointer<jni$_.Void>,
|
||||||
|
jni$_.JMethodIDPtr,
|
||||||
|
)
|
||||||
|
>();
|
||||||
|
|
||||||
|
/// from: `static public int sdkInt()`
|
||||||
|
static core$_.int sdkInt() {
|
||||||
|
final _$$classRef = _class.reference;
|
||||||
|
return _sdkInt(_$$classRef.pointer, _id_sdkInt.pointer).integer;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_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 id, java.lang.String uri, java.lang.String label, java.lang.String icon)`
|
||||||
|
static void createShortcut(
|
||||||
|
jni$_.JString id,
|
||||||
|
jni$_.JString uri,
|
||||||
|
jni$_.JString label,
|
||||||
|
jni$_.JString icon,
|
||||||
|
) {
|
||||||
|
final _$$classRef = _class.reference;
|
||||||
|
final _$id = id.reference;
|
||||||
|
final _$uri = uri.reference;
|
||||||
|
final _$label = label.reference;
|
||||||
|
final _$icon = icon.reference;
|
||||||
|
_createShortcut(
|
||||||
|
_$$classRef.pointer,
|
||||||
|
_id_createShortcut.pointer,
|
||||||
|
_$id.pointer,
|
||||||
|
_$uri.pointer,
|
||||||
|
_$label.pointer,
|
||||||
|
_$icon.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;';
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
|
import 'package:PiliPlus/utils/android/bindings.g.dart';
|
||||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||||
import 'package:flutter/widgets.dart' show WidgetsBinding, Size;
|
import 'package:flutter/widgets.dart' show WidgetsBinding, Size;
|
||||||
|
|
||||||
abstract final class DeviceUtils {
|
abstract final class DeviceUtils {
|
||||||
static late int sdkInt;
|
static final int sdkInt = AndroidHelper.sdkInt();
|
||||||
|
|
||||||
static bool get isTablet {
|
static bool get isTablet {
|
||||||
return size.shortestSide >= 600;
|
return size.shortestSide >= 600;
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ abstract final class ReplyUtils {
|
|||||||
required int type,
|
required int type,
|
||||||
required int id,
|
required int id,
|
||||||
required String message,
|
required String message,
|
||||||
dynamic root,
|
required int root,
|
||||||
dynamic parent,
|
required int parent,
|
||||||
dynamic ctime,
|
required int ctime,
|
||||||
List? pictures,
|
required List pictures,
|
||||||
dynamic mid,
|
required int mid,
|
||||||
bool isManual = false,
|
bool isManual = false,
|
||||||
}) async {
|
}) async {
|
||||||
// CommAntifraud
|
// CommAntifraud
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
import 'dart:convert' show JsonEncoder, base64;
|
import 'dart:convert' show JsonEncoder, base64;
|
||||||
import 'dart:math' show Random;
|
import 'dart:math' show Random;
|
||||||
|
|
||||||
import 'package:PiliPlus/common/constants.dart';
|
|
||||||
import 'package:catcher_2/catcher_2.dart';
|
import 'package:catcher_2/catcher_2.dart';
|
||||||
import 'package:flutter/services.dart'
|
import 'package:flutter/services.dart' show Clipboard, ClipboardData;
|
||||||
show Clipboard, ClipboardData, MethodChannel;
|
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
|
|
||||||
abstract final class Utils {
|
abstract final class Utils {
|
||||||
static final random = Random();
|
static final random = Random();
|
||||||
|
|
||||||
static const channel = MethodChannel(Constants.appName);
|
|
||||||
|
|
||||||
static const jsonEncoder = JsonEncoder.withIndent(' ');
|
static const jsonEncoder = JsonEncoder.withIndent(' ');
|
||||||
|
|
||||||
static final numericRegex = RegExp(r'^[\d\.]+$');
|
static final numericRegex = RegExp(r'^[\d\.]+$');
|
||||||
|
|||||||
19
pubspec.lock
19
pubspec.lock
@@ -269,6 +269,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.4"
|
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:
|
cli_util:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -948,7 +956,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.1"
|
version: "0.6.1"
|
||||||
jni:
|
jni:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: jni
|
name: jni
|
||||||
sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f
|
sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f
|
||||||
@@ -963,6 +971,15 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
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:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ dependencies:
|
|||||||
image_cropper: ^12.0.0
|
image_cropper: ^12.0.0
|
||||||
image_picker: ^1.1.2
|
image_picker: ^1.1.2
|
||||||
intl: ^0.20.2
|
intl: ^0.20.2
|
||||||
|
jni: ^1.0.0
|
||||||
json_annotation: ^4.11.0
|
json_annotation: ^4.11.0
|
||||||
live_photo_maker:
|
live_photo_maker:
|
||||||
git:
|
git:
|
||||||
@@ -244,6 +245,10 @@ dev_dependencies:
|
|||||||
flutter_launcher_icons: ^0.14.4
|
flutter_launcher_icons: ^0.14.4
|
||||||
flutter_lints: ^6.0.0
|
flutter_lints: ^6.0.0
|
||||||
flutter_native_splash: ^2.4.6
|
flutter_native_splash: ^2.4.6
|
||||||
|
jnigen:
|
||||||
|
git:
|
||||||
|
url: https://github.com/dart-lang/native.git
|
||||||
|
path: pkgs/jnigen
|
||||||
|
|
||||||
flutter_launcher_icons:
|
flutter_launcher_icons:
|
||||||
android: true
|
android: true
|
||||||
|
|||||||
1
tool/README.md
Normal file
1
tool/README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
run `dart run tool/jnigen.dart`
|
||||||
23
tool/jnigen.dart
Normal file
23
tool/jnigen.dart
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import 'dart:io' show Platform;
|
||||||
|
|
||||||
|
import 'package:jnigen/jnigen.dart';
|
||||||
|
|
||||||
|
void main(List<String> args) {
|
||||||
|
final packageRoot = Platform.script.resolve('../');
|
||||||
|
generateJniBindings(
|
||||||
|
Config(
|
||||||
|
outputConfig: OutputConfig(
|
||||||
|
dartConfig: DartCodeOutputConfig(
|
||||||
|
path: packageRoot.resolve('lib/utils/android/bindings.g.dart'),
|
||||||
|
structure: .singleFile,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
androidSdkConfig: AndroidSdkConfig(addGradleDeps: true),
|
||||||
|
sourcePath: [packageRoot.resolve('android/app/src/main/java')],
|
||||||
|
classes: [
|
||||||
|
'com.example.piliplus',
|
||||||
|
'java.lang.Runnable',
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user