I need to run a dart function in the background when the methodchannel sends a callback...
here at below dart code...i want to run SendData() function when I receive any callback or return from methodchannel...
IMPORTANT *** => I wants it to work in background...even after the app is terminated...No need of UI change and all...just call the sendData() function in the background
MainActivity.Java
package com.ashbu.flutterappbackground;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodChannel;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;
import android.content.IntentFilter;
import io.flutter.plugin.common.EventChannel.EventSink;
import io.flutter.plugin.common.EventChannel.StreamHandler;
import android.app.Service;
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "samples.flutter.dev/battery";
private static final String IncomingCall_CHANNEL = "samples.flutter.dev/IncomingCall";
AlarmManager alarmManager;
PendingIntent pendingIntent;
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(this, MyService.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
new EventChannel(flutterEngine.getDartExecutor(), IncomingCall_CHANNEL).setStreamHandler(
new StreamHandler() {
private BroadcastReceiver IncomingCallStateChangeReceiver;
@Override
public void onListen(Object arguments, EventSink events) {
IncomingCallStateChangeReceiver = createIncomingCallStateChangeReceiver(events);
registerReceiver(
IncomingCallStateChangeReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
@Override
public void onCancel(Object arguments) {
unregisterReceiver(IncomingCallStateChangeReceiver);
IncomingCallStateChangeReceiver = null;
}
}
);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler(
(call, result) -> {
// Note: this method is invoked on the main thread.
if (call.method.equals("getBatteryLevel")) {
startAlarm();
MyBroadcastReceiver dataGEt = new MyBroadcastReceiver();
result.success(dataGEt.getData());
} else {
cancelAlarm();
}
}
);
}
private BroadcastReceiver createIncomingCallStateChangeReceiver(final EventSink events){
return new BroadcastReceiver() {
@Override
public void onReceive(final Context context, Intent intent) {
TelephonyManager telephony = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
telephony.listen(new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
System.out.println("incomingNumber : " + incomingNumber);
Toast.makeText(context, "TeleDuce Customer " + incomingNumber,
Toast.LENGTH_LONG).show();
if (incomingNumber != null) {
events.success(incomingNumber);
} else {
events.success("Abaha");
}
}
}, PhoneStateListener.LISTEN_CALL_STATE);
}
};
}
private void startAlarm() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, 0, pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, 0, pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, 0, pendingIntent);
}
}
private void cancelAlarm() {
alarmManager.cancel(pendingIntent);
Toast.makeText(getApplicationContext(), "Alarm Cancelled", Toast.LENGTH_LONG).show();
}
}
Main.Dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
static const platform = const MethodChannel('samples.flutter.dev/battery');
static const EventChannel eventChannel =
EventChannel('samples.flutter.dev/IncomingCall');
// Get battery level.
String _batteryLevel = 'Unknown battery level.';
String _IncomingCallStatus = 'Battery status: unknown.';
Future<void> _getBatteryLevel() async {
String batteryLevel;
try {
final String result = await platform.invokeMethod('getBatteryLevel');
batteryLevel = 'Battery level at $result % .';
} on PlatformException catch (e) {
batteryLevel = "Failed to get battery level: '${e.message}'.";
}
setState(() {
_batteryLevel = batteryLevel;
});
}
Future<void> SendData() async { <--------Need to call this function in background
var param = {
'userId': 272.toString(),
'api_key': '******************',
'env': 'production',
'common_search': '',
'filter_type': 'My',
'filter_type_data': '',
'leadsourcerequest': true,
};
// Get the previous cached count and increment it.
var res = await http.post(
'https://***********.amazonaws.com/default/Leadapi',
body: json.encode(param));
Map responsejson = json.decode(res.body);
print(res);
print(responsejson['response_data'][0]);
// This will be null if we're running in the background.
}
@override
void initState() {
// TODO: implement initState
eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError);
super.initState();
}
void _onEvent(Object event) {
setState(() {
_IncomingCallStatus = "Battery status: $event";
SendData(); <-------- This need to be working on background
print('++++++++++++');
});
}
void _onError(Object error) {
setState(() {
_IncomingCallStatus = 'Battery status: unknown.';
});
}
Actually the words like battery status, batteryCahnenl and all is because I just copied this code from flutter platform channel example...pls just ignore
The way platform channels work is the Flutter app executes a method to run platform-specific code. The Flutter app then waits for a callback to be made that can then be handled.
You may want to narrow down the scope that you're trying to achieve in this question. Like when do you intend to call sendData()
from platform-specific code? Do you expect to listen for notifications like firebase_messaging ? If you'd like to run tasks in the background using Flutter, you may want to look into usingIsolate .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.