forked from flutter/plugins
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
71a8317
commit fb0c292
Showing
9 changed files
with
370 additions
and
2 deletions.
There are no files selected for viewing
25 changes: 23 additions & 2 deletions
25
packages/webview_flutter/android/src/main/AndroidManifest.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,23 @@ | ||
<manifest package="io.flutter.plugins.webviewflutter"> | ||
</manifest> | ||
<manifest package="io.flutter.plugins.webviewflutter" | ||
xmlns:android="http://schemas.android.com/apk/res/android"> | ||
<application> | ||
<activity | ||
android:name="io.flutter.plugins.webviewflutter.RequestCameraPermissionActivity" | ||
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" /> | ||
<activity | ||
android:name="io.flutter.plugins.webviewflutter.FileChooserActivity" | ||
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" /> | ||
|
||
<provider | ||
android:name="io.flutter.plugins.webviewflutter.GenericFileProvider" | ||
android:authorities="${applicationId}.generic.provider" | ||
android:exported="false" | ||
android:grantUriPermissions="true" | ||
> | ||
<meta-data | ||
android:name="android.support.FILE_PROVIDER_PATHS" | ||
android:resource="@xml/provider_paths" | ||
/> | ||
</provider> | ||
</application> | ||
</manifest> |
18 changes: 18 additions & 0 deletions
18
...es/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/Constants.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright 2019 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
package io.flutter.plugins.webviewflutter; | ||
|
||
public class Constants { | ||
static final String ACTION_REQUEST_CAMERA_PERMISSION_FINISHED = | ||
"action_request_camera_permission_denied"; | ||
static final String ACTION_FILE_CHOOSER_FINISHED = "action_file_chooser_completed"; | ||
|
||
static final String EXTRA_TITLE = "extra_title"; | ||
static final String EXTRA_TYPE = "extra_type"; | ||
static final String EXTRA_SHOW_CAMERA_OPTION = "extra_show_camera_option"; | ||
static final String EXTRA_FILE_URI = "extra_file_uri"; | ||
|
||
static final String WEBVIEW_STORAGE_DIRECTORY = "storage"; | ||
} |
169 changes: 169 additions & 0 deletions
169
..._flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FileChooserActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
// Copyright 2019 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
package io.flutter.plugins.webviewflutter; | ||
|
||
import static io.flutter.plugins.webviewflutter.Constants.ACTION_FILE_CHOOSER_FINISHED; | ||
import static io.flutter.plugins.webviewflutter.Constants.EXTRA_FILE_URI; | ||
import static io.flutter.plugins.webviewflutter.Constants.EXTRA_SHOW_CAMERA_OPTION; | ||
import static io.flutter.plugins.webviewflutter.Constants.EXTRA_TITLE; | ||
import static io.flutter.plugins.webviewflutter.Constants.EXTRA_TYPE; | ||
import static io.flutter.plugins.webviewflutter.Constants.WEBVIEW_STORAGE_DIRECTORY; | ||
|
||
import android.app.Activity; | ||
import android.content.Intent; | ||
import android.database.Cursor; | ||
import android.net.Uri; | ||
import android.os.Bundle; | ||
import android.provider.MediaStore; | ||
import android.provider.OpenableColumns; | ||
import android.util.Log; | ||
import androidx.annotation.Nullable; | ||
import androidx.core.content.FileProvider; | ||
import java.io.File; | ||
import java.io.FileOutputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.OutputStream; | ||
import java.text.SimpleDateFormat; | ||
import java.util.Date; | ||
|
||
public class FileChooserActivity extends Activity { | ||
|
||
private static final int FILE_CHOOSER_REQUEST_CODE = 12322; | ||
private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss"); | ||
|
||
private Uri cameraImageUri; | ||
|
||
@Override | ||
protected void onCreate(@Nullable Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
showFileChooser(getIntent().getBooleanExtra(EXTRA_SHOW_CAMERA_OPTION, false)); | ||
} | ||
|
||
private void showFileChooser(boolean enableCamera) { | ||
Intent galleryIntent = createGalleryIntent(); | ||
Intent takePictureIntent = enableCamera ? createCameraIntent() : null; | ||
if (galleryIntent == null && takePictureIntent == null) { | ||
// cannot open anything: cancel file chooser | ||
sendBroadcast(new Intent(ACTION_FILE_CHOOSER_FINISHED)); | ||
finish(); | ||
} else { | ||
Intent[] intentArray = | ||
takePictureIntent != null ? new Intent[] {takePictureIntent} : new Intent[] {}; | ||
|
||
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER); | ||
chooserIntent.putExtra( | ||
Intent.EXTRA_INTENT, galleryIntent != null ? galleryIntent : takePictureIntent); | ||
chooserIntent.putExtra(Intent.EXTRA_TITLE, getIntent().getStringExtra(EXTRA_TITLE)); | ||
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray); | ||
|
||
startActivityForResult(chooserIntent, FILE_CHOOSER_REQUEST_CODE); | ||
} | ||
} | ||
|
||
private Intent createGalleryIntent() { | ||
Intent filesIntent = new Intent(Intent.ACTION_GET_CONTENT); | ||
filesIntent.setType(getIntent().getStringExtra(EXTRA_TYPE)); | ||
return (filesIntent.resolveActivity(getPackageManager()) != null) ? filesIntent : null; | ||
} | ||
|
||
private Intent createCameraIntent() { | ||
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); | ||
if (takePictureIntent.resolveActivity(getPackageManager()) == null) { | ||
return null; | ||
} | ||
// Create the File where the photo should go | ||
cameraImageUri = getTempImageUri(); | ||
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraImageUri); | ||
|
||
return takePictureIntent; | ||
} | ||
|
||
private File getStorageDirectory() { | ||
File imageDirectory = new File(getCacheDir(), WEBVIEW_STORAGE_DIRECTORY); | ||
if (!imageDirectory.exists() && !imageDirectory.mkdir()) { | ||
Log.e("WEBVIEW", "Unable to create storage directory"); | ||
} | ||
return imageDirectory; | ||
} | ||
|
||
private Uri getTempImageUri() { | ||
String imageFileName = "IMG-" + simpleDateFormat.format(new Date()) + ".jpg"; | ||
File imageFile = new File(getStorageDirectory(), imageFileName); | ||
return FileProvider.getUriForFile( | ||
this, getApplicationContext().getPackageName() + ".generic.provider", imageFile); | ||
} | ||
|
||
private String getFileNameFromUri(Uri uri) { | ||
Cursor returnCursor = getContentResolver().query(uri, null, null, null, null); | ||
assert returnCursor != null; | ||
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); | ||
returnCursor.moveToFirst(); | ||
String name = returnCursor.getString(nameIndex); | ||
returnCursor.close(); | ||
return name; | ||
} | ||
|
||
private Uri copyToLocalUri(Uri uri) { | ||
InputStream in = null; | ||
OutputStream out = null; | ||
try { | ||
File destination = new File(getStorageDirectory(), getFileNameFromUri(uri)); | ||
in = getContentResolver().openInputStream(uri); | ||
out = new FileOutputStream(destination); | ||
|
||
int cnt = 0; | ||
byte[] buffer = new byte[1024]; | ||
int len; | ||
while ((len = in.read(buffer)) != -1) { | ||
out.write(buffer, 0, len); | ||
cnt += len; | ||
} | ||
|
||
return FileProvider.getUriForFile( | ||
this, getApplicationContext().getPackageName() + ".generic.provider", destination); | ||
} catch (Exception e) { | ||
Log.e("WEBVIEW", "Unable to copy selected image", e); | ||
} finally { | ||
if (in != null) { | ||
try { | ||
in.close(); | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
if (out != null) { | ||
try { | ||
out.close(); | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
|
||
@Override | ||
protected void onActivityResult(int requestCode, int resultCode, Intent data) { | ||
if (requestCode == FILE_CHOOSER_REQUEST_CODE) { | ||
Intent intent = new Intent(ACTION_FILE_CHOOSER_FINISHED); | ||
if (resultCode == Activity.RESULT_OK) { | ||
if (data != null && data.getDataString() != null) { | ||
// result from file browser | ||
final Uri uri = copyToLocalUri(data.getData()); | ||
intent.putExtra(EXTRA_FILE_URI, uri.toString()); | ||
} else { | ||
// result from camera | ||
intent.putExtra(EXTRA_FILE_URI, cameraImageUri.toString()); | ||
} | ||
} | ||
sendBroadcast(intent); | ||
finish(); | ||
} else { | ||
super.onActivityResult(requestCode, resultCode, data); | ||
} | ||
} | ||
} |
89 changes: 89 additions & 0 deletions
89
..._flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FileChooserLauncher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// Copyright 2019 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
package io.flutter.plugins.webviewflutter; | ||
|
||
import static io.flutter.plugins.webviewflutter.Constants.ACTION_FILE_CHOOSER_FINISHED; | ||
import static io.flutter.plugins.webviewflutter.Constants.ACTION_REQUEST_CAMERA_PERMISSION_FINISHED; | ||
import static io.flutter.plugins.webviewflutter.Constants.EXTRA_FILE_URI; | ||
import static io.flutter.plugins.webviewflutter.Constants.EXTRA_SHOW_CAMERA_OPTION; | ||
import static io.flutter.plugins.webviewflutter.Constants.EXTRA_TITLE; | ||
import static io.flutter.plugins.webviewflutter.Constants.EXTRA_TYPE; | ||
|
||
import android.Manifest; | ||
import android.content.BroadcastReceiver; | ||
import android.content.Context; | ||
import android.content.Intent; | ||
import android.content.IntentFilter; | ||
import android.content.pm.PackageManager; | ||
import android.net.Uri; | ||
import android.webkit.ValueCallback; | ||
import androidx.core.content.ContextCompat; | ||
|
||
public class FileChooserLauncher extends BroadcastReceiver { | ||
|
||
private Context context; | ||
private String title; | ||
private String type; | ||
private boolean showCameraOption; | ||
private ValueCallback<Uri[]> filePathCallback; | ||
|
||
public FileChooserLauncher( | ||
Context context, | ||
String title, | ||
String type, | ||
boolean showCameraOption, | ||
ValueCallback<Uri[]> filePathCallback) { | ||
this.context = context; | ||
this.title = title; | ||
this.type = type; | ||
this.showCameraOption = showCameraOption; | ||
this.filePathCallback = filePathCallback; | ||
} | ||
|
||
private boolean hasCameraPermission() { | ||
return ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) | ||
== PackageManager.PERMISSION_GRANTED; | ||
} | ||
|
||
public void start() { | ||
if (!showCameraOption || hasCameraPermission()) { | ||
showFileChooser(); | ||
} else { | ||
IntentFilter intentFilter = new IntentFilter(); | ||
intentFilter.addAction(ACTION_REQUEST_CAMERA_PERMISSION_FINISHED); | ||
context.registerReceiver(this, intentFilter); | ||
|
||
Intent intent = new Intent(context, RequestCameraPermissionActivity.class); | ||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | ||
context.startActivity(intent); | ||
} | ||
} | ||
|
||
private void showFileChooser() { | ||
IntentFilter intentFilter = new IntentFilter(ACTION_FILE_CHOOSER_FINISHED); | ||
context.registerReceiver(this, intentFilter); | ||
|
||
Intent intent = new Intent(context, FileChooserActivity.class); | ||
intent.putExtra(EXTRA_TITLE, title); | ||
intent.putExtra(EXTRA_TYPE, type); | ||
intent.putExtra(EXTRA_SHOW_CAMERA_OPTION, showCameraOption && hasCameraPermission()); | ||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | ||
context.startActivity(intent); | ||
} | ||
|
||
@Override | ||
public void onReceive(Context context, Intent intent) { | ||
if (intent.getAction().equals(ACTION_REQUEST_CAMERA_PERMISSION_FINISHED)) { | ||
context.unregisterReceiver(this); | ||
showFileChooser(); | ||
} else if (intent.getAction().equals(ACTION_FILE_CHOOSER_FINISHED)) { | ||
String uriString = intent.getStringExtra(EXTRA_FILE_URI); | ||
Uri[] result = uriString != null ? new Uri[] {Uri.parse(uriString)} : null; | ||
filePathCallback.onReceiveValue(result); | ||
context.unregisterReceiver(this); | ||
filePathCallback = null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
..._flutter/android/src/main/java/io/flutter/plugins/webviewflutter/GenericFileProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Copyright 2019 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
package io.flutter.plugins.webviewflutter; | ||
|
||
import androidx.core.content.FileProvider; | ||
|
||
public class GenericFileProvider extends FileProvider {} |
39 changes: 39 additions & 0 deletions
39
...roid/src/main/java/io/flutter/plugins/webviewflutter/RequestCameraPermissionActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Copyright 2019 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
package io.flutter.plugins.webviewflutter; | ||
|
||
import static io.flutter.plugins.webviewflutter.Constants.ACTION_REQUEST_CAMERA_PERMISSION_FINISHED; | ||
|
||
import android.Manifest; | ||
import android.app.Activity; | ||
import android.content.Intent; | ||
import android.os.Bundle; | ||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
import androidx.core.app.ActivityCompat; | ||
|
||
public class RequestCameraPermissionActivity extends Activity { | ||
|
||
private static final int CAMERA_PERMISSION_REQUEST_CODE = 12321; | ||
|
||
@Override | ||
protected void onCreate(@Nullable Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
|
||
ActivityCompat.requestPermissions( | ||
this, new String[] {Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE); | ||
} | ||
|
||
@Override | ||
public void onRequestPermissionsResult( | ||
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { | ||
if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) { | ||
sendBroadcast(new Intent(ACTION_REQUEST_CAMERA_PERMISSION_FINISHED)); | ||
finish(); | ||
} else { | ||
super.onRequestPermissionsResult(requestCode, permissions, grantResults); | ||
} | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
packages/webview_flutter/android/src/main/res/values/strings.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<resources> | ||
<string name="webview_file_chooser_title">Choose a file</string> | ||
<string name="webview_file_chooser_type">image/*</string> | ||
</resources> |
Oops, something went wrong.