简体   繁体   中英

Run a method or function in dart when a callback from native android methodchannel

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM