jshare_flutter_plugin 1.0.2

  • Readme
  • Changelog
  • Example
  • Installing
  • 72

jshare-flutter-plugin #

JIGUANG officially supported JShare SDK Flutter plugin (Android & iOS). 极光分享官方支持的 Flutter 插件(Android & iOS)。

一、安装 #

在工程 pubspec.yaml 中加入 dependencies

  • github 集成
dependencies:
  jshare_flutter_plugin:
    git:
      url: git://github.com/jpush/jshare-flutter-plugin.git
      ref: master
  • pub 集成
dependencies:
  jshare_flutter_plugin: 1.0.2

二、配置 #

2.1 Android:

2.1.1 gradle 配置

example/android/app/build.gradle 中添加下列代码:

android: {
  ....
  defaultConfig {
    applicationId "替换成自己应用 ID"
    ...
    ndk {
	//选择要添加的对应 cpu 类型的 .so 库。
	abiFilters 'armeabi', 'armeabi-v7a', 'x86', 'x86_64', 'mips', 'mips64', 'arm64-v8a',        
    }

    manifestPlaceholders = [
        JPUSH_PKGNAME : applicationId,
        JPUSH_APPKEY : "appkey", // NOTE: JPush 上注册的包名对应的 Appkey.
        JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可.
    ]
  }    
}
2.1.2 配置微信平台回调

在你的包名相应目录下新建一个wxapi目录,并在该wxapi目录下新增一个WXEntryActivity类,该类继承自WeChatHandleActivity(例如应用程序的包名为cn.jiguang.share.demo,则新添加的类如下图所示)

注意: 如果复写了onCreate方法、onNewIntent方法,那么必须调用父类方法,否者无法获取分享结果,例如:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
}
  • 并在 manifest 文件里面加上exported属性,设置为true,例如:
<activity
    android:name=".wxapi.WXEntryActivity"
    android:theme="@android:style/Theme.Translucent.NoTitleBar"
    android:exported="true" />
2.1.3 配置Facebook平台
  • example/android/app/src/main/ 目录下的 manifest 文件里面添加 FacebookContentProvider配置:
<provider
    android:authorities="com.facebook.app.FacebookContentProvider您申请的facebook的AppId"
    android:name="cn.jiguang.share.facebook.FacebookContentProvider"
    android:exported="true"
/>

注意: providerauthorities必须为"com.facebook.app.FacebookContentProvider"+"AppId"

  • 如果需要获取facebook上传图片、视频结果可自定义BroadCastReceiver,继承FacebookBroadcastReceiver,复写onSuccessfulAppCall、onFailedAppCall方法:
<receiver android:name="cn.jiguang.share.demo.FaceBookUploadReceiver">
    <intent-filter>
        <action android:name="com.facebook.platform.AppCallResultBroadcast" />
    </intent-filter>
</receiver>

注意receiveraction必须为"com.facebook.platform.AppCallResultBroadcast"

2.2 iOS

iOS 的功能目录为example/ios/

2.2.1 配置 ApplicationQueriesSchemes

iOS9/10 下就需要增加一个应用可跳转的白名单,即 LSApplicationQueriesSchemes,否则将在 SDK 判断是否跳转时用到的canOpenURL 时返回 NO,进而只进行 webview 分享/分享失败。

example/ios/Runner/目录中的info.plist 中加入应用白名单:

  • 右键 info.plist
  • 选择 source code
  • 添加如下内容:
<key>LSApplicationQueriesSchemes</key>
<array>
    <!-- 微信 URL Scheme 白名单-->
    <string>wechat</string>
    <string>weixin</string>

    <!-- 新浪微博 URL Scheme 白名单-->
    <string>sinaweibohd</string>
    <string>sinaweibo</string>
    <string>sinaweibosso</string>
    <string>weibosdk</string>
    <string>weibosdk2.5</string>

    <!-- QQ、Qzone URL Scheme 白名单-->
    <string>mqqapi</string>
    <string>mqq</string>
    <string>mqqOpensdkSSoLogin</string>
    <string>mqqconnect</string>
    <string>mqqopensdkdataline</string>
    <string>mqqopensdkgrouptribeshare</string>
    <string>mqqopensdkfriend</string>
    <string>mqqopensdkapi</string>
    <string>mqqopensdkapiV2</string>
    <string>mqqopensdkapiV3</string>
    <string>mqqopensdkapiV4</string>
    <string>mqzoneopensdk</string>
    <string>wtloginmqq</string>
    <string>wtloginmqq2</string>
    <string>mqqwpa</string>
    <string>mqzone</string>
    <string>mqzonev2</string>
    <string>mqzoneshare</string>
    <string>wtloginqzone</string>
    <string>mqzonewx</string>
    <string>mqzoneopensdkapiV2</string>
    <string>mqzoneopensdkapi19</string>
    <string>mqzoneopensdkapi</string>
    <string>mqqbrowser</string>
    <string>mttbrowser</string>

    <!-- Facebook URL Scheme 白名单-->
    <string>fbapi</string>
    <string>fb-messenger-api</string>
    <string>fbauth2</string>
    <string>fbshareextension</string>

    <!-- Twitter URL Scheme 白名单-->
    <string>twitter</string>
    <string>twitterauth</string>

    <!-- JChatPro URL Scheme 白名单-->
    <string>JChatPro</string>
</array>
2.2.2 添加 URL Types
  • 各个平台的 URL Schemes 格式说明:

  • URL Types 设置

    Xcode 打开工程 example/ios/Runner.xcworkspace目录中的 [TARGETS] -> [Info] 中设置:

2.3 iOS/Android 详细集成配置文档

三、使用 #

import 'package:jshare_flutter_plugin/jshare_flutter_plugin.dart';

APIs #

注意 : 需要先调用 JShare.setup 来初始化插件,才能保证其他功能正常工作。

参考

1.0.2 #

  • 内部安全策略优化

1.0.1 #

  • 修改文档

1.0.0 #

  • jshare-flutter-plugin 第一版本

example/lib/main.dart

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:typed_data';
import 'dart:io';

import 'package:flutter/services.dart';
import 'package:jshare_flutter_plugin/jshare_flutter_plugin.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:path_provider/path_provider.dart';

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

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

class _MyAppState extends State<MyApp> {

  List<Map<String, dynamic>> platfromList = [
    {
      "name": "微信",
      "icon": "jiguang_socialize_wechat.png",
      "platform": JSharePlatform.wechatSession
    },
    {
      "name": "朋友圈",
      "icon": "jiguang_socialize_wxtimeLine.png",
      "platform": JSharePlatform.wechatTimeLine
    },
    {
      "name": "微信收藏",
      "icon": "jiguang_socialize_wxfavorite.png",
      "platform": JSharePlatform.wechatFavourite
    },
    {
      "name": "QQ",
      "icon": "jiguang_socialize_qq.png",
      "platform": JSharePlatform.qq
    },
    {
      "name": "QQ空间",
      "icon": "jiguang_socialize_qzone.png",
      "platform": JSharePlatform.qZone
    },
    {
      "name": "微博",
      "icon": "jiguang_socialize_sina.png",
      "platform": JSharePlatform.sinaWeibo
    },
    {
      "name": "FaceBook",
      "icon": "jiguang_socialize_facebook.png",
      "platform": JSharePlatform.facebook
    },
    {
      "name": "Twitter",
      "icon": "jiguang_socialize_twitter.png",
      "platform": JSharePlatform.twitter
    }
  ];

  String _resultString = "显示结果";

  JShare jShare = new JShare();
  JShareType shareType;

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

  Future<void> initPlatformState() async {

    JShareConfig shareConfig = new JShareConfig(appKey: null);/// 填写自己应用的极光 AppKey

    shareConfig.channel = "channel";
    shareConfig.isDebug = true;
    shareConfig.isAdvertisinId = true;
    shareConfig.isProduction = true;

    shareConfig.weChatAppId = "wxc40e16f3ba6ebabc";
    shareConfig.weChatAppSecret = "dcad950cd0633a27e353477c4ec12e7a";

    shareConfig.qqAppId = "100424468";
    shareConfig.qqAppKey = "glFYjkHQGSOCJHMC";

    shareConfig.sinaWeiboAppKey = "374535501";
    shareConfig.sinaWeiboAppSecret = "baccd12c166f1df96736b51ffbf600a2";
    shareConfig.sinaRedirectUri = "https://www.jiguang.cn";

    shareConfig.facebookAppID = "1847959632183996";
    shareConfig.facebookDisplayName = "JShareDemo";

    shareConfig.twitterConsumerKey = "4hCeIip1cpTk9oPYeCbYKhVWi";
    shareConfig.twitterConsumerSecret =
        "DuIontT8KPSmO2Y1oAvby7tpbWHJimuakpbiAUHEKncbffekmC";

    jShare.setup(config: shareConfig);

    if (!mounted) return;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: new Scaffold(
      appBar: new AppBar(title: new Text("")),
      body: new Center(
        child: new Builder(builder: (BuildContext context) {
          return new Column(
            children: <Widget>[
              new Container(
                margin: EdgeInsets.fromLTRB(10, 10, 10, 10),
                color: Colors.brown,
                child: Text(_resultString),
                width: 300,
                height: 100,
              ),
              new Container(
                margin: EdgeInsets.all(10),
                //color: Colors.brown,
                child: new Row(
                  children: <Widget>[
                    Expanded(
                      flex: 1,
                      child: new CustomButton(
                        title: "分享【文本】",
                        onPressed: () {
                          _showSheet(context, JShareType.text);
                        },
                      ),
                    ),
                    new Text(" "),
                    Expanded(
                      flex: 1,
                      child: new CustomButton(
                        title: "分享【图片】",
                        onPressed: () {
                          _showSheet(context, JShareType.image);
                        },
                      ),
                    ),
                    new Text(" "),
                    Expanded(
                      flex: 1,
                      child: new CustomButton(
                        title: "分享【链接】",
                        onPressed: () {
                          _showSheet(context, JShareType.link);
                        },
                      ),
                    ),
                  ],
                ),
              ),
              new Container(
                  margin: EdgeInsets.fromLTRB(10, 0, 10, 10),
                  child: new Row(
                    children: <Widget>[
                      Expanded(
                        flex: 1,
                        child: new CustomButton(
                          title: "分享【音乐】",
                          onPressed: () {
                            _showSheet(context, JShareType.audio);
                          },
                        ),
                      ),
                      new Text(" "),
                      Expanded(
                        flex: 1,
                        child: new CustomButton(
                          title: "分享【视频】",
                          onPressed: () {
                            _showSheet(context, JShareType.video);
                          },
                        ),
                      ),
                      new Text(" "),
                      Expanded(
                        flex: 1,
                        child: new CustomButton(
                          title: "分享【APP】",
                          onPressed: () {
                            _showSheet(context, JShareType.app);
                          },
                        ),
                      ),
                    ],
                  )),
              new CustomButton(
                title: "分享【小程序】",
                onPressed: () {
                  _showSheet(context, JShareType.miniProgram);
                },
              ),
              new Divider(height: 10,color: Colors.brown),
              new Text("以下示例以【微信】为例"),
              new Container(
                margin: EdgeInsets.fromLTRB(10, 10, 10, 10),
                child: new Row(
                  children: <Widget>[
                    Expanded(
                      flex: 1,
                      child: new CustomButton(
                        title: "是否授权",
                        onPressed: () {
                          jShare.isPlatformAuth(platform: JSharePlatform.wechatSession).then((JShareResponse response){
                            setState(() {
                              _resultString = "是否授权:" + response.toJsonMap().toString();
                            });
                          }).catchError((error){
                            setState(() {
                              _resultString = "是否授权:" + error.toString();
                            });
                          });
                        },
                      ),
                    ),
                    new Text(" "),
                    Expanded(
                      flex: 1,
                      child: new CustomButton(
                        title: "授权",
                        onPressed: () {
                          jShare.authorize(platform: JSharePlatform.wechatSession).then((JShareSocial value){
                            setState(() {
                              _resultString = "授权:" + value.toJsonMap().toString();
                            });
                          }).catchError((error){
                            setState(() {
                              _resultString = "授权:" + error.toString();
                            });
                          });
                        },
                      ),
                    ),
                    new Text(" "),
                    Expanded(
                      flex: 1,
                      child: new CustomButton(
                        title: "取消授权",
                        onPressed: () {
                          jShare.cancelPlatformAuth(platform: JSharePlatform.wechatSession).then((JShareResponse response){
                            setState(() {
                              _resultString = "取消授权:" + response.toJsonMap().toString();
                            });
                          }).catchError((error){
                            setState(() {
                              _resultString = "取消授权:" + error.toString();
                            });
                          });
                        },
                      ),
                    ),
                  ],
                )
              ),
              new CustomButton(
                title: "获取【用户信息】",
                onPressed: () {
                  jShare.getUserInfo(platform: JSharePlatform.wechatSession).then((JShareUserInfo info){
                    setState(() {
                      _resultString = "获取用户信息:" + info.toJsonMap().toString();
                    });
                  }).catchError((error){
                    setState(() {
                      _resultString = "获取用户信息:" + error.toString();
                    });
                  });
                },
              ),
            ],
          );
        }),
      ),
    ));
  }


  Widget _showSheet(BuildContext context, JShareType type) {
    shareType = type;
    showModalBottomSheet(
        context: context,
        builder: (BuildContext context) {
          return _shareWidget(context);
        });
  }

  Widget _shareWidget(BuildContext context) {
    return new Container(
      height: 300,
      color: Colors.white,
      child: new Column(
        children: <Widget>[
          new Padding(
            padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
            child: new Container(
              height: 200,
              child: new GridView.builder(
                gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 4,
                    mainAxisSpacing: 5.0,
                    childAspectRatio: 1.0),
                itemBuilder: (BuildContext context, int index) {
                  return new Column(
                    children: <Widget>[
                      new Padding(
                          padding: EdgeInsets.fromLTRB(0, 6, 0, 6),
                          child: new GestureDetector(
                            child: new Image.asset(
                              'assets/images/${platfromList[index]["icon"]}',
                              width: 50,
                              height: 50,
                              fit: BoxFit.fill,
                            ),
                            onTap: () {
                              Navigator.of(context).pop();
                              _didSelectPlatform(index: index);
                            },
                          )),
                      new Text(platfromList[index]["name"]),
                    ],
                  );
                },
                itemCount: platfromList.length,
              ),
            ),
          ),
          new Divider(height: 0.5, color: Colors.blueGrey),
          new Center(
            child: new Padding(
                padding: EdgeInsets.fromLTRB(0, 8, 0, 8),
                child: new GestureDetector(
                    onTap: () {
                      Navigator.of(context).pop();
                    },
                    child: new Text(
                      "取 消",
                      style:
                          new TextStyle(fontSize: 20.0, color: Colors.blueGrey),
                    ))),
          ),
        ],
      ),
    );
  }

  /// 选择摸个平台分享
  void _didSelectPlatform({@required int index}) async {
    print("Action - didSelectPlatform:  " +
        "platfrom = " +
        platfromList[index].toString());

    JShareMessage message = new JShareMessage();
    message.mediaType = shareType;
    message.platform = platfromList[index]["platform"];

    if (message.platform != JSharePlatform.sinaWeibo) {
      // 新浪可以支持网页分享
      bool isValid = await jShare.isClientValid(platform: message.platform);
      if (isValid == false) {
        print("is not available platfrom (" +
            platfromList[index].toString() +
            ")");
        return;
      }
    }

    message.text = "jshare-text";
    message.title = "jshare-title";
    message.url = "https://www.jiguang.cn/";

    /// 添加 测试图片
    String tempImagePath = await _tempSaveTestImage();

    if (shareType == JShareType.image) {
      //大图
      message.imagePath = tempImagePath;
    } else {
      //缩略图
      message.imagePath = tempImagePath;
    }

    if (shareType == JShareType.audio) {
      //音频跳转链接
      message.url = "https://y.qq.com/n/yqq/song/003RCA7t0y6du5.html";
      // 音频源链接,直接播放
      // message.musicDataUrl = "";
    } else if (shareType == JShareType.video) {
      //视频源
      if (message.platform == JSharePlatform.qZone ||
          message.platform == JSharePlatform.facebook ||
          message.platform == JSharePlatform.facebookMessenger ||
          message.platform == JSharePlatform.twitter) {
        //message.videoPath = "";Android 为本地路径,iOS 为ALAsset的ALAssetPropertyAssetURL
      } else {
        message.url = "http://v.youku.com/v_show/id_XOTQwMDE1ODAw.html?from=s1.8-1-1.2&spm=a2h0k.8191407.0.0";
      }
    } else if (shareType == JShareType.link) {
      //分享网页链接
      //
    } else if (shareType == JShareType.app) {
      //message.fileDataPath = ""; iOS 端 APP 数据
      message.extInfo = "<xml>extend info</xml>";
    } else if (shareType == JShareType.file) {
      // message.fileDataPath = "";
      //message.fileExt = "";
    } else if (shareType == JShareType.emoticon) {
      // message.emoticonDataPath =
    } else if (shareType == JShareType.miniProgram) {
      message.miniProgramUserName = "gh_cd370c00d3d4";
      message.miniProgramPath = "pages/index/index";
      message.miniProgramType = 0;
      message.miniProgramWithShareTicket = true;
      // 小程序封面图
      //message.imageUrl = "https://img2.3lian.com/2014/f5/63/d/23.jpg";
    } else {}

    jShare.shareMessage(message: message).then((JShareResponse response) {
      print("分享回调:" + response.toJsonMap().toString());
      setState(() {
        _resultString = "分享成功:"+ response.toJsonMap().toString();
      });
      /// 删除测试图片
      _tempDeleteTestImage();
    }).catchError((error) {
      print("分享回调 -- 出错:${error.toString()}");

      setState(() {
        _resultString = "分享失败:"+ error.toString();
      });

      /// 删除测试图片
      _tempDeleteTestImage();
    });
  }


  /// TEST : 测试图片
  static String testImageName = "icon_jiguang.png";

  Future<String> _tempSaveTestImage() async {
    print("Action - _tempSaveTestImage:");
    final Directory directory = await getTemporaryDirectory();

    Uint8List bytes = await _getAssetsImageBytes(testImageName);
    String path = await _saveFile(directory, testImageName, bytes);

    return path;
  }

  /// TEST : 删除图片
  void _tempDeleteTestImage() async {
    print("Action - _tempDeleteTestImage:");
    final Directory directory = await getTemporaryDirectory();
    String imageName = testImageName;
    _deleteFile(directory, imageName);
  }


  /// TEST : 获取 assets里的图片(测试暂时用 assets 里的)
  Future<Uint8List> _getAssetsImageBytes(String imagePath) async {
    print("Action - getAssetsImageBytes:" + imagePath);

    ByteData byteData = await rootBundle.load("assets/images/"+imagePath);
    Uint8List uint8list = byteData.buffer.asUint8List();

    return uint8list;
  }

  /// TEST : 存储文件
  Future<String> _saveFile(Directory directory, String name, Uint8List bytes) async {
    print("Action - _saveFile:" + "directory:" + directory.toString() + ",name:" + name);
    final File file = File('${directory.path}/$name');

    if (file.existsSync()) {
      file.deleteSync();
    }

    File file1 = await file.writeAsBytes(bytes);

    if(file1.existsSync()) {
      print('====保存成功');
    }else{
      print('====保存失败');
    }
    return file1.path;
  }

  /// TEST : 获取文件路径
  String _getFilePath(Directory directory, String name){
    print("Action - _getFilePath:");
    final File file = File('${directory.path}/$name');
    if (!file.existsSync()) {
      return null;
    }
    String path = file.readAsStringSync();
    return path;
  }

  /// TEST : 删除文件
  void _deleteFile(Directory directory, String name) {
    print("Action - _deleteFile:");
    final File file = File('${directory.path}/$name');

    if (file.existsSync()) {
      file.deleteSync();
    }
  }
}



/// 封装 按钮
class CustomButton extends StatelessWidget {
  final VoidCallback onPressed;
  final String title;

  const CustomButton({@required this.onPressed, this.title});

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new FlatButton(
      onPressed: onPressed,
      child: new Text("$title"),
      color: Color(0xff585858),
      highlightColor: Color(0xff888888),
      splashColor: Color(0xff888888),
      textColor: Colors.white,
      padding: EdgeInsets.fromLTRB(10, 5, 10, 5),
    );
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  jshare_flutter_plugin: ^1.0.2

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:jshare_flutter_plugin/jshare_flutter_plugin.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
53
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
80
Overall:
Weighted score of the above. [more]
72
Learn more about scoring.

We analyzed this package on Jul 11, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.15
  • Flutter: 1.17.5

Analysis suggestions

Package does not support Flutter platform Linux

Because:

  • package:jshare_flutter_plugin/jshare_flutter_plugin.dart that declares support for platforms: Android, iOS

Package does not support Flutter platform Web

Because:

  • package:jshare_flutter_plugin/jshare_flutter_plugin.dart that declares support for platforms: Android, iOS

Package does not support Flutter platform Windows

Because:

  • package:jshare_flutter_plugin/jshare_flutter_plugin.dart that declares support for platforms: Android, iOS

Package does not support Flutter platform macOS

Because:

  • package:jshare_flutter_plugin/jshare_flutter_plugin.dart that declares support for platforms: Android, iOS

Package not compatible with SDK dart

Because:

  • jshare_flutter_plugin that is a package requiring null.

Health suggestions

Format lib/jshare_flutter_plugin.dart.

Run flutter format to format lib/jshare_flutter_plugin.dart.

Maintenance issues and suggestions

The description contains too many non-ASCII characters. (-20 points)

The site uses English as its primary language. The value of the description field in your package's pubspec.yaml field should primarily contain characters used in English.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.12 1.14.13
meta 1.1.8 1.2.2
sky_engine 0.0.99
typed_data 1.1.6 1.2.0
vector_math 2.0.8 2.1.0-nullsafety
Dev dependencies
flutter_test