Flutter应用控制插件tizen_app_control的使用

Flutter应用控制插件tizen_app_control的使用

pub package

Tizen application control APIs。用于在Tizen设备上启动应用程序。

使用方法

要使用此软件包,在您的 pubspec.yaml 文件中添加 tizen_app_control 作为依赖项。

dependencies:
  tizen_app_control: ^0.2.3

发送启动请求

要发送显式的启动请求,创建一个带有应用ID的 AppControl 实例。

import 'package:tizen_app_control/tizen_app_control.dart';

var request = AppControl(appId: 'com.example.app_id');
await request.sendLaunchRequest();

要发送隐式的启动请求,创建一个 AppControl 实例并指定必要的条件,如操作、URI和MIME类型。例如,如果您想通过手表设备上的短信共享文本消息,将 operation 设置为 http://tizen.org/appcontrol/operation/share_text

import 'package:tizen_app_control/tizen_app_control.dart';

await AppControl(
  operation: 'http://tizen.org/appcontrol/operation/share_text',
  uri: 'sms:',
  launchMode: LaunchMode.group,
  extraData: {
    'http://tizen.org/appcontrol/data/text': 'Some text',
  },
).sendLaunchRequest();

有关Tizen应用控制的详细信息,请参阅Tizen文档:应用管理器 - 应用控制。对于常见的操作类型和示例,请参阅Tizen文档:应用管理器 - 常见应用控制。操作和数据常量(如 http://tizen.org/appcontrol/operation/view)定义在原生API引用中。

接收启动请求

您可以使用 AppControl.onAppControl 订阅传入的应用程序控制。

import 'package:tizen_app_control/tizen_app_control.dart';

var subscription = AppControl.onAppControl.listen((request) async {
  if (request.shouldReply) {
    var reply = AppControl();
    await request.reply(reply, AppControlReplyResult.succeeded);
  }
});
...
await subscription.cancel();

必需的权限

执行请求操作可能需要权限。在您的应用的 tizen-manifest.xml 中添加所需的权限。

<privileges>
  <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
  <!-- 以下为可选权限 -->
  <privilege>http://tizen.org/privilege/call</privilege>
  <privilege>http://tizen.org/privilege/download</privilege>
</privileges>

完整示例代码

以下是完整的示例代码:

// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:messageport_tizen/messageport_tizen.dart';
import 'package:tizen_app_control/tizen_app_control.dart';
import 'package:tizen_app_manager/tizen_app_manager.dart';

const String _kAppId = 'org.tizen.tizen_app_control_example';
const String _kServiceAppId = 'org.tizen.tizen_app_control_example_service';
const String _kPortName = 'service_port';

/// 主UI应用入口点。
void main() {
  runApp(const MyApp());
}

/// 服务应用入口点。
[@pragma](/user/pragma)('vm:entry-point')
void serviceMain() {
  // 此调用是必需的以使用平台通道。
  WidgetsFlutterBinding.ensureInitialized();

  // 监听传入的应用控制。
  final StreamSubscription<ReceivedAppControl> appControlListener =
      AppControl.onAppControl.listen((ReceivedAppControl request) async {
    if (request.shouldReply) {
      final AppControl reply = AppControl();
      await request.reply(reply, AppControlReplyResult.succeeded);
    }
  });

  // 连接到UI应用并发送消息。
  // 如果UI应用未运行,则会抛出异常。
  RemotePort.connect(_kAppId, _kPortName).then((RemotePort remotePort) async {
    while (true) {
      if (await remotePort.check()) {
        await remotePort.send(null);
      } else {
        break;
      }
      await Future<void>.delayed(const Duration(seconds: 1));
    }
  }).whenComplete(() async {
    await appControlListener.cancel();
    await SystemNavigator.pop();
  });
}

/// 主UI应用小部件。
class MyApp extends StatefulWidget {
  /// 主UI应用小部件。
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final GlobalKey<ScaffoldMessengerState> _messengerKey =
      GlobalKey<ScaffoldMessengerState>();
  LocalPort? _localPort;
  int _messagesCount = 0;
  bool _isServiceStarted = false;

  [@override](/user/override)
  void initState() {
    super.initState();

    // 打开一个消息端口以接收来自服务应用的消息。
    LocalPort.create(_kPortName).then((LocalPort value) {
      _localPort = value;
      _localPort?.register((dynamic message, [RemotePort? remotePort]) {
        setState(() {
          _messagesCount++;
        });
      });
    });
  }

  [@override](/user/override)
  void dispose() {
    super.dispose();

    _localPort?.unregister();
  }

  Future<void> _sendSms() async {
    final AppControl request = AppControl(
      operation: 'http://tizen.org/appcontrol/operation/share_text',
      uri: 'sms:',
      launchMode: LaunchMode.group,
      extraData: <String, dynamic>{
        'http://tizen.org/appcontrol/data/text': 'Some text',
      },
    );
    final List<String> matches = await request.getMatchedAppIds();
    if (matches.isEmpty) {
      _messengerKey.currentState!.showSnackBar(
        const SnackBar(content: Text('No application found.')),
      );
      return;
    }
    await request.sendLaunchRequest();
  }

  Future<void> _pickImage() async {
    final AppControl request = AppControl(
      operation: 'http://tizen.org/appcontrol/operation/pick',
      mime: 'image/*',
      launchMode: LaunchMode.group,
    );
    final List<String> matches = await request.getMatchedAppIds();
    if (matches.isEmpty) {
      _messengerKey.currentState!.showSnackBar(
        const SnackBar(content: Text('No application found.')),
      );
      return;
    }
    await request.sendLaunchRequest(
      replyCallback: (
        AppControl request,
        AppControl reply,
        AppControlReplyResult result,
      ) {
        const String kAppControlDataSelected =
            'http://tizen.org/appcontrol/data/selected';
        String? imagePath;
        if (result == AppControlReplyResult.succeeded &&
            reply.extraData.containsKey(kAppControlDataSelected)) {
          final List<String> imagePaths =
              (reply.extraData[kAppControlDataSelected] as List<Object?>)
                  .cast<String>();
          imagePath = imagePaths[0];
        }
        _messengerKey.currentState!.showSnackBar(
          SnackBar(content: Text(imagePath ?? 'No image selected.')),
        );
      },
    );
  }

  Future<void> _launchService() async {
    final AppControl request = AppControl(appId: _kServiceAppId);
    await request.sendLaunchRequest(
      replyCallback: (
        AppControl request,
        AppControl reply,
        AppControlReplyResult result,
      ) {
        if (result == AppControlReplyResult.succeeded) {
          setState(() {
            _isServiceStarted = true;
          });
        } else {
          _messengerKey.currentState!.showSnackBar(
            const SnackBar(content: Text('Launch failed.')),
          );
        }
      },
    );
  }

  Future<void> _terminateService() async {
    final AppRunningContext context = AppRunningContext(appId: _kServiceAppId);
    context.terminate(background: true);
    setState(() {
      _isServiceStarted = false;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      scaffoldMessengerKey: _messengerKey,
      home: Scaffold(
        appBar: AppBar(title: const Text('Tizen App Control Example')),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              ElevatedButton(
                onPressed: _sendSms,
                child: const Text('Send SMS'),
              ),
              const SizedBox(height: 10),
              ElevatedButton(
                onPressed: _pickImage,
                child: const Text('Pick image'),
              ),
              const SizedBox(height: 10),
              if (_isServiceStarted)
                ElevatedButton(
                  onPressed: _terminateService,
                  style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.redAccent),
                  child: const Text('Terminate service'),
                )
              else
                ElevatedButton(
                  onPressed: _launchService,
                  child: const Text('Launch service'),
                ),
              const SizedBox(height: 10),
              Text('Received messages: $_messagesCount'),
            ],
          ),
        ),
      ),
    );
  }
}

更多关于Flutter应用控制插件tizen_app_control的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter应用控制插件tizen_app_control的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter应用中使用tizen_app_control插件来控制Tizen设备上的其他应用的示例代码。这个插件允许你在Flutter应用中启动其他应用并与之交互。

首先,确保你已经在pubspec.yaml文件中添加了tizen_app_control依赖:

dependencies:
  flutter:
    sdk: flutter
  tizen_app_control: ^x.y.z  # 请替换为最新版本号

然后,运行flutter pub get来安装依赖。

以下是一个简单的示例代码,展示了如何使用tizen_app_control插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Tizen App Control Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Tizen App Control Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: _launchCalendarApp,
              child: Text('Launch Calendar App'),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _launchCalendarApp() async {
    try {
      // 创建AppControl对象
      final appControl = AppControl(
        operation: AppControlOperation.VIEW,
        uri: 'calendar://',
        mimeType: 'application/vnd.tizen.calendar',
      );

      // 启动应用
      await appControl.launch();
    } catch (e) {
      // 处理异常
      print('Failed to launch app: $e');
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('Failed to launch app: $e'),
        ),
      );
    }
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个按钮。当用户点击按钮时,将尝试使用tizen_app_control插件启动Tizen设备上的日历应用。

  • AppControl对象被配置为执行VIEW操作,目标URI为calendar://,MIME类型为application/vnd.tizen.calendar
  • appControl.launch()方法用于启动指定的应用。

请注意,上述代码中的URI和MIME类型可能需要根据你想要启动的实际应用进行调整。不同的应用可能有不同的URI方案和MIME类型。

此外,确保你的Flutter应用已经针对Tizen平台进行了配置,并且tizen_app_control插件兼容你的Tizen设备或模拟器。

希望这个示例能帮助你理解如何在Flutter应用中使用tizen_app_control插件来控制Tizen设备上的其他应用。

回到顶部