这样处理很多时候依旧获取不到,debug模式下可以,但release情况下很多时候无法获取,暂未知
刚用Flutter练手做了个小项目,有个需求就是当app由后台切回前台的时候,获取剪切板的内容,如果内容是一个网址,就进行解析
监听切回前台很简单,如下:
class _MyHomePageState extends State with WidgetsBindingObserver {
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
}
}
@override
void initState() {
WidgetsBinding.instance.addObserver(this);
super.initState();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
}
如果在切回时去读取剪切板数据,例如:
@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
super.didChangeAppLifecycleState(state);
switch (state) {
case AppLifecycleState.resumed:
ClipboardData data = await Clipboard.getData(Clipboard.kTextPlain);
print("onResumed __${data}");
break;
}
}
这个时候往往读取到的数据为空,因为在android 10中,我们读取剪切板数据往往在 onWindowFocusChanged 方法下读取,也就是说只有在窗体获取到焦点后才能读取剪切板内容,所以可以创建一个FocusNode,用于获取焦点
class _MyHomePageState extends State with WidgetsBindingObserver {
var _focusNode = FocusNode();
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
FocusScope.of(context).requestFocus(_focusNode);
}
}
@override
void initState() {
WidgetsBinding.instance.addObserver(this);
_focusNode.addListener(() async {
if (_focusNode.hasFocus) {
FocusScope.of(context).unfocus();
ClipboardData data = await Clipboard.getData(Clipboard.kTextPlain);
if (data != null) {
//处理剪切板内容
}
}
});
super.initState();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
}
2021/03/11
上面的方法发现效果并不好,最后的还是通过安卓插件来实现,具体如下:
首先将项目下面的android文件夹下的MainActivity (java或者kt,如果是kt,改成java,kt不会。。。) 改成如下:
public class MainActivity extends FlutterActivity implements MethodChannel.MethodCallHandler{
private static final String CHANNEL = "plugins.flutter.io/windowFocusChangedListener";
private MethodChannel windowFocusChangedListenChannel;
@Override
public void onWindowFocusChanged(boolean hasFocus){
super.onWindowFocusChanged(hasFocus);
if (windowFocusChangedListenChannel != null)
windowFocusChangedListenChannel.invokeMethod("onWindowFocusChanged", hasFocus);
}
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine){
super.configureFlutterEngine(flutterEngine);
windowFocusChangedListenChannel = new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL);
windowFocusChangedListenChannel.setMethodCallHandler(this);
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result){
switch (call.method) {
case "onWindowFocusChanged":
result.success(call.arguments);
break;
default:
result.notImplemented();
}
}
}
回到flutter项目,添加代码如下:
if (defaultTargetPlatform == TargetPlatform.android) {
const MethodChannel windowsFocusChangedChannel =
const MethodChannel('plugins.flutter.io/windowFocusChangedListener');
windowsFocusChangedChannel.setMethodCallHandler(_onMethodCall);
}
Future _onMethodCall(MethodCall call) async {
switch (call.method) {
case 'onWindowFocusChanged':
bool focused = call.arguments;
if (focused) {
readFromClipboard();
}
return true;
}
throw MissingPluginException(
'${call.method} was invoked but has no handler',
);
}