How can I turn off my Android device using Flutter?

Android

Kotlin

Flutter

Dart

Android com Kotlin

24/10/2024

I need to turn off my device through Flutter, but I didn't find anything that said I could do this through Flutter, I went into some forums and saw that I could do it through Kotli, I tried to do it as they said but it's giving errors.

I'll show you my files to see if you find something wrong or if you can solve it in another way.

AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.shoudown_device">
    <uses-permission android:name="android.permission.SHUTDOWN"/>
    <uses-permission android:name="android.permission.REBOOT"/>
    <application
        android:label="shoudown_device"
        android:name="$"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:taskAffinity=""
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- Specifies an Android theme to apply to this Activity as soon as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
              />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
    <!-- Required to query activities that can process text, see:
         https://developer.android.com/training/package-visibility and
         https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.

         In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
    <queries>
        <intent>
            <action android:name="android.intent.action.PROCESS_TEXT"/>
            <data android:mimeType="text/plain"/>
        </intent>
    </queries>
</manifest>


MainActivity.kt:

package com.example.shoudown_device

import android.content.Intent
import android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "com.example.shoudown_device"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "shutdownDevice") {
                shutdownDevice()
                result.success("Shutdown requested")
            } else {
                result.notImplemented()
            }
        }
    }

    private fun shutdownDevice() {
        val requestShutdownIntent = Intent("com.android.internal.intent.action.REQUEST_SHUTDOWN")
        requestShutdownIntent.putExtra("android.intent.extra.KEY_CONFIRM", false)
        requestShutdownIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        startActivity(requestShutdownIntent)
    } 
    
}


shutdown.dart(I call this class in a button only):
import 'package:flutter/services.dart';

class SystemControl {
  static const platform = MethodChannel('com.example.shoudown_device');

  // Método para solicitar o desligamento do dispositivo
  Future<void> shutdownDevice() async {
    try {
      final String result = await platform.invokeMethod('shutdownDevice');
      print(result); // Resposta do código nativo
    } on PlatformException catch (e) {
      print("Failed to shutdown device: '${e.message}'.");
    }
  }
}


The error I'm getting is this:

[code=xml]
E/MethodChannel#com.example.shoudown_device( 5323): Failed to handle method call
E/MethodChannel#com.example.shoudown_device( 5323): java.lang.SecurityException: Permission Denial: starting Intent { act=com.android.internal.intent.action.REQUEST_SHUTDOWN flg=0x10000000 cmp=android/com.android.internal.app.ShutdownActivity (has extras) } from ProcessRecord{7be54c2 5323:com.example.shoudown_device/u0a143} (pid=5323, uid=10143) requires android.permission.SHUTDOWN
E/MethodChannel#com.example.shoudown_device( 5323): at android.os.Parcel.createExceptionOrNull(Parcel.java:2456)
E/MethodChannel#com.example.shoudown_device( 5323): at android.os.Parcel.createException(Parcel.java:2440)
E/MethodChannel#com.example.shoudown_device( 5323): at android.os.Parcel.readException(Parcel.java:2423)
E/MethodChannel#com.example.shoudown_device( 5323): at android.os.Parcel.readException(Parcel.java:2365)
E/MethodChannel#com.example.shoudown_device( 5323): at android.app.IActivityTaskManager$Stub$Proxy.startActivity(IActivityTaskManager.java:2284)
E/MethodChannel#com.example.shoudown_device( 5323): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1743)
E/MethodChannel#com.example.shoudown_device( 5323): at android.app.Activity.startActivityForResult(Activity.java:5403)
E/MethodChannel#com.example.shoudown_device( 5323): at android.app.Activity.startActivityForResult(Activity.java:5361)
E/MethodChannel#com.example.shoudown_device( 5323): at android.app.Activity.startActivity(Activity.java:5747)
E/MethodChannel#com.example.shoudown_device( 5323): at android.app.Activity.startActivity(Activity.java:5700)
E/MethodChannel#com.example.shoudown_device( 5323): at com.example.shoudown_device.MainActivity.shutdownDevice(MainActivity.kt:29)
E/MethodChannel#com.example.shoudown_device( 5323): at com.example.shoudown_device.MainActivity.configureFlutterEngine$lambda$0(MainActivity.kt:17)
E/MethodChannel#com.example.shoudown_device( 5323): at com.example.shoudown_device.MainActivity.$r8$lambda$APljckIVDX14C0nSSXpd3ONxQZo(Unknown Source:0)
E/MethodChannel#com.example.shoudown_device( 5323): at com.example.shoudown_device.MainActivity$$ExternalSyntheticLambda0.onMethodCall(Unknown Source:2)
E/MethodChannel#com.example.shoudown_device( 5323): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:267)
E/MethodChannel#com.example.shoudown_device( 5323): at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:292)
E/MethodChannel#com.example.shoudown_device( 5323): at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-
[...]
I/flutter ( 5323): Failed to shutdown device: 'Permission Denial: starting Intent { act=com.android.internal.intent.action.REQUEST_SHUTDOWN flg=0x10000000 cmp=android/com.android.internal.app.ShutdownActivity (has extras) } from ProcessRecord{7be54c2 5323:com.example.shoudown_device/u0a143} (pid=5323, uid=10143) requires android.permission.SHUTDOWN'.

I would be very grateful if you could help me, because this step, being able to turn off the device, is very important for my project.

I'll wait.
André

André

Curtidas 0
POSTAR