Get basic timer notifications working
This commit is contained in:
parent
7d4b6a45c5
commit
117ca5cdc4
|
@ -1,6 +1,7 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.example.fmassive">
|
package="com.example.fmassive">
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||||
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
|
|
191
android/app/src/main/kotlin/com/example/fmassive/Alarm.kt
Normal file
191
android/app/src/main/kotlin/com/example/fmassive/Alarm.kt
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
package com.example.fmassive
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.*
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.CountDownTimer
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import io.flutter.plugin.common.MethodCall
|
||||||
|
import io.flutter.plugin.common.MethodChannel
|
||||||
|
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
|
||||||
|
import kotlin.math.floor
|
||||||
|
|
||||||
|
|
||||||
|
class AlarmModule(private val context: Context) : MethodCallHandler {
|
||||||
|
|
||||||
|
private var countdownTimer: CountDownTimer? = null
|
||||||
|
var currentMs: Long = 0
|
||||||
|
private var running = false
|
||||||
|
|
||||||
|
private val stopReceiver = object : BroadcastReceiver() {
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
|
Log.d("AlarmModule", "Received stop broadcast intent")
|
||||||
|
if (context != null) {
|
||||||
|
stop(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val addReceiver = object : BroadcastReceiver() {
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
|
if (context != null) {
|
||||||
|
add(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
fun add(context: Context) {
|
||||||
|
Log.d("AlarmModule", "Add 1 min to alarm.")
|
||||||
|
countdownTimer?.cancel()
|
||||||
|
val newMs = if (running) currentMs.toInt().plus(60000) else 60000
|
||||||
|
countdownTimer = getTimer(context, newMs)
|
||||||
|
countdownTimer?.start()
|
||||||
|
running = true
|
||||||
|
//val manager = getManager()
|
||||||
|
//manager.cancel(AlarmService.NOTIFICATION_ID_DONE)
|
||||||
|
//val intent = Intent(context, AlarmService::class.java)
|
||||||
|
//context.stopService(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
fun stop(context: Context) {
|
||||||
|
Log.d("AlarmModule", "Stop alarm.")
|
||||||
|
countdownTimer?.cancel()
|
||||||
|
running = false
|
||||||
|
//val intent = Intent(context, AlarmService::class.java)
|
||||||
|
//reactApplicationContext?.stopService(intent)
|
||||||
|
//val manager = getManager()
|
||||||
|
//manager.cancel(AlarmService.NOTIFICATION_ID_DONE)
|
||||||
|
//manager.cancel(NOTIFICATION_ID_PENDING)
|
||||||
|
//val params = Arguments.createMap().apply {
|
||||||
|
// putString("minutes", "00")
|
||||||
|
// putString("seconds", "00")
|
||||||
|
//}
|
||||||
|
//reactApplicationContext
|
||||||
|
// .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
||||||
|
// .emit("tick", params)
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
fun timer(context: Context, milliseconds: Int) {
|
||||||
|
context.registerReceiver(stopReceiver, IntentFilter(STOP_BROADCAST))
|
||||||
|
context.registerReceiver(addReceiver, IntentFilter(ADD_BROADCAST))
|
||||||
|
Log.d("AlarmModule", "Queue alarm for $milliseconds delay")
|
||||||
|
val manager = getManager(context)
|
||||||
|
//manager.cancel(AlarmService.NOTIFICATION_ID_DONE)
|
||||||
|
//val intent = Intent(reactApplicationContext, AlarmService::class.java)
|
||||||
|
//reactApplicationContext.stopService(intent)
|
||||||
|
countdownTimer?.cancel()
|
||||||
|
countdownTimer = getTimer(context, milliseconds)
|
||||||
|
countdownTimer?.start()
|
||||||
|
running = true
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
private fun getTimer(
|
||||||
|
context: Context,
|
||||||
|
endMs: Int,
|
||||||
|
): CountDownTimer {
|
||||||
|
val builder = getBuilder(context)
|
||||||
|
return object : CountDownTimer(endMs.toLong(), 1000) {
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
override fun onTick(current: Long) {
|
||||||
|
currentMs = current
|
||||||
|
val seconds =
|
||||||
|
floor((current / 1000).toDouble() % 60).toInt().toString().padStart(2, '0')
|
||||||
|
val minutes =
|
||||||
|
floor((current / 1000).toDouble() / 60).toInt().toString().padStart(2, '0')
|
||||||
|
builder.setContentText("$minutes:$seconds").setAutoCancel(false).setDefaults(0)
|
||||||
|
.setProgress(endMs, current.toInt(), false)
|
||||||
|
.setCategory(NotificationCompat.CATEGORY_PROGRESS).priority =
|
||||||
|
NotificationCompat.PRIORITY_LOW
|
||||||
|
val manager = getManager(context)
|
||||||
|
manager.notify(NOTIFICATION_ID_PENDING, builder.build())
|
||||||
|
//val params = Arguments.createMap().apply {
|
||||||
|
// putString("minutes", minutes)
|
||||||
|
// putString("seconds", seconds)
|
||||||
|
//}
|
||||||
|
//reactApplicationContext
|
||||||
|
// .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
||||||
|
// .emit("tick", params)
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
override fun onFinish() {
|
||||||
|
//val context = reactApplicationContext
|
||||||
|
//context.startForegroundService(Intent(context, AlarmService::class.java))
|
||||||
|
//context
|
||||||
|
// .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
||||||
|
// .emit("finish", Arguments.createMap().apply {
|
||||||
|
// putString("minutes", "00")
|
||||||
|
// putString("seconds", "00")
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("UnspecifiedImmutableFlag")
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
private fun getBuilder(context: Context): NotificationCompat.Builder {
|
||||||
|
val contentIntent = Intent(context, MainActivity::class.java)
|
||||||
|
val pendingContent =
|
||||||
|
PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||||
|
val addBroadcast = Intent(ADD_BROADCAST).apply {
|
||||||
|
setPackage(context.packageName)
|
||||||
|
}
|
||||||
|
val pendingAdd =
|
||||||
|
PendingIntent.getBroadcast(context, 0, addBroadcast, PendingIntent.FLAG_MUTABLE)
|
||||||
|
val stopBroadcast = Intent(STOP_BROADCAST)
|
||||||
|
stopBroadcast.setPackage(context.packageName)
|
||||||
|
val pendingStop =
|
||||||
|
PendingIntent.getBroadcast(context, 0, stopBroadcast, PendingIntent.FLAG_IMMUTABLE)
|
||||||
|
return NotificationCompat.Builder(context, CHANNEL_ID_PENDING)
|
||||||
|
.setSmallIcon(R.drawable.ic_baseline_hourglass_bottom_24).setContentTitle("Resting")
|
||||||
|
.setContentIntent(pendingContent)
|
||||||
|
.addAction(R.drawable.ic_baseline_stop_24, "Stop", pendingStop)
|
||||||
|
.addAction(R.drawable.ic_baseline_stop_24, "Add 1 min", pendingAdd)
|
||||||
|
.setDeleteIntent(pendingStop)
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
private fun getManager(context: Context): NotificationManager {
|
||||||
|
val notificationManager = context.getSystemService(
|
||||||
|
NotificationManager::class.java
|
||||||
|
)
|
||||||
|
val timersChannel = NotificationChannel(
|
||||||
|
CHANNEL_ID_PENDING, CHANNEL_ID_PENDING, NotificationManager.IMPORTANCE_LOW
|
||||||
|
)
|
||||||
|
timersChannel.setSound(null, null)
|
||||||
|
timersChannel.description = "Progress on rest timers."
|
||||||
|
notificationManager.createNotificationChannel(timersChannel)
|
||||||
|
return notificationManager
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val STOP_BROADCAST = "stop-timer-event"
|
||||||
|
const val ADD_BROADCAST = "add-timer-event"
|
||||||
|
const val CHANNEL_ID_PENDING = "Timer"
|
||||||
|
const val NOTIFICATION_ID_PENDING = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
|
||||||
|
when (call.method) {
|
||||||
|
"timer" -> {
|
||||||
|
|
||||||
|
}
|
||||||
|
else -> result.notImplemented()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,195 @@
|
||||||
package com.example.fmassive
|
package com.example.fmassive
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.CountDownTimer
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
import io.flutter.embedding.engine.FlutterEngine
|
||||||
|
import io.flutter.plugin.common.MethodChannel
|
||||||
|
import kotlin.math.floor
|
||||||
|
|
||||||
class MainActivity: FlutterActivity() {
|
class MainActivity : FlutterActivity() {
|
||||||
|
private val CHANNEL = "com.massive/android"
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||||
|
super.configureFlutterEngine(flutterEngine)
|
||||||
|
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
|
||||||
|
// This method is invoked on the main thread.
|
||||||
|
call, result ->
|
||||||
|
if (call.method == "timer") {
|
||||||
|
val args = call.arguments as ArrayList<Long>
|
||||||
|
timer(args[0])
|
||||||
|
} else {
|
||||||
|
result.notImplemented()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var countdownTimer: CountDownTimer? = null
|
||||||
|
var currentMs: Long = 0
|
||||||
|
private var running = false
|
||||||
|
|
||||||
|
private val stopReceiver = object : BroadcastReceiver() {
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
|
Log.d("AlarmModule", "Received stop broadcast intent")
|
||||||
|
stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val addReceiver = object : BroadcastReceiver() {
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
|
add()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
fun add() {
|
||||||
|
Log.d("AlarmModule", "Add 1 min to alarm.")
|
||||||
|
countdownTimer?.cancel()
|
||||||
|
val newMs = if (running) currentMs.toInt().plus(60000) else 60000
|
||||||
|
countdownTimer = getTimer(newMs.toLong())
|
||||||
|
countdownTimer?.start()
|
||||||
|
running = true
|
||||||
|
//val manager = getManager()
|
||||||
|
//manager.cancel(AlarmService.NOTIFICATION_ID_DONE)
|
||||||
|
//val intent = Intent(context, AlarmService::class.java)
|
||||||
|
//context.stopService(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
fun stop() {
|
||||||
|
Log.d("AlarmModule", "Stop alarm.")
|
||||||
|
countdownTimer?.cancel()
|
||||||
|
running = false
|
||||||
|
//val intent = Intent(context, AlarmService::class.java)
|
||||||
|
//reactApplicationContext?.stopService(intent)
|
||||||
|
//val manager = getManager()
|
||||||
|
//manager.cancel(AlarmService.NOTIFICATION_ID_DONE)
|
||||||
|
//manager.cancel(NOTIFICATION_ID_PENDING)
|
||||||
|
//val params = Arguments.createMap().apply {
|
||||||
|
// putString("minutes", "00")
|
||||||
|
// putString("seconds", "00")
|
||||||
|
//}
|
||||||
|
//reactApplicationContext
|
||||||
|
// .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
||||||
|
// .emit("tick", params)
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
fun timer(milliseconds: Long) {
|
||||||
|
context.registerReceiver(stopReceiver, IntentFilter(STOP_BROADCAST))
|
||||||
|
context.registerReceiver(addReceiver, IntentFilter(ADD_BROADCAST))
|
||||||
|
Log.d("AlarmModule", "Queue alarm for $milliseconds delay")
|
||||||
|
//val manager = getManager()
|
||||||
|
//manager.cancel(AlarmService.NOTIFICATION_ID_DONE)
|
||||||
|
//val intent = Intent(reactApplicationContext, AlarmService::class.java)
|
||||||
|
//reactApplicationContext.stopService(intent)
|
||||||
|
countdownTimer?.cancel()
|
||||||
|
countdownTimer = getTimer(milliseconds)
|
||||||
|
countdownTimer?.start()
|
||||||
|
running = true
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
private fun getTimer(
|
||||||
|
endMs: Long,
|
||||||
|
): CountDownTimer {
|
||||||
|
val builder = getBuilder()
|
||||||
|
return object : CountDownTimer(endMs.toLong(), 1000) {
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
override fun onTick(current: Long) {
|
||||||
|
currentMs = current
|
||||||
|
val seconds =
|
||||||
|
floor((current / 1000).toDouble() % 60).toInt().toString().padStart(2, '0')
|
||||||
|
val minutes =
|
||||||
|
floor((current / 1000).toDouble() / 60).toInt().toString().padStart(2, '0')
|
||||||
|
builder.setContentText("$minutes:$seconds").setAutoCancel(false).setDefaults(0)
|
||||||
|
.setProgress(endMs.toInt(), current.toInt(), false)
|
||||||
|
.setCategory(NotificationCompat.CATEGORY_PROGRESS).priority =
|
||||||
|
NotificationCompat.PRIORITY_LOW
|
||||||
|
val manager = getManager()
|
||||||
|
Log.d("AlarmModule", "Notify $NOTIFICATION_ID_PENDING")
|
||||||
|
manager.notify(NOTIFICATION_ID_PENDING, builder.build())
|
||||||
|
//val params = Arguments.createMap().apply {
|
||||||
|
// putString("minutes", minutes)
|
||||||
|
// putString("seconds", seconds)
|
||||||
|
//}
|
||||||
|
//reactApplicationContext
|
||||||
|
// .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
||||||
|
// .emit("tick", params)
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
override fun onFinish() {
|
||||||
|
//val context = reactApplicationContext
|
||||||
|
//context.startForegroundService(Intent(context, AlarmService::class.java))
|
||||||
|
//context
|
||||||
|
// .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
||||||
|
// .emit("finish", Arguments.createMap().apply {
|
||||||
|
// putString("minutes", "00")
|
||||||
|
// putString("seconds", "00")
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("UnspecifiedImmutableFlag")
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
private fun getBuilder(): NotificationCompat.Builder {
|
||||||
|
val contentIntent = Intent(context, MainActivity::class.java)
|
||||||
|
val pendingContent =
|
||||||
|
PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||||
|
val addBroadcast = Intent(ADD_BROADCAST).apply {
|
||||||
|
setPackage(context.packageName)
|
||||||
|
}
|
||||||
|
val pendingAdd =
|
||||||
|
PendingIntent.getBroadcast(context, 0, addBroadcast, PendingIntent.FLAG_MUTABLE)
|
||||||
|
val stopBroadcast = Intent(STOP_BROADCAST)
|
||||||
|
stopBroadcast.setPackage(context.packageName)
|
||||||
|
val pendingStop =
|
||||||
|
PendingIntent.getBroadcast(context, 0, stopBroadcast, PendingIntent.FLAG_IMMUTABLE)
|
||||||
|
return NotificationCompat.Builder(context, CHANNEL_ID_PENDING)
|
||||||
|
.setSmallIcon(R.drawable.ic_baseline_hourglass_bottom_24).setContentTitle("Resting")
|
||||||
|
.setContentIntent(pendingContent)
|
||||||
|
.addAction(R.drawable.ic_baseline_stop_24, "Stop", pendingStop)
|
||||||
|
.addAction(R.drawable.ic_baseline_stop_24, "Add 1 min", pendingAdd)
|
||||||
|
.setDeleteIntent(pendingStop)
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
private fun getManager(): NotificationManager {
|
||||||
|
val notificationManager = context.getSystemService(
|
||||||
|
NotificationManager::class.java
|
||||||
|
)
|
||||||
|
val timersChannel = NotificationChannel(
|
||||||
|
CHANNEL_ID_PENDING, CHANNEL_ID_PENDING, NotificationManager.IMPORTANCE_LOW
|
||||||
|
)
|
||||||
|
timersChannel.setSound(null, null)
|
||||||
|
timersChannel.description = "Progress on rest timers."
|
||||||
|
notificationManager.createNotificationChannel(timersChannel)
|
||||||
|
return notificationManager
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val STOP_BROADCAST = "stop-timer-event"
|
||||||
|
const val ADD_BROADCAST = "add-timer-event"
|
||||||
|
const val CHANNEL_ID_PENDING = "Timer"
|
||||||
|
const val NOTIFICATION_ID_PENDING = 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.example.fmassive
|
||||||
|
|
||||||
|
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||||
|
import io.flutter.plugin.common.MethodChannel
|
||||||
|
|
||||||
|
class MyFlutterPlugin : FlutterPlugin {
|
||||||
|
private lateinit var channel: MethodChannel
|
||||||
|
|
||||||
|
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||||
|
val context = binding.applicationContext
|
||||||
|
val handler = AlarmModule(context)
|
||||||
|
channel = MethodChannel(binding.binaryMessenger, "my_channel")
|
||||||
|
channel.setMethodCallHandler(handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||||
|
channel.setMethodCallHandler(null)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
</selector>
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
</selector>
|
|
@ -1,4 +1,7 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const MyApp());
|
runApp(const MyApp());
|
||||||
|
@ -48,17 +51,10 @@ class MyHomePage extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MyHomePageState extends State<MyHomePage> {
|
class _MyHomePageState extends State<MyHomePage> {
|
||||||
int _counter = 0;
|
static const platform = MethodChannel('com.massive/android');
|
||||||
|
|
||||||
void _incrementCounter() async {
|
Future<void> _timer() async {
|
||||||
setState(() {
|
await platform.invokeMethod('timer', [3000]);
|
||||||
// This call to setState tells the Flutter framework that something has
|
|
||||||
// changed in this State, which causes it to rerun the build method below
|
|
||||||
// so that the display can reflect the updated values. If we changed
|
|
||||||
// _counter without calling setState(), then the build method would not be
|
|
||||||
// called again, and so nothing would appear to happen.
|
|
||||||
_counter++;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -99,14 +95,14 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||||
'You have pushed the button this many times:',
|
'You have pushed the button this many times:',
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'$_counter',
|
'Tap to start timer',
|
||||||
style: Theme.of(context).textTheme.headlineMedium,
|
style: Theme.of(context).textTheme.headlineMedium,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
onPressed: _incrementCounter,
|
onPressed: _timer,
|
||||||
tooltip: 'Increment',
|
tooltip: 'Increment',
|
||||||
child: const Icon(Icons.add),
|
child: const Icon(Icons.add),
|
||||||
), // This trailing comma makes auto-formatting nicer for build methods.
|
), // This trailing comma makes auto-formatting nicer for build methods.
|
||||||
|
|
|
@ -62,14 +62,6 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
flutter_foreground_plugin:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: flutter_foreground_plugin
|
|
||||||
sha256: "640ce980401eece566441b867400e137357d2331a564f1670d6d5c46fa12d8d4"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.8.0"
|
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
@ -194,4 +186,3 @@ packages:
|
||||||
version: "2.1.4"
|
version: "2.1.4"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.19.5 <3.0.0"
|
dart: ">=2.19.5 <3.0.0"
|
||||||
flutter: ">=2.0.0"
|
|
||||||
|
|
|
@ -34,7 +34,6 @@ dependencies:
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^1.0.2
|
cupertino_icons: ^1.0.2
|
||||||
flutter_foreground_plugin: ^0.8.0
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user