Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
ShareExtend
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
李增强
ShareExtend
Commits
524fd1f6
Commit
524fd1f6
authored
Nov 02, 2019
by
zhouteng
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev'
parents
67f7ba7f
f5d8bb3e
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
185 additions
and
78 deletions
+185
-78
android/src/main/java/com/zt/shareextend/ShareExtendPlugin.java
...d/src/main/java/com/zt/shareextend/ShareExtendPlugin.java
+35
-26
android/src/main/java/com/zt/shareextend/ShareUtils.java
android/src/main/java/com/zt/shareextend/ShareUtils.java
+13
-3
example/android/app/src/main/AndroidManifest.xml
example/android/app/src/main/AndroidManifest.xml
+2
-0
example/ios/Flutter/flutter_export_environment.sh
example/ios/Flutter/flutter_export_environment.sh
+11
-0
example/ios/Podfile
example/ios/Podfile
+2
-1
example/ios/Runner.xcodeproj/project.pbxproj
example/ios/Runner.xcodeproj/project.pbxproj
+35
-10
example/ios/Runner/Runner-Bridging-Header.h
example/ios/Runner/Runner-Bridging-Header.h
+1
-0
example/lib/main.dart
example/lib/main.dart
+35
-17
example/pubspec.yaml
example/pubspec.yaml
+9
-1
ios/Classes/ShareExtendPlugin.m
ios/Classes/ShareExtendPlugin.m
+19
-11
lib/share_extend.dart
lib/share_extend.dart
+23
-9
No files found.
android/src/main/java/com/zt/shareextend/ShareExtendPlugin.java
View file @
524fd1f6
...
...
@@ -4,13 +4,15 @@ import android.Manifest;
import
android.content.Intent
;
import
android.content.pm.PackageManager
;
import
android.net.Uri
;
import
android.os.Build
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
androidx.core.app.ActivityCompat
;
import
androidx.core.content.ContextCompat
;
import
io.flutter.plugin.common.MethodCall
;
import
io.flutter.plugin.common.MethodChannel
;
import
io.flutter.plugin.common.PluginRegistry
;
...
...
@@ -23,10 +25,10 @@ public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, Plugi
/// the authorities for FileProvider
private
static
final
int
CODE_ASK_PERMISSION
=
100
;
private
static
final
String
CHANNEL
=
"share_extend"
;
private
static
final
String
CHANNEL
=
"
com.zt.shareextend/
share_extend"
;
private
final
Registrar
mRegistrar
;
private
String
tex
t
;
private
List
<
String
>
lis
t
;
private
String
type
;
public
static
void
registerWith
(
Registrar
registrar
)
{
...
...
@@ -48,40 +50,41 @@ public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, Plugi
throw
new
IllegalArgumentException
(
"Map argument expected"
);
}
// Android does not support showing the share sheet at a particular point on screen.
share
((
String
)
call
.
argument
(
"tex
t"
),
(
String
)
call
.
argument
(
"type"
));
share
((
List
)
call
.
argument
(
"lis
t"
),
(
String
)
call
.
argument
(
"type"
));
result
.
success
(
null
);
}
else
{
result
.
notImplemented
();
}
}
private
void
share
(
String
tex
t
,
String
type
)
{
if
(
text
==
null
||
tex
t
.
isEmpty
())
{
throw
new
IllegalArgumentException
(
"Non-empty
tex
t expected"
);
private
void
share
(
List
<
String
>
lis
t
,
String
type
)
{
if
(
list
==
null
||
lis
t
.
isEmpty
())
{
throw
new
IllegalArgumentException
(
"Non-empty
lis
t expected"
);
}
this
.
text
=
tex
t
;
this
.
list
=
lis
t
;
this
.
type
=
type
;
Intent
shareIntent
=
new
Intent
();
shareIntent
.
setAction
(
Intent
.
ACTION_SEND
);
shareIntent
.
addFlags
(
Intent
.
FLAG_GRANT_READ_URI_PERMISSION
);
if
(
"text"
.
equals
(
type
))
{
shareIntent
.
putExtra
(
Intent
.
EXTRA_TEXT
,
text
);
shareIntent
.
setAction
(
Intent
.
ACTION_SEND
);
shareIntent
.
putExtra
(
Intent
.
EXTRA_TEXT
,
list
.
get
(
0
));
shareIntent
.
setType
(
"text/plain"
);
}
else
{
File
f
=
new
File
(
text
);
if
(!
f
.
exists
())
{
throw
new
IllegalArgumentException
(
"file not exists"
);
}
if
(
ShareUtils
.
shouldRequestPermission
(
text
))
{
if
(!
checkPermisson
())
{
if
(
ShareUtils
.
shouldRequestPermission
(
list
))
{
if
(!
checkPermission
())
{
requestPermission
();
return
;
}
}
Uri
uri
=
ShareUtils
.
getUriForFile
(
mRegistrar
.
activity
(),
f
,
type
);
ArrayList
<
Uri
>
uriList
=
new
ArrayList
<>();
for
(
String
path
:
list
)
{
File
f
=
new
File
(
path
);
Uri
uri
=
ShareUtils
.
getUriForFile
(
mRegistrar
.
activity
(),
f
,
type
);
uriList
.
add
(
uri
);
}
if
(
"image"
.
equals
(
type
))
{
shareIntent
.
setType
(
"image/*"
);
...
...
@@ -90,9 +93,18 @@ public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, Plugi
}
else
{
shareIntent
.
setType
(
"application/*"
);
}
shareIntent
.
putExtra
(
Intent
.
EXTRA_STREAM
,
uri
);
if
(
uriList
.
size
()
==
1
)
{
shareIntent
.
setAction
(
Intent
.
ACTION_SEND
);
shareIntent
.
putExtra
(
Intent
.
EXTRA_STREAM
,
uriList
.
get
(
0
));
}
else
{
shareIntent
.
setAction
(
Intent
.
ACTION_SEND_MULTIPLE
);
shareIntent
.
putParcelableArrayListExtra
(
Intent
.
EXTRA_STREAM
,
uriList
);
}
}
startChooserActivity
(
shareIntent
);
}
private
void
startChooserActivity
(
Intent
shareIntent
)
{
Intent
chooserIntent
=
Intent
.
createChooser
(
shareIntent
,
null
/* dialog title optional */
);
if
(
mRegistrar
.
activity
()
!=
null
)
{
mRegistrar
.
activity
().
startActivity
(
chooserIntent
);
...
...
@@ -102,12 +114,9 @@ public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, Plugi
}
}
private
boolean
checkPermisson
()
{
if
(
ContextCompat
.
checkSelfPermission
(
mRegistrar
.
context
(),
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
)
==
PackageManager
.
PERMISSION_GRANTED
)
{
return
true
;
}
return
false
;
private
boolean
checkPermission
()
{
return
ContextCompat
.
checkSelfPermission
(
mRegistrar
.
context
(),
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
)
==
PackageManager
.
PERMISSION_GRANTED
;
}
private
void
requestPermission
()
{
...
...
@@ -117,7 +126,7 @@ public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, Plugi
@Override
public
boolean
onRequestPermissionsResult
(
int
requestCode
,
String
[]
perms
,
int
[]
grantResults
)
{
if
(
requestCode
==
CODE_ASK_PERMISSION
&&
grantResults
.
length
>
0
&&
grantResults
[
0
]
==
PackageManager
.
PERMISSION_GRANTED
)
{
share
(
tex
t
,
type
);
share
(
lis
t
,
type
);
}
return
false
;
}
...
...
android/src/main/java/com/zt/shareextend/ShareUtils.java
View file @
524fd1f6
...
...
@@ -11,13 +11,14 @@ import android.provider.MediaStore;
import
android.text.TextUtils
;
import
java.io.File
;
import
java.util.List
;
import
androidx.core.content.FileProvider
;
public
class
ShareUtils
{
/// get the uri for file
public
static
Uri
getUriForFile
(
Context
context
,
File
file
,
String
type
)
{
static
Uri
getUriForFile
(
Context
context
,
File
file
,
String
type
)
{
String
authorities
=
context
.
getPackageName
()
+
".shareextend.fileprovider"
;
...
...
@@ -51,7 +52,16 @@ public class ShareUtils {
return
uri
;
}
public
static
boolean
shouldRequestPermission
(
String
path
)
{
static
boolean
shouldRequestPermission
(
List
<
String
>
pathList
)
{
for
(
String
path
:
pathList
)
{
if
(
shouldRequestPermission
(
path
))
{
return
true
;
}
}
return
false
;
}
static
boolean
shouldRequestPermission
(
String
path
)
{
return
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
M
&&
isPathInExternalStorage
(
path
);
}
...
...
@@ -121,7 +131,7 @@ public class ShareUtils {
* @param audioFile
* @return content Uri
*/
p
ublic
static
Uri
getAudioContentUri
(
Context
context
,
File
audioFile
)
{
p
rivate
static
Uri
getAudioContentUri
(
Context
context
,
File
audioFile
)
{
String
filePath
=
audioFile
.
getAbsolutePath
();
Cursor
cursor
=
context
.
getContentResolver
().
query
(
MediaStore
.
Audio
.
Media
.
EXTERNAL_CONTENT_URI
,
new
String
[]{
MediaStore
.
Audio
.
Media
.
_ID
},
MediaStore
.
Audio
.
Media
.
DATA
+
"=? "
,
...
...
example/android/app/src/main/AndroidManifest.xml
View file @
524fd1f6
...
...
@@ -7,6 +7,8 @@
-->
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.WRITE_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.CAMERA"
/>
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
...
...
example/ios/Flutter/flutter_export_environment.sh
0 → 100755
View file @
524fd1f6
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export
"FLUTTER_ROOT=/Users/zhouteng/Android/flutter"
export
"FLUTTER_APPLICATION_PATH=/Users/zhouteng/flutter-demos/ShareExtend/example"
export
"FLUTTER_TARGET=/Users/zhouteng/flutter-demos/ShareExtend/example/lib/main.dart"
export
"FLUTTER_BUILD_DIR=build"
export
"SYMROOT=
${
SOURCE_ROOT
}
/../build/ios"
export
"FLUTTER_FRAMEWORK_DIR=/Users/zhouteng/Android/flutter/bin/cache/artifacts/engine/ios"
export
"FLUTTER_BUILD_NAME=1.0.0"
export
"FLUTTER_BUILD_NUMBER=1"
export
"TRACK_WIDGET_CREATION=true"
example/ios/Podfile
View file @
524fd1f6
# Uncomment this line to define a global platform for your project
#
platform :ios, '9.0'
platform
:ios
,
'9.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV
[
'COCOAPODS_DISABLE_STATS'
]
=
'true'
...
...
@@ -27,6 +27,7 @@ def parse_KV_file(file, separator='=')
end
target
'Runner'
do
use_frameworks!
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
system
(
'rm -rf .symlinks'
)
...
...
example/ios/Runner.xcodeproj/project.pbxproj
View file @
524fd1f6
This diff is collapsed.
Click to expand it.
example/ios/Runner/Runner-Bridging-Header.h
0 → 100644
View file @
524fd1f6
#import "GeneratedPluginRegistrant.h"
example/lib/main.dart
View file @
524fd1f6
import
'package:flutter/material.dart'
;
import
'dart:io'
;
import
'package:flutter/material.dart'
;
import
'package:multi_image_picker/multi_image_picker.dart'
;
import
'package:share_extend/share_extend.dart'
;
import
'package:image_picker/image_picker.dart'
;
import
'package:path_provider/path_provider.dart'
;
void
main
(
)
=>
runApp
(
new
MyApp
());
void
main
(
)
=>
runApp
(
MyApp
());
class
MyApp
extends
StatefulWidget
{
@override
_MyAppState
createState
()
=>
new
_MyAppState
();
_MyAppState
createState
()
=>
_MyAppState
();
}
class
_MyAppState
extends
State
<
MyApp
>
{
...
...
@@ -20,22 +22,22 @@ class _MyAppState extends State<MyApp> {
@override
Widget
build
(
BuildContext
context
)
{
return
new
MaterialApp
(
home:
new
Scaffold
(
appBar:
new
AppBar
(
return
MaterialApp
(
home:
Scaffold
(
appBar:
AppBar
(
title:
const
Text
(
'Plugin example app'
),
),
body:
Container
(
child:
new
Center
(
child:
new
Column
(
child:
Center
(
child:
Column
(
children:
<
Widget
>[
new
RaisedButton
(
RaisedButton
(
onPressed:
()
{
ShareExtend
.
share
(
"share text"
,
"text"
);
},
child:
new
Text
(
"share text"
),
child:
Text
(
"share text"
),
),
new
RaisedButton
(
RaisedButton
(
onPressed:
()
async
{
File
f
=
await
ImagePicker
.
pickImage
(
source
:
ImageSource
.
gallery
);
...
...
@@ -43,9 +45,9 @@ class _MyAppState extends State<MyApp> {
ShareExtend
.
share
(
f
.
path
,
"image"
);
}
},
child:
new
Text
(
"share image"
),
child:
Text
(
"share image"
),
),
new
RaisedButton
(
RaisedButton
(
onPressed:
()
async
{
File
f
=
await
ImagePicker
.
pickVideo
(
source
:
ImageSource
.
gallery
);
...
...
@@ -53,13 +55,19 @@ class _MyAppState extends State<MyApp> {
ShareExtend
.
share
(
f
.
path
,
"video"
);
}
},
child:
new
Text
(
"share video"
),
child:
Text
(
"share video"
),
),
new
RaisedButton
(
RaisedButton
(
onPressed:
()
{
_shareApplicationDocumentsFile
();
},
child:
new
Text
(
"share file"
),
child:
Text
(
"share file"
),
),
RaisedButton
(
onPressed:
()
{
_shareMultipleImages
();
},
child:
Text
(
"share multiple images"
),
),
],
),
...
...
@@ -69,10 +77,20 @@ class _MyAppState extends State<MyApp> {
);
}
///share multiple images
_shareMultipleImages
()
async
{
List
<
Asset
>
assetList
=
await
MultiImagePicker
.
pickImages
(
maxImages:
5
);
var
imageList
=
List
<
String
>();
for
(
var
asset
in
assetList
)
{
imageList
.
add
(
await
asset
.
filePath
);
}
ShareExtend
.
shareMultiple
(
imageList
,
"image"
);
}
///share the documents file
_shareApplicationDocumentsFile
()
async
{
Directory
dir
=
await
getApplicationDocumentsDirectory
();
File
testFile
=
new
File
(
"
${dir.path}
/flutter/test.txt"
);
File
testFile
=
File
(
"
${dir.path}
/flutter/test.txt"
);
if
(!
await
testFile
.
exists
())
{
await
testFile
.
create
(
recursive:
true
);
testFile
.
writeAsStringSync
(
"test for share documents file"
);
...
...
example/pubspec.yaml
View file @
524fd1f6
...
...
@@ -19,8 +19,14 @@ dependencies:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons
:
^0.1.2
path_provider
:
^1.4.0
multi_image_picker
:
^4.5.9
# image_picker: ^0.6.1+10
image_picker
:
path_provider
:
git
:
url
:
git@github.com:miguelpruivo/plugins.git
path
:
packages/image_picker
ref
:
image_picker-Fix-#41046
dev_dependencies
:
flutter_test
:
...
...
@@ -29,6 +35,8 @@ dev_dependencies:
share_extend
:
path
:
../
# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec
...
...
ios/Classes/ShareExtendPlugin.m
View file @
524fd1f6
...
...
@@ -4,18 +4,18 @@
+
(
void
)
registerWithRegistrar
:(
NSObject
<
FlutterPluginRegistrar
>*
)
registrar
{
FlutterMethodChannel
*
shareChannel
=
[
FlutterMethodChannel
methodChannelWithName:
@"share_extend"
methodChannelWithName:
@"
com.zt.shareextend/
share_extend"
binaryMessenger:
[
registrar
messenger
]];
[
shareChannel
setMethodCallHandler
:
^
(
FlutterMethodCall
*
call
,
FlutterResult
result
)
{
if
([
@"share"
isEqualToString
:
call
.
method
])
{
NSDictionary
*
arguments
=
[
call
arguments
];
NS
String
*
shareText
=
arguments
[
@"tex
t"
];
NS
Array
*
array
=
arguments
[
@"lis
t"
];
NSString
*
shareType
=
arguments
[
@"type"
];
if
(
shareText
.
length
==
0
)
{
if
(
array
.
count
==
0
)
{
result
(
[
FlutterError
errorWithCode
:
@"error"
message
:
@"Non-empty
tex
t expected"
details
:
nil
]);
[
FlutterError
errorWithCode
:
@"error"
message
:
@"Non-empty
lis
t expected"
details
:
nil
]);
return
;
}
...
...
@@ -31,14 +31,22 @@
}
if
([
shareType
isEqualToString
:
@"text"
])
{
[
self
share
:
shareText
atSource
:
originRect
];
[
self
share
:
array
atSource
:
originRect
];
result
(
nil
);
}
else
if
([
shareType
isEqualToString
:
@"image"
])
{
UIImage
*
image
=
[
UIImage
imageWithContentsOfFile
:
shareText
];
[
self
share
:
image
atSource
:
originRect
];
NSMutableArray
*
imageArray
=
[[
NSMutableArray
alloc
]
init
];
for
(
NSString
*
path
in
array
)
{
UIImage
*
image
=
[
UIImage
imageWithContentsOfFile
:
path
];
[
imageArray
addObject
:
image
];
}
[
self
share
:
imageArray
atSource
:
originRect
];
}
else
{
NSURL
*
url
=
[
NSURL
fileURLWithPath
:
shareText
];
[
self
share
:
url
atSource
:
originRect
];
NSMutableArray
*
urlArray
=
[[
NSMutableArray
alloc
]
init
];
for
(
NSString
*
path
in
array
)
{
NSURL
*
url
=
[
NSURL
fileURLWithPath
:
path
];
[
urlArray
addObject
:
url
];
}
[
self
share
:
urlArray
atSource
:
originRect
];
result
(
nil
);
}
}
else
{
...
...
@@ -47,8 +55,8 @@
}];
}
+
(
void
)
share
:(
id
)
sharedItems
atSource
:(
CGRect
)
origin
{
UIActivityViewController
*
activityViewController
=
[[
UIActivityViewController
alloc
]
initWithActivityItems
:
@[
sharedItems
]
applicationActivities
:
nil
];
+
(
void
)
share
:(
NSArray
*
)
sharedItems
atSource
:(
CGRect
)
origin
{
UIActivityViewController
*
activityViewController
=
[[
UIActivityViewController
alloc
]
initWithActivityItems
:
sharedItems
applicationActivities
:
nil
];
UIViewController
*
controller
=
[
UIApplication
sharedApplication
].
keyWindow
.
rootViewController
;
...
...
lib/share_extend.dart
View file @
524fd1f6
/// A flutter plugin to share text, image, file with system ui.
/// It is compatible with both and
or
id and ios.
/// It is compatible with both and
ro
id and ios.
///
///
/// A open source authorized by zhouteng [https://github.com/zhouteng0217/ShareExtend](https://github.com/zhouteng0217/ShareExtend).
...
...
@@ -11,29 +11,43 @@ import 'dart:ui';
/// Plugin for summoning a platform share sheet.
class
ShareExtend
{
/// [MethodChannel] used to communicate with the platform side.
static
const
MethodChannel
_channel
=
const
MethodChannel
(
'share_extend'
);
static
const
MethodChannel
_channel
=
const
MethodChannel
(
'com.zt.shareextend/share_extend'
);
static
Future
<
void
>
shareMultiple
(
List
<
String
>
list
,
String
type
,
{
Rect
sharePositionOrigin
})
{
assert
(
list
!=
null
&&
list
.
isNotEmpty
);
return
_shareInner
(
list
,
type
,
sharePositionOrigin:
sharePositionOrigin
);
}
static
Future
<
void
>
share
(
String
text
,
String
type
,
{
Rect
sharePositionOrigin
})
{
assert
(
text
!=
null
);
assert
(
text
.
isNotEmpty
);
List
<
String
>
list
=
[
text
];
return
_shareInner
(
list
,
type
,
sharePositionOrigin:
sharePositionOrigin
);
}
/// method to share with system ui
/// It uses the ACTION_SEND Intent on Android and UIActivityViewController
/// on iOS.
/// type "text", "image" ,"file"
/// [list] can be text or path list
/// [type] "text", "image" ,"file"
/// [sharePositionOrigin] only supports ios
///
static
Future
<
void
>
share
(
String
tex
t
,
String
type
,
static
Future
<
void
>
_shareInner
(
List
<
String
>
lis
t
,
String
type
,
{
Rect
sharePositionOrigin
})
{
assert
(
text
!=
null
);
assert
(
text
.
isNotEmpty
);
assert
(
list
!=
null
&&
list
.
isNotEmpty
);
final
Map
<
String
,
dynamic
>
params
=
<
String
,
dynamic
>{
'
text'
:
tex
t
,
'
list'
:
lis
t
,
'type'
:
type
};
if
(
sharePositionOrigin
!=
null
)
{
params
[
'originX'
]
=
sharePositionOrigin
.
left
;
params
[
'originY'
]
=
sharePositionOrigin
.
top
;
params
[
'originWidth'
]
=
sharePositionOrigin
.
width
;
params
[
'originHeight'
]
=
sharePositionOrigin
.
height
;
}
return
_channel
.
invokeMethod
(
'share'
,
params
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment