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
1c5d0220
Commit
1c5d0220
authored
Jun 27, 2020
by
zhouteng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update project to support android embedding v2 api
parent
b24c80ad
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
259 additions
and
125 deletions
+259
-125
android/src/main/java/com/zt/shareextend/MethodCallHandlerImpl.java
...c/main/java/com/zt/shareextend/MethodCallHandlerImpl.java
+36
-0
android/src/main/java/com/zt/shareextend/Share.java
android/src/main/java/com/zt/shareextend/Share.java
+122
-0
android/src/main/java/com/zt/shareextend/ShareExtendPlugin.java
...d/src/main/java/com/zt/shareextend/ShareExtendPlugin.java
+48
-102
example/android/app/src/main/AndroidManifest.xml
example/android/app/src/main/AndroidManifest.xml
+22
-7
example/android/app/src/main/java/com/zt/shareextendexample/EmbeddingV1Activity.java
...n/java/com/zt/shareextendexample/EmbeddingV1Activity.java
+25
-0
example/android/app/src/main/java/com/zt/shareextendexample/MainActivity.java
...src/main/java/com/zt/shareextendexample/MainActivity.java
+0
-13
pubspec.yaml
pubspec.yaml
+6
-3
No files found.
android/src/main/java/com/zt/shareextend/MethodCallHandlerImpl.java
0 → 100644
View file @
1c5d0220
package
com.zt.shareextend
;
import
androidx.annotation.NonNull
;
import
java.util.Map
;
import
io.flutter.plugin.common.MethodCall
;
import
io.flutter.plugin.common.MethodChannel
;
/**
* Created by zhouteng on 2020/6/27
*/
public
class
MethodCallHandlerImpl
implements
MethodChannel
.
MethodCallHandler
{
private
static
final
String
METHOD_SHARE
=
"share"
;
private
Share
share
;
public
MethodCallHandlerImpl
(
Share
share
)
{
this
.
share
=
share
;
}
@Override
public
void
onMethodCall
(
@NonNull
MethodCall
call
,
@NonNull
MethodChannel
.
Result
result
)
{
if
(
METHOD_SHARE
.
equals
(
call
.
method
))
{
if
(!(
call
.
arguments
instanceof
Map
))
{
throw
new
IllegalArgumentException
(
"Map argument expected"
);
}
share
.
share
(
call
);
result
.
success
(
null
);
}
else
{
result
.
notImplemented
();
}
}
}
android/src/main/java/com/zt/shareextend/Share.java
0 → 100644
View file @
1c5d0220
package
com.zt.shareextend
;
import
android.Manifest
;
import
android.app.Activity
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.pm.PackageManager
;
import
android.net.Uri
;
import
androidx.core.app.ActivityCompat
;
import
androidx.core.content.ContextCompat
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.List
;
import
io.flutter.plugin.common.MethodCall
;
/**
* Created by zhouteng on 2020/6/27
* <p>
* Handles share action
*/
public
class
Share
{
private
static
final
int
CODE_ASK_PERMISSION
=
100
;
private
Context
context
;
private
MethodCall
call
;
public
Share
(
Context
context
)
{
this
.
context
=
context
;
}
void
share
()
{
share
(
call
);
}
void
share
(
MethodCall
call
)
{
if
(
call
==
null
)
{
return
;
}
this
.
call
=
call
;
List
<
String
>
list
=
call
.
argument
(
"list"
);
String
type
=
call
.
argument
(
"type"
);
String
sharePanelTitle
=
call
.
argument
(
"sharePanelTitle"
);
String
subject
=
call
.
argument
(
"subject"
);
String
extraText
=
call
.
argument
(
"extraText"
);
if
(
list
==
null
||
list
.
isEmpty
())
{
throw
new
IllegalArgumentException
(
"Non-empty list expected"
);
}
ArrayList
<
Uri
>
uriList
=
new
ArrayList
<>();
Intent
shareIntent
=
new
Intent
();
shareIntent
.
addFlags
(
Intent
.
FLAG_GRANT_READ_URI_PERMISSION
);
shareIntent
.
putExtra
(
Intent
.
EXTRA_SUBJECT
,
subject
);
if
(
"text"
.
equals
(
type
))
{
shareIntent
.
setAction
(
Intent
.
ACTION_SEND
);
shareIntent
.
putExtra
(
Intent
.
EXTRA_TEXT
,
list
.
get
(
0
));
shareIntent
.
setType
(
"text/plain"
);
}
else
{
if
(
ShareUtils
.
shouldRequestPermission
(
list
))
{
if
(!
checkPermission
())
{
requestPermission
();
return
;
}
}
shareIntent
.
putExtra
(
Intent
.
EXTRA_TEXT
,
extraText
);
for
(
String
path
:
list
)
{
File
f
=
new
File
(
path
);
Uri
uri
=
ShareUtils
.
getUriForFile
(
context
,
f
);
uriList
.
add
(
uri
);
}
if
(
"image"
.
equals
(
type
))
{
shareIntent
.
setType
(
"image/*"
);
}
else
if
(
"video"
.
equals
(
type
))
{
shareIntent
.
setType
(
"video/*"
);
}
else
{
shareIntent
.
setType
(
"application/*"
);
}
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
,
sharePanelTitle
,
uriList
);
}
private
void
startChooserActivity
(
Intent
shareIntent
,
String
sharePanelTitle
,
ArrayList
<
Uri
>
uriList
)
{
Intent
chooserIntent
=
Intent
.
createChooser
(
shareIntent
,
sharePanelTitle
);
ShareUtils
.
grantUriPermission
(
context
,
uriList
,
chooserIntent
);
if
(
context
instanceof
Activity
)
{
context
.
startActivity
(
chooserIntent
);
}
else
{
chooserIntent
.
addFlags
(
Intent
.
FLAG_ACTIVITY_NEW_TASK
);
context
.
startActivity
(
chooserIntent
);
}
}
private
boolean
checkPermission
()
{
return
ContextCompat
.
checkSelfPermission
(
context
,
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
)
==
PackageManager
.
PERMISSION_GRANTED
;
}
private
void
requestPermission
()
{
if
(!(
context
instanceof
Activity
))
{
return
;
}
ActivityCompat
.
requestPermissions
((
Activity
)
context
,
new
String
[]{
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
},
CODE_ASK_PERMISSION
);
}
}
android/src/main/java/com/zt/shareextend/ShareExtendPlugin.java
View file @
1c5d0220
package
com.zt.shareextend
;
import
android.Manifest
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.pm.PackageManager
;
import
android.content.pm.ResolveInfo
;
import
android.net.Uri
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
androidx.annotation.NonNull
;
import
androidx.core.app.ActivityCompat
;
import
androidx.core.content.ContextCompat
;
import
io.flutter.plugin.common.
MethodCall
;
import
io.flutter.embedding.engine.plugins.FlutterPlugin
;
import
io.flutter.embedding.engine.plugins.activity.ActivityAware
;
import
io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
;
import
io.flutter.plugin.common.
BinaryMessenger
;
import
io.flutter.plugin.common.MethodChannel
;
import
io.flutter.plugin.common.PluginRegistry
;
import
io.flutter.plugin.common.PluginRegistry.Registrar
;
...
...
@@ -23,125 +16,78 @@ import io.flutter.plugin.common.PluginRegistry.Registrar;
/**
* Plugin method host for presenting a share sheet via Intent
*/
public
class
ShareExtendPlugin
implements
MethodChannel
.
MethodCallHandler
,
PluginRegistry
.
RequestPermissionsResultListener
{
public
class
ShareExtendPlugin
implements
FlutterPlugin
,
ActivityAware
,
PluginRegistry
.
RequestPermissionsResultListener
{
/// the authorities for FileProvider
private
static
final
int
CODE_ASK_PERMISSION
=
100
;
private
static
final
String
CHANNEL
=
"com.zt.shareextend/share_extend"
;
private
final
Registrar
mRegistrar
;
private
List
<
String
>
list
;
private
String
type
;
private
String
sharePanelTitle
;
private
String
subject
;
private
S
tring
extraText
;
private
FlutterPluginBinding
pluginBinding
;
private
ActivityPluginBinding
activityBinding
;
private
MethodChannel
methodChannel
;
private
MethodCallHandlerImpl
callHandler
;
private
S
hare
share
;
public
static
void
registerWith
(
Registrar
registrar
)
{
MethodChannel
channel
=
new
MethodChannel
(
registrar
.
messenger
(),
CHANNEL
);
final
ShareExtendPlugin
instance
=
new
ShareExtendPlugin
(
registrar
);
registrar
.
addRequestPermissionsResultListener
(
instance
);
channel
.
setMethodCallHandler
(
instance
);
ShareExtendPlugin
plugin
=
new
ShareExtendPlugin
();
plugin
.
setUpChannel
(
registrar
.
context
(),
registrar
.
messenger
(),
registrar
,
null
);
}
p
rivate
ShareExtendPlugin
(
Registrar
registrar
)
{
this
.
mRegistrar
=
registrar
;
@Override
p
ublic
void
onAttachedToEngine
(
@NonNull
FlutterPluginBinding
flutterPluginBinding
)
{
pluginBinding
=
flutterPluginBinding
;
}
@Override
public
void
onMethodCall
(
MethodCall
call
,
MethodChannel
.
Result
result
)
{
if
(
call
.
method
.
equals
(
"share"
))
{
if
(!(
call
.
arguments
instanceof
Map
))
{
throw
new
IllegalArgumentException
(
"Map argument expected"
);
}
// Android does not support showing the share sheet at a particular point on screen.
list
=
call
.
argument
(
"list"
);
type
=
call
.
argument
(
"type"
);
sharePanelTitle
=
call
.
argument
(
"sharePanelTitle"
);
subject
=
call
.
argument
(
"subject"
);
extraText
=
call
.
argument
(
"extraText"
);
share
(
list
,
type
,
sharePanelTitle
,
subject
,
extraText
);
result
.
success
(
null
);
}
else
{
result
.
notImplemented
();
public
void
onDetachedFromEngine
(
@NonNull
FlutterPluginBinding
flutterPluginBinding
)
{
pluginBinding
=
null
;
}
}
private
void
share
(
List
<
String
>
list
,
String
type
,
String
sharePanelTitle
,
String
subject
,
String
extraText
)
{
ArrayList
<
Uri
>
uriList
=
new
ArrayList
<>();;
if
(
list
==
null
||
list
.
isEmpty
())
{
throw
new
IllegalArgumentException
(
"Non-empty list expected"
);
}
Intent
shareIntent
=
new
Intent
();
shareIntent
.
addFlags
(
Intent
.
FLAG_GRANT_READ_URI_PERMISSION
);
shareIntent
.
putExtra
(
Intent
.
EXTRA_SUBJECT
,
subject
);
if
(
"text"
.
equals
(
type
))
{
shareIntent
.
setAction
(
Intent
.
ACTION_SEND
);
shareIntent
.
putExtra
(
Intent
.
EXTRA_TEXT
,
list
.
get
(
0
));
shareIntent
.
setType
(
"text/plain"
);
}
else
{
if
(
ShareUtils
.
shouldRequestPermission
(
list
))
{
if
(!
checkPermission
())
{
requestPermission
();
return
;
}
}
shareIntent
.
putExtra
(
Intent
.
EXTRA_TEXT
,
extraText
);
for
(
String
path
:
list
)
{
File
f
=
new
File
(
path
);
Uri
uri
=
ShareUtils
.
getUriForFile
(
getContext
(),
f
);
uriList
.
add
(
uri
);
@Override
public
void
onAttachedToActivity
(
@NonNull
ActivityPluginBinding
activityPluginBinding
)
{
activityBinding
=
activityPluginBinding
;
setUpChannel
(
activityBinding
.
getActivity
(),
pluginBinding
.
getBinaryMessenger
(),
null
,
activityBinding
);
}
if
(
"image"
.
equals
(
type
))
{
shareIntent
.
setType
(
"image/*"
);
}
else
if
(
"video"
.
equals
(
type
))
{
shareIntent
.
setType
(
"video/*"
);
}
else
{
shareIntent
.
setType
(
"application/*"
);
}
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
,
sharePanelTitle
,
uriList
);
@Override
public
void
onDetachedFromActivityForConfigChanges
()
{
onDetachedFromActivity
();
}
private
Context
getContext
()
{
return
mRegistrar
.
activity
()
!=
null
?
mRegistrar
.
activity
()
:
mRegistrar
.
context
();
@Override
public
void
onReattachedToActivityForConfigChanges
(
@NonNull
ActivityPluginBinding
activityPluginBinding
)
{
onAttachedToActivity
(
activityPluginBinding
);
}
private
void
startChooserActivity
(
Intent
shareIntent
,
String
sharePanelTitle
,
ArrayList
<
Uri
>
uriList
)
{
Intent
chooserIntent
=
Intent
.
createChooser
(
shareIntent
,
sharePanelTitle
);
ShareUtils
.
grantUriPermission
(
getContext
(),
uriList
,
chooserIntent
);
@Override
public
void
onDetachedFromActivity
()
{
tearDown
();
}
if
(
mRegistrar
.
activity
()
!=
null
)
{
mRegistrar
.
activity
().
startActivity
(
chooserIntent
);
private
void
setUpChannel
(
Context
context
,
BinaryMessenger
messenger
,
Registrar
registrar
,
ActivityPluginBinding
activityBinding
)
{
methodChannel
=
new
MethodChannel
(
messenger
,
CHANNEL
);
share
=
new
Share
(
context
);
callHandler
=
new
MethodCallHandlerImpl
(
share
);
methodChannel
.
setMethodCallHandler
(
callHandler
);
if
(
registrar
!=
null
)
{
registrar
.
addRequestPermissionsResultListener
(
this
);
}
else
{
chooserIntent
.
addFlags
(
Intent
.
FLAG_ACTIVITY_NEW_TASK
);
mRegistrar
.
context
().
startActivity
(
chooserIntent
);
}
activityBinding
.
addRequestPermissionsResultListener
(
this
);
}
private
boolean
checkPermission
()
{
return
ContextCompat
.
checkSelfPermission
(
mRegistrar
.
context
(),
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
)
==
PackageManager
.
PERMISSION_GRANTED
;
}
private
void
requestPermission
()
{
ActivityCompat
.
requestPermissions
(
mRegistrar
.
activity
(),
new
String
[]{
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
},
CODE_ASK_PERMISSION
);
private
void
tearDown
()
{
activityBinding
.
removeRequestPermissionsResultListener
(
this
);
activityBinding
=
null
;
methodChannel
.
setMethodCallHandler
(
null
);
methodChannel
=
null
;
}
@Override
public
boolean
onRequestPermissionsResult
(
int
requestCode
,
String
[]
perms
,
int
[]
grantResults
)
{
if
(
requestCode
==
CODE_ASK_PERMISSION
&&
grantResults
.
length
>
0
&&
grantResults
[
0
]
==
PackageManager
.
PERMISSION_GRANTED
)
{
share
(
list
,
type
,
sharePanelTitle
,
subject
,
extraText
);
share
.
share
(
);
}
return
false
;
}
...
...
example/android/app/src/main/AndroidManifest.xml
View file @
1c5d0220
...
...
@@ -20,25 +20,40 @@
android:name=
"io.flutter.app.FlutterApplication"
android:label=
"share_extend_example"
android:icon=
"@mipmap/ic_launcher"
>
<activity
android:name=
"
.Main
Activity"
android:name=
"
io.flutter.embedding.android.Flutter
Activity"
android:launchMode=
"singleTop"
android:theme=
"@style/LaunchTheme"
android:configChanges=
"orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated=
"true"
android:windowSoftInputMode=
"adjustResize"
>
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). -->
<meta-data
android:name=
"io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value=
"true"
/>
android:name=
"io.flutter.embedding.android.SplashScreenDrawable"
android:resource=
"@drawable/launch_background"
/>
<intent-filter>
<action
android:name=
"android.intent.action.MAIN"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
<!-- used for v1 api -->
<activity
android:name=
".EmbeddingV1Activity"
android:theme=
"@android:style/Theme.Black.NoTitleBar"
android:configChanges=
"orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
android:hardwareAccelerated=
"true"
android:windowSoftInputMode=
"adjustResize"
>
<meta-data
android:name=
"io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value=
"true"
/>
</activity>
<meta-data
android:name=
"flutterEmbedding"
android:value=
"2"
/>
</application>
</manifest>
example/android/app/src/main/java/com/zt/shareextendexample/EmbeddingV1Activity.java
0 → 100644
View file @
1c5d0220
package
com.zt.shareextendexample
;
import
android.os.Bundle
;
import
com.vitanov.multiimagepicker.MultiImagePickerPlugin
;
import
com.zt.shareextend.ShareExtendPlugin
;
import
io.flutter.app.FlutterActivity
;
import
io.flutter.embedding.engine.plugins.FlutterPlugin
;
import
io.flutter.plugins.GeneratedPluginRegistrant
;
import
io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin
;
import
io.flutter.plugins.imagepicker.ImagePickerPlugin
;
import
io.flutter.plugins.pathprovider.PathProviderPlugin
;
public
class
EmbeddingV1Activity
extends
FlutterActivity
{
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
ShareExtendPlugin
.
registerWith
(
registrarFor
(
"com.zt.shareextend.ShareExtendPlugin"
));
ImagePickerPlugin
.
registerWith
(
registrarFor
(
"io.flutter.plugins.imagepicker.ImagePickerPlugin"
));
MultiImagePickerPlugin
.
registerWith
(
registrarFor
(
"com.vitanov.multiimagepicker.MultiImagePickerPlugin"
));
PathProviderPlugin
.
registerWith
(
registrarFor
(
"io.flutter.plugins.pathprovider.PathProviderPlugin"
));
FlutterAndroidLifecyclePlugin
.
registerWith
(
registrarFor
(
"io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin"
));
}
}
example/android/app/src/main/java/com/zt/shareextendexample/MainActivity.java
deleted
100644 → 0
View file @
b24c80ad
package
com.zt.shareextendexample
;
import
android.os.Bundle
;
import
io.flutter.app.FlutterActivity
;
import
io.flutter.plugins.GeneratedPluginRegistrant
;
public
class
MainActivity
extends
FlutterActivity
{
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
GeneratedPluginRegistrant
.
registerWith
(
this
);
}
}
pubspec.yaml
View file @
1c5d0220
...
...
@@ -18,9 +18,12 @@ dependencies:
# The following section is specific to Flutter.
flutter
:
plugin
:
androidPackage
:
com.zt.shareextend
platforms
:
android
:
package
:
com.zt.shareextend
pluginClass
:
ShareExtendPlugin
iosPrefix
:
FLT
ios
:
pluginClass
:
FLTShareExtendPlugin
# To add assets to your plugin package, add an assets section, like this:
# assets:
...
...
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