diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml
index 1d4c0a0..6533663 100644
--- a/android/app/src/debug/AndroidManifest.xml
+++ b/android/app/src/debug/AndroidManifest.xml
@@ -13,10 +13,5 @@
-
-
-
-
-
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index b66acbf..4491749 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -35,11 +35,6 @@
-
-
-
-
-
@@ -54,10 +49,5 @@
-
-
-
-
-
diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml
index 1d4c0a0..6533663 100644
--- a/android/app/src/profile/AndroidManifest.xml
+++ b/android/app/src/profile/AndroidManifest.xml
@@ -13,10 +13,5 @@
-
-
-
-
-
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index dcf0c72..573e609 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -18,18 +18,6 @@
$(FLUTTER_BUILD_NAME)
CFBundleSignature
????
- CFBundleURLTypes
-
-
- CFBundleTypeRole
- Editor
- CFBundleURLSchemes
-
- ShareMedia
-
-
-
-
CFBundleVersion
$(FLUTTER_BUILD_NUMBER)
LSApplicationQueriesSchemes
diff --git a/ios/ShareExtension/Base.lproj/MainInterface.storyboard b/ios/ShareExtension/Base.lproj/MainInterface.storyboard
deleted file mode 100644
index 286a508..0000000
--- a/ios/ShareExtension/Base.lproj/MainInterface.storyboard
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ios/ShareExtension/Info.plist b/ios/ShareExtension/Info.plist
deleted file mode 100644
index 00576e2..0000000
--- a/ios/ShareExtension/Info.plist
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
- NSExtension
-
- NSExtensionAttributes
-
- NSExtensionActivationRule
-
- NSExtensionActivationSupportsFileWithMaxCount
- 1
-
-
- NSExtensionMainStoryboard
- MainInterface
- NSExtensionPointIdentifier
- com.apple.share-services
-
-
-
diff --git a/ios/ShareExtension/ShareExtension.entitlements b/ios/ShareExtension/ShareExtension.entitlements
deleted file mode 100644
index 1db6944..0000000
--- a/ios/ShareExtension/ShareExtension.entitlements
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
- com.apple.security.application-groups
-
- group.de.seemoo.ios.openhaystack
-
-
-
diff --git a/ios/ShareExtension/ShareViewController.swift b/ios/ShareExtension/ShareViewController.swift
deleted file mode 100644
index 4535c28..0000000
--- a/ios/ShareExtension/ShareViewController.swift
+++ /dev/null
@@ -1,342 +0,0 @@
-//
-// ShareViewController.swift
-// ShareExtension
-//
-// Created by Max Granzow on 18.01.22.
-//
-
-import UIKit
-import Social
-import MobileCoreServices
-import Photos
-
-// Source: https://pub.dev/packages/receive_sharing_intent
-class ShareViewController: SLComposeServiceViewController {
- let hostAppBundleIdentifier = "de.seemoo.ios.openhaystack"
- let sharedKey = "ShareKey"
- var sharedMedia: [SharedMediaFile] = []
- var sharedText: [String] = []
- let imageContentType = kUTTypeImage as String
- let videoContentType = kUTTypeMovie as String
- let textContentType = kUTTypeText as String
- let urlContentType = kUTTypeURL as String
- let fileURLType = kUTTypeFileURL as String;
-
- override func isContentValid() -> Bool {
- return true
- }
-
- override func viewDidLoad() {
- super.viewDidLoad();
- }
-
- override func viewDidAppear(_ animated: Bool) {
- super.viewDidAppear(animated)
-
- // This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
- if let content = extensionContext!.inputItems[0] as? NSExtensionItem {
- if let contents = content.attachments {
- for (index, attachment) in (contents).enumerated() {
- if attachment.hasItemConformingToTypeIdentifier(imageContentType) {
- handleImages(content: content, attachment: attachment, index: index)
- } else if attachment.hasItemConformingToTypeIdentifier(fileURLType) {
- handleFiles(content: content, attachment: attachment, index: index)
- } else if attachment.hasItemConformingToTypeIdentifier(textContentType) {
- handleText(content: content, attachment: attachment, index: index)
- } else if attachment.hasItemConformingToTypeIdentifier(urlContentType) {
- handleUrl(content: content, attachment: attachment, index: index)
- } else if attachment.hasItemConformingToTypeIdentifier(videoContentType) {
- handleVideos(content: content, attachment: attachment, index: index)
- }
- }
- }
- }
- }
-
- override func didSelectPost() {
- print("didSelectPost");
- }
-
- override func configurationItems() -> [Any]! {
- // To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here.
- return []
- }
-
- private func handleText (content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
- attachment.loadItem(forTypeIdentifier: textContentType, options: nil) { [weak self] data, error in
-
- if error == nil, let item = data as? String, let this = self {
-
- this.sharedText.append(item)
-
- // If this is the last item, save imagesData in userDefaults and redirect to host app
- if index == (content.attachments?.count)! - 1 {
- let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)")
- userDefaults?.set(this.sharedText, forKey: this.sharedKey)
- userDefaults?.synchronize()
- this.redirectToHostApp(type: .text)
- }
-
- } else {
- self?.dismissWithError()
- }
- }
- }
-
- private func handleUrl (content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
- attachment.loadItem(forTypeIdentifier: urlContentType, options: nil) { [weak self] data, error in
-
- if error == nil, let item = data as? URL, let this = self {
-
- this.sharedText.append(item.absoluteString)
-
- // If this is the last item, save imagesData in userDefaults and redirect to host app
- if index == (content.attachments?.count)! - 1 {
- let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)")
- userDefaults?.set(this.sharedText, forKey: this.sharedKey)
- userDefaults?.synchronize()
- this.redirectToHostApp(type: .text)
- }
-
- } else {
- self?.dismissWithError()
- }
- }
- }
-
- private func handleImages (content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
- attachment.loadItem(forTypeIdentifier: imageContentType, options: nil) { [weak self] data, error in
-
- if error == nil, let url = data as? URL, let this = self {
-
- // Always copy
- let fileName = this.getFileName(from: url, type: .image)
- let newPath = FileManager.default
- .containerURL(forSecurityApplicationGroupIdentifier: "group.\(this.hostAppBundleIdentifier)")!
- .appendingPathComponent(fileName)
- let copied = this.copyFile(at: url, to: newPath)
- if(copied) {
- this.sharedMedia.append(SharedMediaFile(path: newPath.absoluteString, thumbnail: nil, duration: nil, type: .image))
- }
-
- // If this is the last item, save imagesData in userDefaults and redirect to host app
- if index == (content.attachments?.count)! - 1 {
- let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)")
- userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey)
- userDefaults?.synchronize()
- this.redirectToHostApp(type: .media)
- }
-
- } else {
- self?.dismissWithError()
- }
- }
- }
-
- private func handleVideos (content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
- attachment.loadItem(forTypeIdentifier: videoContentType, options: nil) { [weak self] data, error in
-
- if error == nil, let url = data as? URL, let this = self {
-
- // Always copy
- let fileName = this.getFileName(from: url, type: .video)
- let newPath = FileManager.default
- .containerURL(forSecurityApplicationGroupIdentifier: "group.\(this.hostAppBundleIdentifier)")!
- .appendingPathComponent(fileName)
- let copied = this.copyFile(at: url, to: newPath)
- if(copied) {
- guard let sharedFile = this.getSharedMediaFile(forVideo: newPath) else {
- return
- }
- this.sharedMedia.append(sharedFile)
- }
-
- // If this is the last item, save imagesData in userDefaults and redirect to host app
- if index == (content.attachments?.count)! - 1 {
- let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)")
- userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey)
- userDefaults?.synchronize()
- this.redirectToHostApp(type: .media)
- }
-
- } else {
- self?.dismissWithError()
- }
- }
- }
-
- private func handleFiles (content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
- attachment.loadItem(forTypeIdentifier: fileURLType, options: nil) { [weak self] data, error in
-
- if error == nil, let url = data as? URL, let this = self {
-
- // Always copy
- let fileName = this.getFileName(from :url, type: .file)
- let newPath = FileManager.default
- .containerURL(forSecurityApplicationGroupIdentifier: "group.\(this.hostAppBundleIdentifier)")!
- .appendingPathComponent(fileName)
- let copied = this.copyFile(at: url, to: newPath)
- if (copied) {
- this.sharedMedia.append(SharedMediaFile(path: newPath.absoluteString, thumbnail: nil, duration: nil, type: .file))
- }
-
- if index == (content.attachments?.count)! - 1 {
- let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)")
- userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey)
- userDefaults?.synchronize()
- this.redirectToHostApp(type: .file)
- }
-
- } else {
- self?.dismissWithError()
- }
- }
- }
-
- private func dismissWithError() {
- print("[ERROR] Error loading data!")
- let alert = UIAlertController(title: "Error", message: "Error loading data", preferredStyle: .alert)
-
- let action = UIAlertAction(title: "Error", style: .cancel) { _ in
- self.dismiss(animated: true, completion: nil)
- }
-
- alert.addAction(action)
- present(alert, animated: true, completion: nil)
- extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
- }
-
- private func redirectToHostApp(type: RedirectType) {
- let url = URL(string: "ShareMedia://dataUrl=\(sharedKey)#\(type)")
- var responder = self as UIResponder?
- let selectorOpenURL = sel_registerName("openURL:")
-
- while (responder != nil) {
- if (responder?.responds(to: selectorOpenURL))! {
- let _ = responder?.perform(selectorOpenURL, with: url)
- }
- responder = responder!.next
- }
- extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
- }
-
- enum RedirectType {
- case media
- case text
- case file
- }
-
- func getExtension(from url: URL, type: SharedMediaType) -> String {
- let parts = url.lastPathComponent.components(separatedBy: ".")
- var ex: String? = nil
- if (parts.count > 1) {
- ex = parts.last
- }
-
- if (ex == nil) {
- switch type {
- case .image:
- ex = "PNG"
- case .video:
- ex = "MP4"
- case .file:
- ex = "TXT"
- }
- }
- return ex ?? "Unknown"
- }
-
- func getFileName(from url: URL, type: SharedMediaType) -> String {
- var name = url.lastPathComponent
-
- if (name.isEmpty) {
- name = UUID().uuidString + "." + getExtension(from: url, type: type)
- }
-
- return name
- }
-
- func copyFile(at srcURL: URL, to dstURL: URL) -> Bool {
- do {
- if FileManager.default.fileExists(atPath: dstURL.path) {
- try FileManager.default.removeItem(at: dstURL)
- }
- try FileManager.default.copyItem(at: srcURL, to: dstURL)
- } catch (let error) {
- print("Cannot copy item at \(srcURL) to \(dstURL): \(error)")
- return false
- }
- return true
- }
-
- private func getSharedMediaFile(forVideo: URL) -> SharedMediaFile? {
- let asset = AVAsset(url: forVideo)
- let duration = (CMTimeGetSeconds(asset.duration) * 1000).rounded()
- let thumbnailPath = getThumbnailPath(for: forVideo)
-
- if FileManager.default.fileExists(atPath: thumbnailPath.path) {
- return SharedMediaFile(path: forVideo.absoluteString, thumbnail: thumbnailPath.absoluteString, duration: duration, type: .video)
- }
-
- var saved = false
- let assetImgGenerate = AVAssetImageGenerator(asset: asset)
- assetImgGenerate.appliesPreferredTrackTransform = true
- // let scale = UIScreen.main.scale
- assetImgGenerate.maximumSize = CGSize(width: 360, height: 360)
- do {
- let img = try assetImgGenerate.copyCGImage(at: CMTimeMakeWithSeconds(600, preferredTimescale: Int32(1.0)), actualTime: nil)
- try UIImage.pngData(UIImage(cgImage: img))()?.write(to: thumbnailPath)
- saved = true
- } catch {
- saved = false
- }
-
- return saved ? SharedMediaFile(path: forVideo.absoluteString, thumbnail: thumbnailPath.absoluteString, duration: duration, type: .video) : nil
-
- }
-
- private func getThumbnailPath(for url: URL) -> URL {
- let fileName = Data(url.lastPathComponent.utf8).base64EncodedString().replacingOccurrences(of: "==", with: "")
- let path = FileManager.default
- .containerURL(forSecurityApplicationGroupIdentifier: "group.\(hostAppBundleIdentifier)")!
- .appendingPathComponent("\(fileName).jpg")
- return path
- }
-
- class SharedMediaFile: Codable {
- var path: String; // can be image, video or url path. It can also be text content
- var thumbnail: String?; // video thumbnail
- var duration: Double?; // video duration in milliseconds
- var type: SharedMediaType;
-
-
- init(path: String, thumbnail: String?, duration: Double?, type: SharedMediaType) {
- self.path = path
- self.thumbnail = thumbnail
- self.duration = duration
- self.type = type
- }
-
- // Debug method to print out SharedMediaFile details in the console
- func toString() {
- print("[SharedMediaFile] \n\tpath: \(self.path)\n\tthumbnail: \(self.thumbnail)\n\tduration: \(self.duration)\n\ttype: \(self.type)")
- }
- }
-
- enum SharedMediaType: Int, Codable {
- case image
- case video
- case file
- }
-
- func toData(data: [SharedMediaFile]) -> Data {
- let encodedData = try? JSONEncoder().encode(data)
- return encodedData!
- }
-}
-
-extension Array {
- subscript (safe index: UInt) -> Element? {
- return Int(index) < count ? self[Int(index)] : nil
- }
-}
diff --git a/lib/main.dart b/lib/main.dart
index 373863e..eb2a6b3 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -3,7 +3,6 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
-import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import 'package:openhaystack_mobile/dashboard/dashboard_desktop.dart';
import 'package:openhaystack_mobile/dashboard/dashboard_mobile.dart';
import 'package:openhaystack_mobile/accessory/accessory_registry.dart';
@@ -53,32 +52,10 @@ class _AppLayoutState extends State {
initState() {
super.initState();
- _intentDataStreamSubscription = ReceiveSharingIntent.getMediaStream()
- .listen(handleFileSharingIntent, onError: print);
- ReceiveSharingIntent.getInitialMedia()
- .then(handleFileSharingIntent);
-
var accessoryRegistry = Provider.of(context, listen: false);
accessoryRegistry.loadAccessories();
}
- Future handleFileSharingIntent(List files) async {
- // Received a sharing intent with a number of files.
- // Import the accessories for each device in sequence.
- // If no files are shared do nothing
- for (var file in files) {
- if (file.type == SharedMediaType.FILE) {
- // On iOS the file:// prefix has to be stripped to access the file path
- String path = Platform.isIOS
- ? Uri.decodeComponent(file.path.replaceFirst('file://', ''))
- : file.path;
- Navigator.push(context, MaterialPageRoute(
- builder: (context) => ItemFileImport(filePath: path),
- ));
- }
- }
- }
-
@override
void dispose() {
_intentDataStreamSubscription?.cancel();
diff --git a/pubspec.lock b/pubspec.lock
index be5ff95..691c999 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -648,14 +648,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.2.1"
- receive_sharing_intent:
- dependency: "direct main"
- description:
- name: receive_sharing_intent
- sha256: "912bebb551bce75a14098891fd750305b30d53eba0d61cc70cd9973be9866e8d"
- url: "https://pub.dev"
- source: hosted
- version: "1.4.5"
share_plus:
dependency: "direct main"
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index e3a8c86..80144c2 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -56,7 +56,6 @@ dependencies:
file_picker: ^5.2.7
# Sharing
- receive_sharing_intent: ^1.4.5
share_plus: ^6.3.1
url_launcher: ^6.0.17
path_provider: ^2.0.8