flutter: why I cannot get my battery level?

Viewed 696

I'm learning how to connect flutter and native android. I'm practicing an example about get the battery level. Below is my code and error info it's simple but cannot get the result I want.

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'battery level',
      home: MyHomePage(title: 'battery level'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  static const platform = const MethodChannel('samples.fltter.io/battery');
  String _batteryLevel = 'Unknow battery level';

  Future<Null> getBatteryLevel() async {
    String batteryLevel = '';
    try {
      int res = await platform.invokeMethod('getBatteryLevel');
      batteryLevel = 'battery level is: $res';
    } on PlatformException catch(e) {
      batteryLevel = 'caught an error';
    }
    setState(() {
      _batteryLevel = batteryLevel;
    });
    print(_batteryLevel);
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            RaisedButton(
              child: Text('click'),
              onPressed: (){getBatteryLevel();},
            ),
            Text(_batteryLevel),
          ],
        ),
      )
    );
  }
}

E/flutter (11202): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: MissingPluginException(No implementation found for method getBatteryLevel on channel samples.fltter.io/battery)
E/flutter (11202): #0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:154:7)
E/flutter (11202): <asynchronous suspension>
E/flutter (11202): #1      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:329:12)
E/flutter (11202): #2      _MyHomePageState._getBatteryLevel (package:batterylevel/main.dart:54:41)
E/flutter (11202): #3      _MyHomePageState.build.<anonymous closure> (package:batterylevel/main.dart:75:29)
E/flutter (11202): #4      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:779:19)
E/flutter (11202): #5      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:862:36)
E/flutter (11202): #6      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
E/flutter (11202): #7      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:504:11)
E/flutter (11202): #8      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:282:5)
E/flutter (11202): #9      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:217:7)
E/flutter (11202): #10     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:475:9)
E/flutter (11202): #11     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:76:12)
E/flutter (11202): #12     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:122:9)
E/flutter (11202): #13     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:379:8)
E/flutter (11202): #14     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:120:18)
E/flutter (11202): #15     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:106:7)
E/flutter (11202): #16     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19)
E/flutter (11202): #17     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
E/flutter (11202): #18     GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
E/flutter (11202): #19     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
E/flutter (11202): #20     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
E/flutter (11202): #21     _rootRunUnary (dart:async/zone.dart:1196:13)
E/flutter (11202): #22     _CustomZone.runUnary (dart:async/zone.dart:1085:19)
E/flutter (11202): #23     _CustomZone.runUnaryGuarded (dart:async/zone.dart:987:7)
E/flutter (11202): #24     _invoke1 (dart:ui/hooks.dart:275:10)
E/flutter (11202): #25     _dispatchPointerDataPacket (dart:ui/hooks.dart:184:5)

2 Answers

Have you made changes in your mainactivity class?? Replace below code from your MainActivity class in android folder

import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES


class MainActivity: FlutterActivity() {
  private val CHANNEL = "samples.flutter.dev/battery"

  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 ->
      if (call.method == "getBatteryLevel") {
        val batteryLevel = getBatteryLevel()

        if (batteryLevel != -1) {
          result.success(batteryLevel)
        } else {
          result.error("UNAVAILABLE", "Battery level not available.", null)
        }
      } else {
        result.notImplemented()
      }
    }

  }

    private fun getBatteryLevel(): Int {
    val batteryLevel: Int
    if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
      val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
      batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
    } else {
      val intent = ContextWrapper(applicationContext).registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
      batteryLevel = intent!!.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100 / intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
    }

    return batteryLevel
  }
}

It seems like there is no such method in java side. In the example here, you define java side of code and flutter uses that method in java to call battery level. That's what you are missing.

Related