Skip to content

Commit

Permalink
Fix sharing image does not work sometimes on iOS and on Android when …
Browse files Browse the repository at this point in the history
…sharing from google photos (cloud)
  • Loading branch information
kasemmohamed committed Jun 25, 2019
1 parent fae21c4 commit 056627f
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 23 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.1.3

* Fix sharing image does not work sometimes on iOS and on Android when sharing from google photos (cloud)

## 1.1.2

* Return absolute path for images instead of a reference that can be used directly with File.dart
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import android.os.Build
import android.os.Environment
import android.provider.DocumentsContract
import android.provider.MediaStore
import java.io.File
import java.io.FileOutputStream
import java.util.*


object FileDirectory {
Expand Down Expand Up @@ -57,19 +60,18 @@ object FileDirectory {
"audio" -> contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
}

if(contentUri==null) return null

val selection = "_id=?"
val selectionArgs = arrayOf(split[1])
return getDataColumn(context, contentUri, selection, selectionArgs)
}// MediaProvider
// DownloadsProvider
} else if ("content".equals(uri.scheme!!, ignoreCase = true)) {
} else if ("content".equals(uri.scheme, ignoreCase = true)) {
return getDataColumn(context, uri, null, null)
} else if ("file".equals(uri.scheme!!, ignoreCase = true)) {
return uri.path
}// File
// MediaStore (and general)
}

return null
return uri.path
}

/**
Expand All @@ -82,15 +84,25 @@ object FileDirectory {
* @param selectionArgs (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
private fun getDataColumn(context: Context, uri: Uri?, selection: String?,
private fun getDataColumn(context: Context, uri: Uri, selection: String?,
selectionArgs: Array<String>?): String? {

if (uri.authority != null) {
val targetFile = File(context.cacheDir, "IMG_${Date().time}.png")
context.contentResolver.openInputStream(uri)?.use { input ->
FileOutputStream(targetFile).use { fileOut ->
input.copyTo(fileOut)
}
}
return targetFile.path
}

var cursor: Cursor? = null
val column = "_data"
val projection = arrayOf(column)

try {
cursor = context.contentResolver.query(uri!!, projection, selection, selectionArgs, null)
cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null)
if (cursor != null && cursor.moveToFirst()) {
val column_index = cursor.getColumnIndexOrThrow(column)
return cursor.getString(column_index)
Expand Down
30 changes: 25 additions & 5 deletions example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ import MobileCoreServices
import Photos

class ShareViewController: SLComposeServiceViewController {

// TODO: IMPROTANT: This should be your host app bundle identiefier
let hostAppBundleIdentifier = "com.kasem.sharing"
let sharedKey = "ShareKey"
var sharedData: [String] = []
let imageContentType = kUTTypeImage as String
Expand Down Expand Up @@ -186,7 +187,7 @@ class ShareViewController: SLComposeServiceViewController {

if error == nil, let item = data as? String, let this = self {

this.sharedData.append( item)
this.sharedData.append(item)

// If this is the last item, save imagesData in userDefaults and redirect to host app
if index == (content.attachments?.count)! - 1 {
Expand Down Expand Up @@ -214,9 +215,7 @@ class ShareViewController: SLComposeServiceViewController {

// If this is the last item, save imagesData in userDefaults and redirect to host app
if index == (content.attachments?.count)! - 1 {
// TODO: IMPROTANT: This should be your host app bundle identiefier
let hostAppBundleIdentiefier = "com.kasem.sharing"
let userDefaults = UserDefaults(suiteName: "group.\(hostAppBundleIdentiefier)")
let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)")
userDefaults?.set(this.sharedData, forKey: this.sharedKey)
userDefaults?.synchronize()
this.redirectToHostApp(type: .text)
Expand All @@ -243,6 +242,14 @@ class ShareViewController: SLComposeServiceViewController {
let fileName = component.components(separatedBy: ".").first!
if let asset = this.imageAssetDictionary[fileName] {
this.sharedData.append( asset.localIdentifier)
} else {
// If we could not find the file then copy it
let newPath = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.\(this.hostAppBundleIdentifier)")!.appendingPathComponent(fileName)
let copied = this.copyFile(at: url, to: newPath)
if(copied) {
this.sharedData.append(newPath.absoluteString)
}
}
break
}
Expand Down Expand Up @@ -314,6 +321,19 @@ class ShareViewController: SLComposeServiceViewController {

return assetDictionary
}()

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
}
}
```

Expand Down
32 changes: 25 additions & 7 deletions example/ios/Sharing Extension/ShareViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import MobileCoreServices
import Photos

class ShareViewController: SLComposeServiceViewController {

// TODO: IMPROTANT: This should be your host app bundle identiefier
let hostAppBundleIdentifier = "com.kasem.sharing"
let sharedKey = "ShareKey"
var sharedData: [String] = []
let imageContentType = kUTTypeImage as String
Expand Down Expand Up @@ -60,9 +61,7 @@ class ShareViewController: SLComposeServiceViewController {

// If this is the last item, save imagesData in userDefaults and redirect to host app
if index == (content.attachments?.count)! - 1 {
// TODO: IMPROTANT: This should be your host app bundle identiefier
let hostAppBundleIdentiefier = "com.kasem.sharing"
let userDefaults = UserDefaults(suiteName: "group.\(hostAppBundleIdentiefier)")
let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)")
userDefaults?.set(this.sharedData, forKey: this.sharedKey)
userDefaults?.synchronize()
this.redirectToHostApp(type: .text)
Expand All @@ -84,9 +83,7 @@ class ShareViewController: SLComposeServiceViewController {

// If this is the last item, save imagesData in userDefaults and redirect to host app
if index == (content.attachments?.count)! - 1 {
// TODO: IMPROTANT: This should be your host app bundle identiefier
let hostAppBundleIdentiefier = "com.kasem.sharing"
let userDefaults = UserDefaults(suiteName: "group.\(hostAppBundleIdentiefier)")
let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)")
userDefaults?.set(this.sharedData, forKey: this.sharedKey)
userDefaults?.synchronize()
this.redirectToHostApp(type: .text)
Expand All @@ -113,6 +110,14 @@ class ShareViewController: SLComposeServiceViewController {
let fileName = component.components(separatedBy: ".").first!
if let asset = this.imageAssetDictionary[fileName] {
this.sharedData.append( asset.localIdentifier)
} else {
// If we could not find the file then copy it
let newPath = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.\(this.hostAppBundleIdentifier)")!.appendingPathComponent(fileName)
let copied = this.copyFile(at: url, to: newPath)
if(copied) {
this.sharedData.append(newPath.absoluteString)
}
}
break
}
Expand Down Expand Up @@ -184,4 +189,17 @@ class ShareViewController: SLComposeServiceViewController {

return assetDictionary
}()

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
}
}
4 changes: 2 additions & 2 deletions lib/receive_sharing_intent.dart
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,11 @@ class ReceiveSharingIntent {
/// If the value is not valid as a URI or URI reference,
/// a [FormatException] is thrown.
///
/// Refer to `getLinkStream` about error/exception details.
/// Refer to `getTextStream` about error/exception details.
///
/// If the app was started by a share intent or user activity the stream will
/// not emit that initial uri - query either the `getInitialTextAsUri` instead.
static Stream<Uri> getLinkStreamAsUri() {
static Stream<Uri> getTextStreamAsUri() {
return getTextStream().transform<Uri>(
new StreamTransformer<String, Uri>.fromHandlers(
handleData: (String data, EventSink<Uri> sink) {
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: receive_sharing_intent
description: A flutter plugin that enables flutter apps to receive sharing photos, text or url from other apps.
version: 1.1.2
version: 1.1.3
author: Kasem SAEED<[email protected]>
homepage: https://github.com/KasemJaffer/receive_sharing_intent

Expand Down

0 comments on commit 056627f

Please sign in to comment.