Skip to content

Commit

Permalink
Remove unused codes and fix bug FileUriExposedException
Browse files Browse the repository at this point in the history
  • Loading branch information
lubritto committed Oct 16, 2019
1 parent 39074ce commit aed06ad
Show file tree
Hide file tree
Showing 14 changed files with 106 additions and 93 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## 1.0.2

* Fix bug (FileUriExposedException) on new android versions
* Fix Android bug (FileUriExposedException) on new versions with FileProvider implementation (see the readme to configure)

## 1.0.1+1

Expand Down
41 changes: 38 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ A Flutter plugin for IOS and Android providing a simple way to share a message,

## Features:

* Share message and/or link urls.
* Share local file path
* Share messages and/or link urls.
* Share local files.

![android](assets/gifs/flutter_share_android.gif) ........... ![ios](assets/gifs/flutter_share_ios.gif)
![android](assets/gifs/flutter_share_android.gif)         ![ios](assets/gifs/flutter_share_ios.gif)

## Installation

Expand All @@ -28,6 +28,41 @@ target 'Runner' do
...
```

### Android

If you pretends to use the file share, you need to configure the file provider, this will give access to the files turning possible to share with other applications.

Add to `AndroidManifest.xml`:

```
<application>
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
</application>
```
Obs: You can change the android:name if you have an extension of file provider.

Add `res/xml/provider_paths.xml`:

```
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
```

If you want to learn more about file provider you can access:

- https://developer.android.com/reference/android/support/v4/content/FileProvider

### Example

Here is an example flutter app displaying the two shares methods. (I'm using documents_picker just to get a local file you don't need to use.)
Expand Down
1 change: 1 addition & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ android {

dependencies {
api 'commons-io:commons-io:2.6'
implementation 'androidx.core:core:1.1.0'
}

Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import android.text.TextUtils;
import android.util.Log;

import androidx.core.content.FileProvider;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import io.flutter.plugin.common.MethodCall;
Expand All @@ -16,8 +16,6 @@
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;

import org.apache.commons.io.FileUtils;


/** FlutterSharePlugin */
public class FlutterSharePlugin implements MethodCallHandler {
Expand All @@ -39,15 +37,15 @@ public static void registerWith(Registrar registrar) {
@Override
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("shareFile")) {
result.success(shareFile(call));
shareFile(call, result);
} else if (call.method.equals("share")) {
result.success(share(call));
share(call, result);
} else {
result.notImplemented();
}
}

private boolean share(MethodCall call) {
private void share(MethodCall call, Result result) {
try
{
String title = call.argument("title");
Expand All @@ -58,7 +56,8 @@ private boolean share(MethodCall call) {
if (title == null || title.isEmpty())
{
Log.println(Log.ERROR, "", "FlutterShare Error: Title null or empty");
return false;
result.error("FlutterShare: Title cannot be null or empty", null, null);
return;
}

ArrayList<String> extraTextList = new ArrayList<>();
Expand Down Expand Up @@ -89,59 +88,33 @@ private boolean share(MethodCall call) {
chooserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mRegistrar.context().startActivity(chooserIntent);

return true;
result.success(true);
}
catch (Exception ex)
{
Log.println(Log.ERROR, "", "FlutterShare: Error");
result.error(ex.getMessage(), null, null);
}

return false;
}

private boolean shareFile(MethodCall call) {
File file = null;

String title = call.argument("title");
String text = call.argument("text");
String filePath = call.argument("filePath");
String chooserTitle = call.argument("chooserTitle");

private void shareFile(MethodCall call, Result result) {
try
{
String title = call.argument("title");
String text = call.argument("text");
String filePath = call.argument("filePath");
String chooserTitle = call.argument("chooserTitle");

if (filePath == null || filePath.isEmpty())
{
Log.println(Log.ERROR, "", "FlutterShare: ShareLocalFile Error: filePath null or empty");
return false;
}

String fileName = Uri.parse(filePath).getLastPathSegment();

File oldFile = new File(filePath);

byte[] bArray = FileUtils.readFileToByteArray(oldFile);

String tempDirPath = mRegistrar.context().getExternalCacheDir()
+ File.separator + "TempFiles" + File.separator;
String path = tempDirPath + fileName;

File tempDir = new File(tempDirPath);

file = new File(path);

if (!tempDir.exists())
tempDir.mkdirs();
else {
DeleteAllTempFiles();
result.error("FlutterShare: FilePath cannot be null or empty", null, null);
return;
}

file.createNewFile();
File file = new File(filePath);

FileOutputStream fo = new FileOutputStream(file);
fo.write(bArray);
fo.close();

Uri fileUri = Uri.parse(file.getPath());
Uri fileUri = FileProvider.getUriForFile(mRegistrar.context(), mRegistrar.context().getApplicationContext().getPackageName() + ".provider", file);

Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Expand All @@ -158,39 +131,12 @@ private boolean shareFile(MethodCall call) {
chooserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mRegistrar.context().startActivity(chooserIntent);

return true;
}
catch (IOException ex) {
ex.printStackTrace();
Log.println(Log.ERROR, "", "FlutterShare: IOException");
result.success(true);
}
catch (Exception ex)
{
ex.printStackTrace();
result.error(ex.getMessage(), null, null);
Log.println(Log.ERROR, "", "FlutterShare: Error");
}
finally {
if (file != null)
file.deleteOnExit();
}

return false;
}


public void DeleteAllTempFiles(){
String tempDirPath = mRegistrar.context().getExternalCacheDir()
+ File.separator + "TempFiles" + File.separator;

File tempDir = new File(tempDirPath);

if (tempDir.exists()) {

String[] children = tempDir.list();
for (int i = 0; i < children.length; i++)
{
new File(tempDir, children[i]).delete();
}
}
}
}
12 changes: 6 additions & 6 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 27
compileSdkVersion 28

lintOptions {
disable 'InvalidPackage'
Expand All @@ -24,11 +24,11 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.fluttershareexample"
minSdkVersion 16
targetSdkVersion 27
minSdkVersion 17
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
Expand All @@ -46,6 +46,6 @@ flutter {

dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
}
9 changes: 9 additions & 0 deletions example/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,14 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
</application>
</manifest>
4 changes: 4 additions & 0 deletions example/android/app/src/main/res/xml/provider_paths.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
3 changes: 3 additions & 0 deletions example/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
android.enableJetifier=true
android.useAndroidX=true

org.gradle.jvmargs=-Xmx1536M
8 changes: 7 additions & 1 deletion example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ PODS:
- Flutter (1.0.0)
- flutter_share (0.0.1):
- Flutter
- path_provider (0.0.1):
- Flutter

DEPENDENCIES:
- documents_picker (from `.symlinks/plugins/documents_picker/ios`)
- Flutter (from `.symlinks/flutter/ios`)
- flutter_share (from `.symlinks/plugins/flutter_share/ios`)
- path_provider (from `.symlinks/plugins/path_provider/ios`)

EXTERNAL SOURCES:
documents_picker:
Expand All @@ -17,11 +20,14 @@ EXTERNAL SOURCES:
:path: ".symlinks/flutter/ios"
flutter_share:
:path: ".symlinks/plugins/flutter_share/ios"
path_provider:
:path: ".symlinks/plugins/path_provider/ios"

SPEC CHECKSUMS:
documents_picker: 5af54172fc411009a331391a6264987a852fcef8
Flutter: 58dd7d1b27887414a370fcccb9e645c08ffd7a6a
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
flutter_share: 4be0208963c60b537e6255ed2ce1faae61cd9ac2
path_provider: f96fff6166a8867510d2c25fdcc346327cc4b259

PODFILE CHECKSUM: 7765ea4305eaab0b3dfd384c7de11902aa3195fd

Expand Down
2 changes: 2 additions & 0 deletions example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,14 @@
"${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
"${BUILT_PRODUCTS_DIR}/documents_picker/documents_picker.framework",
"${BUILT_PRODUCTS_DIR}/flutter_share/flutter_share.framework",
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/documents_picker.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_share.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
Expand Down
11 changes: 9 additions & 2 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:io';

import 'package:documents_picker/documents_picker.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -31,8 +32,14 @@ class MyApp extends StatelessWidget {
}

Future<void> shareScreenShot() async {
final directory = await getExternalStorageDirectory();
final String localPath = '${directory.path}/test.png';
Directory directory;
if (Platform.isAndroid) {
directory = await getExternalStorageDirectory();
} else {
directory = await getApplicationDocumentsDirectory();
}
final String localPath =
'${directory.path}/${DateTime.now().toIso8601String()}.png';

await _controller.capture(path: localPath);

Expand Down
4 changes: 2 additions & 2 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ packages:
name: documents_picker
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.3"
version: "1.0.0"
flutter:
dependency: "direct main"
description: flutter
Expand All @@ -54,7 +54,7 @@ packages:
path: ".."
relative: true
source: path
version: "1.0.1+1"
version: "1.0.2+1"
flutter_test:
dependency: "direct dev"
description: flutter
Expand Down
4 changes: 2 additions & 2 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ dependencies:

cupertino_icons: ^0.1.2
screenshot: ^0.1.1
documents_picker: ^0.0.2
path_provider: ^1.2.0
documents_picker: ^1.0.0
path_provider: ^1.3.0

dev_dependencies:
flutter_test:
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: flutter_share
description: Simple way to share message, links or files from your flutter app for Android and IOS (Enter to see some gifs).
version: 1.0.2
version: 1.0.2+1
author: Lucas Britto <[email protected]>
homepage: https://github.com/lubritto/flutter_share

Expand Down

0 comments on commit aed06ad

Please sign in to comment.