admin管理员组

文章数量:1022853

i am working on BLE releated project. i am making an app for making my device peripheral device using flutter_ble_peripheral_central package i hvae made background service using flutter_background_service. when i am sending message from central device i am getting exception : W/FlutterJNI(418): Tried to send a platform message to Flutter, but FlutterJNI was detached from native C++. Could not send. Channel: ble_peripheral/event. Response ID: 35

i want this application to run this service even when the app is closed from recent apps. For now app is working fine when app is open in recent apps.


// my mainAcitivity.kt code:
package com.novice.flutter_ble_peripheral_central_example
import android.content.Intent
import android.os.Build
import android.view.KeyEvent
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.pluginmon.MethodChannel
import java.io.DataOutputStream

class MainActivity : FlutterActivity() {
private val CHANNEL = "com.novice.key_simulator"
//    private val methodChannel = "com.novice.key_simulator"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
    
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "startService" -> {
                    val intent = Intent(this, KeyPressService::class.java)
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        startForegroundService(intent) // Use startForegroundService for modern Android versions
                    } else {
                        startService(intent)
                    }
                    result.success(null)
                }
                "startBackgroundService" -> {
                    startService(Intent(this, KeyPressService::class.java))
                    result.success(null)
                }
                "pressUpArrow" -> {
                    pressKey(KeyEvent.KEYCODE_DPAD_UP)
                    result.success(null)
                }
                "pressDownArrow" -> {
                    pressKey(KeyEvent.KEYCODE_DPAD_DOWN)
                    result.success(null)
                }
                "pressLeftArrow" -> {
                    pressKey(KeyEvent.KEYCODE_DPAD_LEFT)
                    result.success(null)
                }
                "pressRightArrow" -> {
                    pressKey(KeyEvent.KEYCODE_DPAD_RIGHT)
                    result.success(null)
                }
                "pressEnter" -> {
                    pressKey(KeyEvent.KEYCODE_ENTER)
                    result.success(null)
                }
                "pressBack" -> {
                    pressKey(KeyEvent.KEYCODE_BACK)
                    result.success(null)
                }
                "pressHome" -> {
                    pressKey(KeyEvent.KEYCODE_HOME)
                    result.success(null)
                }
                else -> result.notImplemented()
            }
        }
    }
    
    private fun pressKey(keyCode: Int) {
        try {
            val process = Runtime.getRuntime().exec("su")
            DataOutputStream(process.outputStream).use { os ->
                os.writeBytes("input keyevent $keyCode\n")
                os.flush()
            }
            process.waitFor()
        } catch (e: Exception) {
            if (e is android.os.DeadObjectException) {
                // Log or handle the exception, possibly notify the user or restart the process
                e.printStackTrace()
            } else {
                e.printStackTrace()
            }
        }
    }

}
// my flutter code for peripheral device:


import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_ble_peripheral_central/flutter_ble_peripheral_central.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';

class PeripheralController extends GetxController {
void onInit() async{
super.onInit();
// bleStartAdvertising("advertisingText", "readableText");
}

List\<String\> events = \[\];
final eventStreamController = StreamController\<String\>();
final bluetoothState = TextEditingController();
final advertisingText= TextEditingController();
final readableText= TextEditingController();
final indicateText= TextEditingController();
final writeableText= TextEditingController();
bool isSwitchOn = false;
StreamSubscription\<dynamic\>? eventSubscription;
final ScrollController scrollController = ScrollController();
final \_flutterBlePeripheralCentralPlugin = FlutterBlePeripheralCentral();

void permissionCheck() async {
if (Platform.isAndroid) {
var permission = await Permission.location.request();
var bleScan = await Permission.bluetoothScan.request();
var bleConnect = await Permission.bluetoothConnect.request();
var bleAdvertise = await Permission.bluetoothAdvertise.request();
var locationWhenInUse = await Permission.locationWhenInUse.request();

      print('location permission: ${permission.isGranted}');
      print('bleScan permission: ${bleScan.isGranted}');
      print('bleConnect permission: ${bleConnect.isGranted}');
      print('bleAdvertise permission: ${bleAdvertise.isGranted}');
      print('location locationWhenInUse: ${locationWhenInUse.isGranted}');
    }

}

void clearLog() {
events.clear();
update();
}

void addEvent(String event) {
events.add(event);
update();

    Map<String, dynamic> responseMap = jsonDecode(event);
    
    if (responseMap.containsKey('message')) {
      String message = responseMap['message'];
      print('Message: $message');
    } else if(responseMap.containsKey('state')) {
      bluetoothState.text = responseMap['state'];
      // setState(() {
      // });
    
      if (event == 'disconnected') {
        eventSubscription?.cancel();
      }
    } else if(responseMap.containsKey('onCharacteristicWriteRequest')) {
      // setState(() {
        // add conditions here for moving cursor
        writeableText.text = responseMap['onCharacteristicWriteRequest'];
        if (writeableText.text == "up") {
          KeySimulator.pressUpArrow();
        } else if (writeableText.text == "down") {
          KeySimulator.pressDownArrow();
        } else if (writeableText.text == "left") {
          KeySimulator.pressLeftArrow();
        } else if (writeableText.text == "right") {
          KeySimulator.pressRightArrow();
        } else if (writeableText.text == "enter") {
          KeySimulator.pressEnter();
        } else if (writeableText.text == "home") {
          KeySimulator.pressHome();
        } else if (writeableText.text == "back") {
          KeySimulator.pressBack();
        }
      // });
    } else {
      print('Message key not found in the JSON response.');
    }

}

restartAdvertising()async{
await bleStopAdvertising();
await bleStartAdvertising("advertisingText", "readableText");
print("restarted");

}

bleStartAdvertising(String advertisingText, String readableText) async {
clearLog();
eventStreamController.sink.add('Starting...');

    eventSubscription = await _flutterBlePeripheralCentralPlugin
        .startBlePeripheralService(advertisingText, readableText)
        .listen((event) {
    
      eventStreamController.sink.add('-> '+event);
    
      addEvent(event);
    
      print('peripheral event: ' + event);
    });

}

bleStopAdvertising() async {
await \_flutterBlePeripheralCentralPlugin.stopBlePeripheralService();
}
void bleEditTextCharForRead(String readableText) async {
await \_flutterBlePeripheralCentralPlugin.editTextCharForRead(readableText);
}
void bleIndicate(String sendData) async {
await \_flutterBlePeripheralCentralPlugin.sendIndicate(sendData);
}

void onClose() {
// Dispose of resources when the controller is closed
super.onClose();
}
}

class KeySimulator {
static const platform = MethodChannel('com.novice.key_simulator');

static Future\<void\> pressUpArrow() async =\> \_pressKey("pressUpArrow");
static Future\<void\> pressDownArrow() async =\> \_pressKey("pressDownArrow");
static Future\<void\> pressLeftArrow() async =\> \_pressKey("pressLeftArrow");
static Future\<void\> pressRightArrow() async =\> \_pressKey("pressRightArrow");
static Future\<void\> pressEnter() async =\> \_pressKey("pressEnter");
static Future\<void\> pressBack() async =\> \_pressKey("pressBack");
static Future\<void\> pressHome() async =\> \_pressKey("pressHome");

static Future\<void\> \_pressKey(String method) async {
try {
await platform.invokeMethod(method);
} on PlatformException catch (e) {
print("Failed to press $method: '${e.message}'.");
}
}
}

i am working on BLE releated project. i am making an app for making my device peripheral device using flutter_ble_peripheral_central package i hvae made background service using flutter_background_service. when i am sending message from central device i am getting exception : W/FlutterJNI(418): Tried to send a platform message to Flutter, but FlutterJNI was detached from native C++. Could not send. Channel: ble_peripheral/event. Response ID: 35

i want this application to run this service even when the app is closed from recent apps. For now app is working fine when app is open in recent apps.


// my mainAcitivity.kt code:
package com.novice.flutter_ble_peripheral_central_example
import android.content.Intent
import android.os.Build
import android.view.KeyEvent
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.pluginmon.MethodChannel
import java.io.DataOutputStream

class MainActivity : FlutterActivity() {
private val CHANNEL = "com.novice.key_simulator"
//    private val methodChannel = "com.novice.key_simulator"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
    
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "startService" -> {
                    val intent = Intent(this, KeyPressService::class.java)
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        startForegroundService(intent) // Use startForegroundService for modern Android versions
                    } else {
                        startService(intent)
                    }
                    result.success(null)
                }
                "startBackgroundService" -> {
                    startService(Intent(this, KeyPressService::class.java))
                    result.success(null)
                }
                "pressUpArrow" -> {
                    pressKey(KeyEvent.KEYCODE_DPAD_UP)
                    result.success(null)
                }
                "pressDownArrow" -> {
                    pressKey(KeyEvent.KEYCODE_DPAD_DOWN)
                    result.success(null)
                }
                "pressLeftArrow" -> {
                    pressKey(KeyEvent.KEYCODE_DPAD_LEFT)
                    result.success(null)
                }
                "pressRightArrow" -> {
                    pressKey(KeyEvent.KEYCODE_DPAD_RIGHT)
                    result.success(null)
                }
                "pressEnter" -> {
                    pressKey(KeyEvent.KEYCODE_ENTER)
                    result.success(null)
                }
                "pressBack" -> {
                    pressKey(KeyEvent.KEYCODE_BACK)
                    result.success(null)
                }
                "pressHome" -> {
                    pressKey(KeyEvent.KEYCODE_HOME)
                    result.success(null)
                }
                else -> result.notImplemented()
            }
        }
    }
    
    private fun pressKey(keyCode: Int) {
        try {
            val process = Runtime.getRuntime().exec("su")
            DataOutputStream(process.outputStream).use { os ->
                os.writeBytes("input keyevent $keyCode\n")
                os.flush()
            }
            process.waitFor()
        } catch (e: Exception) {
            if (e is android.os.DeadObjectException) {
                // Log or handle the exception, possibly notify the user or restart the process
                e.printStackTrace()
            } else {
                e.printStackTrace()
            }
        }
    }

}
// my flutter code for peripheral device:


import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_ble_peripheral_central/flutter_ble_peripheral_central.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';

class PeripheralController extends GetxController {
void onInit() async{
super.onInit();
// bleStartAdvertising("advertisingText", "readableText");
}

List\<String\> events = \[\];
final eventStreamController = StreamController\<String\>();
final bluetoothState = TextEditingController();
final advertisingText= TextEditingController();
final readableText= TextEditingController();
final indicateText= TextEditingController();
final writeableText= TextEditingController();
bool isSwitchOn = false;
StreamSubscription\<dynamic\>? eventSubscription;
final ScrollController scrollController = ScrollController();
final \_flutterBlePeripheralCentralPlugin = FlutterBlePeripheralCentral();

void permissionCheck() async {
if (Platform.isAndroid) {
var permission = await Permission.location.request();
var bleScan = await Permission.bluetoothScan.request();
var bleConnect = await Permission.bluetoothConnect.request();
var bleAdvertise = await Permission.bluetoothAdvertise.request();
var locationWhenInUse = await Permission.locationWhenInUse.request();

      print('location permission: ${permission.isGranted}');
      print('bleScan permission: ${bleScan.isGranted}');
      print('bleConnect permission: ${bleConnect.isGranted}');
      print('bleAdvertise permission: ${bleAdvertise.isGranted}');
      print('location locationWhenInUse: ${locationWhenInUse.isGranted}');
    }

}

void clearLog() {
events.clear();
update();
}

void addEvent(String event) {
events.add(event);
update();

    Map<String, dynamic> responseMap = jsonDecode(event);
    
    if (responseMap.containsKey('message')) {
      String message = responseMap['message'];
      print('Message: $message');
    } else if(responseMap.containsKey('state')) {
      bluetoothState.text = responseMap['state'];
      // setState(() {
      // });
    
      if (event == 'disconnected') {
        eventSubscription?.cancel();
      }
    } else if(responseMap.containsKey('onCharacteristicWriteRequest')) {
      // setState(() {
        // add conditions here for moving cursor
        writeableText.text = responseMap['onCharacteristicWriteRequest'];
        if (writeableText.text == "up") {
          KeySimulator.pressUpArrow();
        } else if (writeableText.text == "down") {
          KeySimulator.pressDownArrow();
        } else if (writeableText.text == "left") {
          KeySimulator.pressLeftArrow();
        } else if (writeableText.text == "right") {
          KeySimulator.pressRightArrow();
        } else if (writeableText.text == "enter") {
          KeySimulator.pressEnter();
        } else if (writeableText.text == "home") {
          KeySimulator.pressHome();
        } else if (writeableText.text == "back") {
          KeySimulator.pressBack();
        }
      // });
    } else {
      print('Message key not found in the JSON response.');
    }

}

restartAdvertising()async{
await bleStopAdvertising();
await bleStartAdvertising("advertisingText", "readableText");
print("restarted");

}

bleStartAdvertising(String advertisingText, String readableText) async {
clearLog();
eventStreamController.sink.add('Starting...');

    eventSubscription = await _flutterBlePeripheralCentralPlugin
        .startBlePeripheralService(advertisingText, readableText)
        .listen((event) {
    
      eventStreamController.sink.add('-> '+event);
    
      addEvent(event);
    
      print('peripheral event: ' + event);
    });

}

bleStopAdvertising() async {
await \_flutterBlePeripheralCentralPlugin.stopBlePeripheralService();
}
void bleEditTextCharForRead(String readableText) async {
await \_flutterBlePeripheralCentralPlugin.editTextCharForRead(readableText);
}
void bleIndicate(String sendData) async {
await \_flutterBlePeripheralCentralPlugin.sendIndicate(sendData);
}

void onClose() {
// Dispose of resources when the controller is closed
super.onClose();
}
}

class KeySimulator {
static const platform = MethodChannel('com.novice.key_simulator');

static Future\<void\> pressUpArrow() async =\> \_pressKey("pressUpArrow");
static Future\<void\> pressDownArrow() async =\> \_pressKey("pressDownArrow");
static Future\<void\> pressLeftArrow() async =\> \_pressKey("pressLeftArrow");
static Future\<void\> pressRightArrow() async =\> \_pressKey("pressRightArrow");
static Future\<void\> pressEnter() async =\> \_pressKey("pressEnter");
static Future\<void\> pressBack() async =\> \_pressKey("pressBack");
static Future\<void\> pressHome() async =\> \_pressKey("pressHome");

static Future\<void\> \_pressKey(String method) async {
try {
await platform.invokeMethod(method);
} on PlatformException catch (e) {
print("Failed to press $method: '${e.message}'.");
}
}
}

本文标签: