Flutter - Escribir código específico de Android
Flutter proporciona un marco general para acceder a funciones específicas de la plataforma. Esto permite al desarrollador ampliar la funcionalidad del marco Flutter utilizando código específico de la plataforma. Se puede acceder fácilmente a funciones específicas de la plataforma, como cámara, nivel de batería, navegador, etc., a través del marco.
La idea general de acceder al código específico de la plataforma es a través de un protocolo de mensajería simple. El código Flutter, el cliente y el código de la plataforma y el host se vinculan a un canal de mensajes común. El cliente envía un mensaje al anfitrión a través del canal de mensajes. El Anfitrión escucha en el Canal de Mensajes, recibe el mensaje y hace la funcionalidad necesaria y finalmente, devuelve el resultado al Cliente a través del Canal de Mensajes.
La arquitectura de código específica de la plataforma se muestra en el diagrama de bloques que se muestra a continuación:
El protocolo de mensajería utiliza un códec de mensajes estándar (clase StandardMessageCodec) que admite la serialización binaria de valores similares a JSON como números, cadenas, booleanos, etc. La serialización y deserialización funciona de forma transparente entre el cliente y el host.
Escribamos una aplicación simple para abrir un navegador usando el SDK de Android y entendamos cómo
Cree una nueva aplicación Flutter en Android Studio, flutter_browser_app
Reemplace el código main.dart con el siguiente código:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(this.title),
),
body: Center(
child: RaisedButton(
child: Text('Open Browser'),
onPressed: null,
),
),
);
}
}
Aquí, hemos creado un nuevo botón para abrir el navegador y establecer su método onPressed como nulo.
Ahora, importe los siguientes paquetes:
import 'dart:async';
import 'package:flutter/services.dart';
Aquí, services.dart incluye la funcionalidad para invocar código específico de la plataforma.
Cree un nuevo canal de mensajes en el widget MyHomePage.
static const platform = const
MethodChannel('flutterapp.tutorialspoint.com/browser');
Escriba un método, _openBrowser para invocar el método específico de la plataforma, el método openBrowser a través del canal de mensajes.
Future<void> _openBrowser() async {
try {
final int result = await platform.invokeMethod(
'openBrowser', <String, String>{
'url': "https://flutter.dev"
}
);
}
on PlatformException catch (e) {
// Unable to open the browser
print(e);
}
}
Aquí, hemos utilizado platform.invokeMethod para invocar openBrowser (explicado en los próximos pasos). openBrowser tiene un argumento, url para abrir una URL específica.
Cambie el valor de la propiedad onPressed de RaisedButton de nulo a _openBrowser.
onPressed: _openBrowser,
Abra MainActivity.java (dentro de la carpeta de Android) e importe la biblioteca requerida -
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugins.GeneratedPluginRegistrant;
Escriba un método, openBrowser para abrir un navegador
private void openBrowser(MethodCall call, Result result, String url) {
Activity activity = this;
if (activity == null) {
result.error("ACTIVITY_NOT_AVAILABLE",
"Browser cannot be opened without foreground
activity", null);
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
activity.startActivity(intent);
result.success((Object) true);
}
Ahora, configure el nombre del canal en la clase MainActivity -
private static final String CHANNEL = "flutterapp.tutorialspoint.com/browser";
Escriba el código específico de Android para configurar el manejo de mensajes en el método onCreate -
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
new MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, Result result) {
String url = call.argument("url");
if (call.method.equals("openBrowser")) {
openBrowser(call, result, url);
} else {
result.notImplemented();
}
}
});
Aquí, hemos creado un canal de mensajes usando la clase MethodChannel y usamos la clase MethodCallHandler para manejar el mensaje. onMethodCall es el método real responsable de llamar al código específico de la plataforma correcta al verificar el mensaje. El método onMethodCall extrae la URL del mensaje y luego invoca openBrowser solo cuando la llamada al método es openBrowser. De lo contrario, devuelve el método notImplemented.
El código fuente completo de la aplicación es el siguiente:
main.dart
MainActivity.java
package com.tutorialspoint.flutterapp.flutter_browser_app;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "flutterapp.tutorialspoint.com/browser";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
new MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, Result result) {
String url = call.argument("url");
if (call.method.equals("openBrowser")) {
openBrowser(call, result, url);
} else {
result.notImplemented();
}
}
}
);
}
private void openBrowser(MethodCall call, Result result, String url) {
Activity activity = this; if (activity == null) {
result.error(
"ACTIVITY_NOT_AVAILABLE", "Browser cannot be opened without foreground activity", null
);
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
activity.startActivity(intent);
result.success((Object) true);
}
}
main.dart
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(
title: 'Flutter Demo Home Page'
),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
static const platform = const MethodChannel('flutterapp.tutorialspoint.com/browser');
Future<void> _openBrowser() async {
try {
final int result = await platform.invokeMethod('openBrowser', <String, String>{
'url': "https://flutter.dev"
});
}
on PlatformException catch (e) {
// Unable to open the browser print(e);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(this.title),
),
body: Center(
child: RaisedButton(
child: Text('Open Browser'),
onPressed: _openBrowser,
),
),
);
}
}
Ejecute la aplicación y haga clic en el botón Abrir navegador y podrá ver que se inicia el navegador. La aplicación del navegador - La página de inicio es como se muestra en la captura de pantalla aquí -