mirror of
https://github.com/bytedream/Yamete-Kudasai.git
synced 2025-05-09 04:05:09 +02:00
Proper update service, no sound on normal app start
This commit is contained in:
parent
ccf871ce8b
commit
498e3dcbf5
@ -32,7 +32,7 @@ apply plugin: 'com.android.application'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
compileSdkVersion 31
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
@ -43,7 +43,7 @@ android {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "org.bytedream.yamete_kudasai"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 30
|
||||
targetSdkVersion 31
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
multiDexEnabled true
|
||||
|
@ -38,22 +38,15 @@
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
</application>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<queries>
|
||||
<!-- If your app opens https URLs -->
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<data android:scheme="https" />
|
||||
</intent>
|
||||
<!-- If your app makes calls -->
|
||||
<intent>
|
||||
<action android:name="android.intent.action.DIAL" />
|
||||
<data android:scheme="tel" />
|
||||
</intent>
|
||||
<!-- If your app emails -->
|
||||
<intent>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<data android:mimeType="*/*" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
</manifest>
|
||||
|
@ -38,25 +38,13 @@ void initBackground() {
|
||||
);
|
||||
|
||||
Map<UpdateAction, String>? data;
|
||||
int running = 0;
|
||||
|
||||
StreamSubscription<UpdateAction?>? sub = _portUpdate.stream.listen((event) async {
|
||||
data ??= (jsonDecode(generateEventData(await SharedPreferences.getInstance())) as Map<String, dynamic>)
|
||||
.map((key, value) => MapEntry(UpdateAction.values.elementAt(int.parse(key)), value as String));
|
||||
if (data!.containsKey(event!)) {
|
||||
final player = await _player.play(data![event]!);
|
||||
running++;
|
||||
FlutterBackgroundService().setNotificationInfo(
|
||||
title: 'Yamete Kudasai',
|
||||
content: 'Dispatching ${actions.values.elementAt(event.index).toLowerCase()} event'
|
||||
);
|
||||
await player.onPlayerCompletion.first;
|
||||
if (--running == 0) {
|
||||
FlutterBackgroundService().setNotificationInfo(
|
||||
title: 'Yamete Kudasai',
|
||||
content: 'Running'
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
136
lib/main.dart
136
lib/main.dart
@ -1,11 +1,15 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_background_service/flutter_background_service.dart';
|
||||
import 'package:future_progress_dialog/future_progress_dialog.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:open_file/open_file.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:yamete_kudasai/background.dart';
|
||||
@ -15,7 +19,20 @@ import 'choose_audio.dart';
|
||||
void main() {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
|
||||
runApp(YameteKudasai());
|
||||
runApp(MaterialApp(
|
||||
title: "Yamete Kudasai",
|
||||
theme: ThemeData.from(
|
||||
colorScheme: const ColorScheme.highContrastDark(
|
||||
primary: Color(0xFFFF0000),
|
||||
primaryVariant: Color(0xFFC20000),
|
||||
secondary: Colors.purple,
|
||||
surface: Colors.black,
|
||||
background: Colors.black12,
|
||||
onPrimary: Colors.white,
|
||||
),
|
||||
),
|
||||
home: YameteKudasai(),
|
||||
));
|
||||
}
|
||||
|
||||
class YameteKudasai extends StatefulWidget {
|
||||
@ -26,34 +43,10 @@ class YameteKudasai extends StatefulWidget {
|
||||
class _YameteKudasaiState extends State<YameteKudasai> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
http.get(Uri.https('api.github.com', 'repos/ByteDream/yamete_kudasai/releases/latest'))
|
||||
.timeout(const Duration(seconds: 5), onTimeout: () => http.Response.bytes([], 504)).then((response) async {
|
||||
if (response.statusCode == 200) {
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
final tag = (jsonDecode(response.body) as Map<String, dynamic>)['tag_name'] as String;
|
||||
if (int.parse(tag.substring(1).replaceAll('.', '')) > int.parse(packageInfo.version.replaceAll('.', ''))) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => _buildUpdateNotification(context, tag)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
FlutterBackgroundService.initialize(initBackground, foreground: false);
|
||||
checkUpdate(context);
|
||||
|
||||
return MaterialApp(
|
||||
title: "Yamete Kudasai",
|
||||
theme: ThemeData.from(
|
||||
colorScheme: const ColorScheme.highContrastDark(
|
||||
primary: Color(0xFFFF0000),
|
||||
primaryVariant: Color(0xFFC20000),
|
||||
secondary: Colors.purple,
|
||||
surface: Colors.black,
|
||||
background: Colors.black26,
|
||||
onPrimary: Colors.white,
|
||||
),
|
||||
),
|
||||
home: Scaffold(
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Yamete Kudasai'),
|
||||
),
|
||||
@ -98,18 +91,34 @@ class _YameteKudasaiState extends State<YameteKudasai> {
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildUpdateNotification(BuildContext context, String tag) {
|
||||
Widget _buildUpdateNotification(BuildContext context, String tag, String apkUrl) {
|
||||
return AlertDialog(
|
||||
backgroundColor: Colors.black,
|
||||
title: Text('Newer version is available ($tag)'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
if (await canLaunch('https://github.com/ByteDream/yamete_kudasai/releases/tag/$tag')) {
|
||||
await launch('https://github.com/ByteDream/yamete_kudasai/releases/tag/$tag');
|
||||
await updateAPK(context, apkUrl);
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => FutureProgressDialog(
|
||||
updateAPK(context, apkUrl),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.transparent
|
||||
),
|
||||
message: const Text('Downloading update...'),
|
||||
)
|
||||
);
|
||||
},
|
||||
child: const Text('Update')
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
if (await canLaunch('https://github.com/ByteDream/Yamete-Kudasai/releases/tag/$tag')) {
|
||||
await launch('https://github.com/ByteDream/Yamete-Kudasai/releases/tag/$tag');
|
||||
}
|
||||
},
|
||||
child: const Text('Show new release')
|
||||
@ -178,12 +187,75 @@ class _YameteKudasaiState extends State<YameteKudasai> {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> checkUpdate(BuildContext context) async {
|
||||
final response = await http.get(Uri.https('api.github.com', 'repos/ByteDream/Yamete-Kudasai/releases/latest'))
|
||||
.timeout(const Duration(seconds: 5), onTimeout: () => http.Response.bytes([], 504));
|
||||
if (response.statusCode == 200) {
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
final json = (jsonDecode(response.body) as Map<String, dynamic>);
|
||||
final tag = json['tag_name'] as String;
|
||||
final apkUrl = json['assets'][0]['browser_download_url'] as String;
|
||||
if (int.parse(tag.substring(1).replaceAll('.', '')) > int.parse(packageInfo.version.replaceAll('.', ''))) {
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => _buildUpdateNotification(context, tag, apkUrl)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateAPK(BuildContext context, String apkUrl) async {
|
||||
ResultType result;
|
||||
if ((await Permission.storage.request()).isGranted) {
|
||||
final file = File('/storage/emulated/0/Download/${apkUrl.split('/').last}');
|
||||
final completer = Completer<void>();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return FutureProgressDialog(
|
||||
completer.future,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.transparent
|
||||
),
|
||||
message: const Text('Downloading update...'),
|
||||
);
|
||||
}
|
||||
);
|
||||
if (!(await file.exists())) {
|
||||
final resp = await http.get(Uri.parse(apkUrl));
|
||||
await file.writeAsBytes(resp.bodyBytes);
|
||||
}
|
||||
result = (await OpenFile.open(file.path)).type;
|
||||
completer.complete();
|
||||
} else {
|
||||
result = ResultType.error;
|
||||
}
|
||||
if (result != ResultType.done) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text('Failed to install update'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: const Text('Ok'),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
Navigator.pop(context);
|
||||
// await file.delete();
|
||||
}
|
||||
|
||||
Future<bool> isRunning() async {
|
||||
try {
|
||||
FlutterBackgroundService().sendData({'action': 'ping'});
|
||||
await FlutterBackgroundService().onDataReceived.first.timeout(const Duration(milliseconds: 500));
|
||||
return true;
|
||||
} on Exception catch (e) {
|
||||
} on Exception {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -45,11 +45,11 @@ public class PortUpdatePlugin implements FlutterPlugin, StreamHandler {
|
||||
batteryReceiver = createBatteryReceiver(eventSink);
|
||||
headphoneReceiver = createHeadphoneReceiver(eventSink);
|
||||
|
||||
context.registerReceiver(batteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||
context.registerReceiver(headphoneReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
|
||||
Intent batteryIntent = context.registerReceiver(batteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||
Intent headphoneIntent = context.registerReceiver(headphoneReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
|
||||
|
||||
// lastBatteryStatus = getBatteryStatus(intent);
|
||||
// lastHeadphoneStatus = getHeadphoneStatus(intent);
|
||||
if (batteryIntent != null) lastBatteryStatus = getBatteryStatus(batteryIntent);
|
||||
if (headphoneIntent != null) lastHeadphoneStatus = getHeadphoneStatus(headphoneIntent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 1.0.0
|
||||
version: 1.1.0
|
||||
|
||||
environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
@ -36,8 +36,12 @@ dependencies:
|
||||
audioplayers: ^0.20.1
|
||||
cupertino_icons: ^1.0.2
|
||||
flutter_background_service: ^0.1.5
|
||||
future_progress_dialog: ^0.2.0
|
||||
http: ^0.13.4
|
||||
open_file: ^3.2.1
|
||||
package_info_plus: ^1.3.0
|
||||
path_provider: ^2.0.7
|
||||
permission_handler: ^8.3.0
|
||||
shared_preferences: ^2.0.8
|
||||
url_launcher: ^6.0.13
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user