IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Flutter读取剪贴板中的内容 -> 正文阅读

[移动开发]Flutter读取剪贴板中的内容

昨天刚学到的知识,来记录下,客户需求是将收货地址粘贴到文本框中并识别出收件人、地址和电话(这个网上有相应接口),于是乎我想到了现在有些APP(某宝、某音、某东等等等等)在其他地方粘贴好文字之后切换回APP可以直接读取到剪贴板的内容,所以我想搞一下,下面是代码~

首先是简单的读取剪贴板中内容:

//获取粘贴板中的文本
ClipboardData data = await Clipboard.getData(Clipboard.kTextPlain);
if (data != null) {
  //这里是一个剪贴板对象,调用data.text就是文本,其他的内容各位自行查看
  print(data);
}

//粘贴文本
Clipboard.setData(ClipboardData(text:text));

but,用我的安卓11手机测试时读取不到内容 => 为null,后来到网上找资料说安卓10以后resumed状态下无法获取剪贴板内容;在Android 高版本上,AndroidQ 对剪切板的改动是:当应用没有获取到焦点时,无法读取剪切板内容。于是乎我找到了一位大佬的博客,他的思路是这样婶儿滴:在页面中创建一个FocusNode用于获取文本框焦点,并在initState方法中对FocusNode进行监听,当从后台切换回APP(即resumed状态)时,获取到文本框的焦点并赋值,接下来上代码:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:io';
import 'package:device_info/device_info.dart';

class TestPage extends StatefulWidget {
  final arguments;
  TestPage({Key key, this.arguments}) : super(key : key);
  _TestPageState createState() => _TestPageState(this.arguments);
}

// 注意:WidgetsBindingObserver要一起继承
class _TestPageState extends State<TestPage> with WidgetsBindingObserver {
  final arguments;
  _TestPageState(this.arguments);

  //FocusNode
  FocusNode jkNode = new FocusNode();
  //文本框controller
  TextEditingController jkC = new TextEditingController();

  @override
  void initState() {
    WidgetsBinding.instance.addObserver(this);
    //判断是否是安卓10以上设备
    _judgeTen();
    super.initState();
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
    // 处于这种状态的应用程序应该假设它们可能在任何时候暂停。
      case AppLifecycleState.inactive:
        break;
    // 应用程序可见,前台
      case AppLifecycleState.resumed:
        //判断平台信息
        _judgePlatformInfo();
        break;
    // 应用程序不可见,后台
      case AppLifecycleState.paused:
        break;
    // 申请将暂时暂停
      case AppLifecycleState.detached:
        break;
    }
  }

  //判断是否是安卓10以上设备
  _judgeTen () async {
    //获取设备信息
    DeviceInfoPlugin dip = new DeviceInfoPlugin();
    AndroidDeviceInfo adi = await dip.androidInfo;
    //经亲测发现安卓10以下取到的版本号是xxx.0,安卓10以上直接取到10或者11
    String version = "";
    if (adi.version.release.contains(".")) {
      //判断版本号中是否有.,有的话用.分割一下取得那个整数(返回的是字符串类型)
      var haha = adi.version.release.split(".");
      version = haha[0];
    } else {
      version = adi.version.release;
    }
    //如果版本号大于等于10,则监听FocusNode
    if ( int.parse(version) >= 10 ) {
      _androidAboveTengetClipboardContent();
    }
  }

  //判断平台信息
  _judgePlatformInfo () async {
    if (Platform.isAndroid) {
      DeviceInfoPlugin dip = new DeviceInfoPlugin();
      AndroidDeviceInfo adi = await dip.androidInfo;
      String version = "";
      if (adi.version.release.contains(".")) {
        var haha = adi.version.release.split(".");
        version = haha[0];
      } else {
        version = adi.version.release;
      }
      if ( int.parse(version) < 10 ) {
        _androidBelowTengetClipboardContent();
      } else {
        FocusScope.of(context).requestFocus(jkNode);
      }
    }
  }

  //获取剪贴板内容:安卓10以下和以上两个方法
  _androidBelowTengetClipboardContent () async {
    ClipboardData data = await Clipboard.getData(Clipboard.kTextPlain);
    if (data != null) {
      this.jkC.text = data.text;
    }
  }

  _androidAboveTengetClipboardContent () async {
    jkNode.addListener(() async {
      if (jkNode.hasFocus) {
        FocusScope.of(context).unfocus();
        ClipboardData data = await Clipboard.getData(Clipboard.kTextPlain);
        if (data != null) {
          this.jkC.text = data.text;
        }
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("测试"),
      ),
      body: Center(
        child: TextField(
          textInputAction: TextInputAction.done,
          focusNode: jkNode,
          controller: jkC,
          onEditingComplete: (){
            FocusScope.of(context).unfocus();
          },
          decoration: InputDecoration(
            hintText: "请输入快递地址信息",
          ),
          onChanged: (val) {
            print(val);
          },
        ),
      ),
    );
  }
}

正常状况下,当你把flutter app切到后台,到别的地方赋值文字后再切回app文本框里是有文字的了,亲测有效~

但是作者后面又有改动,是通过原生安卓插件实现的,这里我就没仔细研究了,因为只自学过flutter,安卓丝毫不动,下面是我借鉴的地址:android读取剪切板选中内容,Android 10 Flutter resume状态下读取剪切板内容_体制内生存之道的博客-CSDN博客,代码有点儿乱哈哈,各位自己归纳吧~

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-12-02 16:52:58  更:2021-12-02 16:54:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:17:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码