Last active
July 17, 2021 14:56
-
-
Save ivanburlakov/19b95fc3586967719defa34a1d21fb1b to your computer and use it in GitHub Desktop.
Flutter Android Foreground Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<manifest ...> | |
// add following line | |
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> | |
<application | |
... | |
// add following line | |
<service android:name=".ExampleService" /> | |
</application> | |
</manifest> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// change 'flutter_foreground_example' to your app name | |
package com.example.flutter_foreground_example | |
import androidx.annotation.RequiresApi | |
import android.content.Context | |
import android.graphics.Color | |
import android.app.Notification | |
import android.app.NotificationManager | |
import android.app.NotificationChannel | |
import android.app.Service | |
import android.content.Intent | |
import android.os.Build | |
import android.os.IBinder | |
import androidx.core.app.NotificationCompat | |
import java.util.Timer | |
import java.util.TimerTask | |
class ExampleService : Service() { | |
val notificationId = 1 | |
var serviceRunning = false | |
lateinit var builder: NotificationCompat.Builder | |
lateinit var channel: NotificationChannel | |
lateinit var manager: NotificationManager | |
override fun onCreate() { | |
super.onCreate() | |
startForeground() | |
serviceRunning = true | |
Timer().schedule(object : TimerTask() { | |
override fun run() { | |
if (serviceRunning == true) { | |
updateNotification("I got updated!") | |
} | |
} | |
}, 5000) | |
} | |
override fun onDestroy() { | |
super.onDestroy() | |
serviceRunning = false | |
} | |
@RequiresApi(Build.VERSION_CODES.O) | |
private fun createNotificationChannel(channelId: String, channelName: String): String { | |
channel = NotificationChannel(channelId, | |
channelName, NotificationManager.IMPORTANCE_NONE) | |
channel.lightColor = Color.BLUE | |
channel.lockscreenVisibility = Notification.VISIBILITY_PRIVATE | |
manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager | |
manager.createNotificationChannel(channel) | |
return channelId | |
} | |
private fun startForeground() { | |
val channelId = | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | |
createNotificationChannel("example_service", "Example Service") | |
} else { | |
// If earlier version channel ID is not used | |
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context) | |
"" | |
} | |
builder = NotificationCompat.Builder(this, channelId) | |
builder | |
.setOngoing(true) | |
.setOnlyAlertOnce(true) | |
.setSmallIcon(R.mipmap.ic_launcher) | |
.setContentTitle("Example Service") | |
.setContentText("Example Serivce is running") | |
.setCategory(Notification.CATEGORY_SERVICE) | |
startForeground(1, builder.build()) | |
} | |
private fun updateNotification(text: String) { | |
builder | |
.setContentText(text) | |
manager.notify(notificationId, builder.build()); | |
} | |
override fun onBind(intent: Intent): IBinder? { | |
return null | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:flutter/services.dart'; | |
import 'dart:async'; | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Foreground Example', | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: MyHomePage(title: 'Foreground Example Home Page'), | |
); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
MyHomePage({Key? key, required this.title}) : super(key: key); | |
final String title; | |
@override | |
_MyHomePageState createState() => _MyHomePageState(); | |
} | |
class _MyHomePageState extends State<MyHomePage> { | |
static const platform = const MethodChannel('example_service'); | |
String _serverState = 'Did not make the call yet'; | |
Future<void> _startService() async { | |
try { | |
final result = await platform.invokeMethod('startExampleService'); | |
setState(() { | |
_serverState = result; | |
}); | |
} on PlatformException catch (e) { | |
print("Failed to invoke method: '${e.message}'."); | |
} | |
} | |
Future<void> _stopService() async { | |
try { | |
final result = await platform.invokeMethod('stopExampleService'); | |
setState(() { | |
_serverState = result; | |
}); | |
} on PlatformException catch (e) { | |
print("Failed to invoke method: '${e.message}'."); | |
} | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text(widget.title), | |
), | |
body: Center( | |
child: Column( | |
children: [ | |
Text(_serverState), | |
ElevatedButton( | |
child: Text('Start Service'), | |
onPressed: _startService, | |
), | |
ElevatedButton( | |
child: Text('Stop Service'), | |
onPressed: _stopService, | |
), | |
], | |
), | |
), | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// change 'flutter_foreground_example' to your app name | |
package com.example.flutter_foreground_example | |
import android.content.Intent | |
import androidx.annotation.NonNull | |
import io.flutter.embedding.android.FlutterActivity | |
import io.flutter.embedding.engine.FlutterEngine | |
import io.flutter.plugin.common.MethodChannel | |
import io.flutter.plugins.GeneratedPluginRegistrant | |
class MainActivity : FlutterActivity() { | |
private val CHANNEL = "example_service" | |
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { | |
super.configureFlutterEngine(flutterEngine) | |
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { | |
// Note: this method is invoked on the main thread. | |
call, result -> | |
when (call.method) { | |
"startExampleService" -> { | |
startService(Intent(this, ExampleService::class.java)) | |
result.success("Started!") | |
} | |
"stopExampleService" -> { | |
stopService(Intent(this, ExampleService::class.java)) | |
result.success("Stopped!") | |
} | |
else -> { | |
result.notImplemented() | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment