자니노트

[Flutter] 앱에 공유된 DATA 정보 받기 - uni_links, receive_sharing_intent 본문

모바일 개발/Dart&Flutter

[Flutter] 앱에 공유된 DATA 정보 받기 - uni_links, receive_sharing_intent

zaninote 2023. 9. 12. 10:21

Flutter로 URL을 공유받는 앱을 만들려면, Android와 iOS에서 각각의 설정과 uni_links 패키지를 사용하여 Flutter 코드를 작성해야 합니다. 다음은 이를 위한 단계별 안내입니다.

 

1. 패키지 추가
pubspec.yaml 파일에 uni_links 패키지를 추가합니다.

dependencies:
  flutter:
    sdk: flutter
  uni_links: ^latest_version

 

2. Android 설정
AndroidManifest.xml 파일에 아래의 <intent-filter>를 추가하여 앱이 텍스트 형식의 URL을 받을 수 있도록 설정합니다.

<activity ...>
    ...
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
    ...
</activity>

 

3. iOS 설정
Info.plist 파일에 아래의 설정을 추가하여 앱이 URL을 받을 수 있도록 설정합니다.

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>com.example.myapp</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>myapp</string>
        </array>
    </dict>
</array>

 

4. Flutter 코드 작성
uni_links 패키지를 사용하여 앱에서 공유된 URL을 받아올 수 있습니다.

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

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _receivedLink = "";

  @override
  void initState() {
    super.initState();
    initUniLinks();
  }

  void initUniLinks() async {
    String initialLink;
    try {
      initialLink = await getInitialLink();
      if (initialLink != null) {
        setState(() {
          _receivedLink = initialLink;
        });
      }
    } catch (e) {
      // Handle error
    }

    getLinksStream().listen((String link) {
      setState(() {
        _receivedLink = link;
      });
    }, onError: (err) {
      // Handle error
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('URL Receiver App')),
        body: Center(
          child: Text('Received Link: $_receivedLink'),
        ),
      ),
    );
  }
}

이 코드는 앱이 실행될 때 처음으로 전달된 URL을 받아와 _receivedLink 변수에 저장하고, 

그 후로 전달되는 URL도 동일한 변수에 저장합니다. 저장된 URL은 화면에 표시됩니다.

이렇게 하면 Flutter 앱이 Android와 iOS에서 URL을 공유받을 수 있도록 설정하고 코드를 작성한 것입니다.

 

그런데 getLinksStream 이게 deprecated 되어서 좀더 찾아봤습니다.

linkStream은 getLinksStream과 같은 방식으로 작동하지만, API가 더 간결하게 변경되었습니다.

 

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

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _receivedLink = "";

  @override
  void initState() {
    super.initState();
    initUniLinks();
  }

  void initUniLinks() async {
    String initialLink;
    try {
      initialLink = await getInitialLink();
      if (initialLink != null) {
        setState(() {
          _receivedLink = initialLink;
        });
      }
    } catch (e) {
      // Handle error
    }

    linkStream.listen((String? link) {
      if (link != null) {
        setState(() {
            _receivedLink = link;
        });
      }
    }, onError: (err) {
      // Handle error
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('URL Receiver App')),
        body: Center(
          child: Text('Received Link: $_receivedLink'),
        ),
      ),
    );
  }
}

 

위에 소스를 간단히 설명하면 아래와 같습니다.

 

함수 선언:

void initUniLinks() async {

초기 링크 얻기:

String? initialLink;
try {
  initialLink = await getInitialLink();
  if (initialLink != null) {
    setState(() {
      _receivedLink = initialLink;
    });
  }
} catch (e) {
  // Handle error
}

getInitialLink()는 앱이 시작될 때 전달된 링크를 가져오는 함수입니다. 앱이 이미 실행 중일 때 링크가 전달되면 이 함수는 해당 링크를 반환하지 않습니다.
await getInitialLink()는 앱이 시작될 때 전달된 링크를 비동기적으로 가져옵니다.
가져온 링크가 null이 아니면, 상태를 업데이트하여 화면에 표시합니다.

 

링크 스트림 리스너 설정:

linkStream.listen((String? link) {
  if (link != null) {
      setState(() {
          _receivedLink = link;
      });
  }
}, onError: (err) {
  // Handle error
});

linkStream은 앱이 실행 중일 때 새로운 링크가 전달될 때마다 이벤트를 발생시키는 스트림입니다.
listen 메서드를 사용하여 링크가 전달될 때마다 호출되는 콜백 함수를 설정합니다.
콜백 함수는 전달된 링크를 받아 화면에 표시합니다.
onError 콜백은 링크 수신 중 오류가 발생할 경우 호출됩니다.

 

이 함수를 통해 앱이 시작될 때 전달된 링크를 처리하고, 앱이 실행 중일 때 새로운 링크가 전달될 때마다 해당 링크를 받아 처리할 수 있게 됩니다.

 

공유하기 앱에서 공유해서 테스트 하거나 adb shell을 이용하여 테스트할 수 있습니다.

아래 방법은 adb를 이용한 방법입니다.

adb shell am start -a android.intent.action.SEND -t text/plain -e android.intent.extra.TEXT "https://example.com"

여기까지가 uni_links 를 이용한 방법입니다.

 

두번째 방법은 receive_sharing_intent 를 이용한 방법입니다.

receive_sharing_intent 패키지는 그 중 하나의 방법으로, Android와 iOS에서 공유된 텍스트나 파일을 받아 처리할 수 있습니다.

 

아래는 receive_sharing_intent 패키지를 사용하는 방법입니다:

패키지 추가:
pubspec.yaml 파일에 receive_sharing_intent 패키지를 추가합니다.

dependencies:
  receive_sharing_intent: latest_version

저같은 경우는 1.4.5 를 사용하였습니다.

 

코드 구현:
receive_sharing_intent 패키지를 사용하여 공유된 텍스트나 파일을 받습니다.

import 'package:receive_sharing_intent/receive_sharing_intent.dart';

...

@override
void initState() {
  super.initState();

  // 공유된 텍스트 받기
  ReceiveSharingIntent.getInitialText().then((String? value) {
    if (value != null) {
      // 여기서 value를 처리합니다. (예: 화면 전환, 데이터 표시 등)
    }
  });

  // 파일 공유 받기 (예: 이미지, 동영상 등)
  ReceiveSharingIntent.getInitialMedia().then((List<SharedMediaFile>? value) {
    if (value != null && value.isNotEmpty) {
      // 여기서 value를 처리합니다.
    }
  });

  // 스트림을 사용하여 앱이 이미 실행 중인 상태에서 공유된 데이터 받기
  StreamSubscription? _intentDataStreamSubscription =
      ReceiveSharingIntent.getTextStream().listen((String? value) {
    if (value != null) {
      // 여기서 value를 처리합니다.
    }
  });
}

플랫폼별 설정:

Android: AndroidManifest.xml에 인텐트 필터를 추가합니다.
iOS: Info.plist에 URL 스킴 및 공유 확장 설정을 추가합니다.
이 방법을 사용하면, 웹 브라우저나 다른 앱에서 "공유하기" 옵션을 통해 Flutter 앱으로 텍스트나 파일을 전송할 수 있습니다.

 

조금더 간단하게 구현할 수 있는거 같습니다.

진행 도중에 빌드 에러가 발생한 부분도 있어 공유 드립니다.

 

프로젝트의 android/build.gradle 파일에서 ext.kotlin_version 값을 1.5.20 또는 그 이상의 최신 버전으로 설정합니다.
receive_sharing_intent 플러그인의 android/build.gradle 파일을 찾아 동일한 버전으로 kotlin-gradle-plugin의 버전을 업데이트합니다.

 

저는 아래와 같이 설정하여 해결했습니다.

ext.kotlin_version = '1.7.10'

 

그리고 추후에 get put 하면 변경될 수 있기에 별도의 디렉토리에 카피해서 사용했습니다.

lib 와 동일 레벨에 pub 을 만들고 그 밑에 복사 후에 아래와 같이

pubspec.yaml 에 추가하였습니다.

receive_sharing_intent:
  path: pub/receive_sharing_intent-1.4.5

 

Comments