1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-31 07:33:46 +00:00

Add support for camera for android choose file

This commit is contained in:
Kyle Spearrin
2017-07-22 21:06:53 -04:00
parent f9d336a3a6
commit 395545f7b1
14 changed files with 271 additions and 622 deletions

View File

@@ -18,6 +18,7 @@ using Bit.App;
using Android.Nfc;
using Android.Views.InputMethods;
using System.IO;
using System.Linq;
namespace Bit.Android
{
@@ -211,8 +212,18 @@ namespace Bit.Android
ParseYubiKey(intent.DataString);
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
public async override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
if(requestCode == Constants.SelectFilePermissionRequestCode)
{
if(grantResults.Any(r => r != Permission.Granted))
{
MessagingCenter.Send(Xamarin.Forms.Application.Current, "SelectFileCameraPermissionDenied");
}
await _deviceActionService.SelectFileAsync();
return;
}
ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
@@ -221,16 +232,32 @@ namespace Bit.Android
if(requestCode == Constants.SelectFileRequestCode && resultCode == Result.Ok)
{
global::Android.Net.Uri uri = null;
if(data != null)
string fileName = null;
if(data != null && data.Data != null)
{
uri = data.Data;
using(var stream = ContentResolver.OpenInputStream(uri))
using(var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
MessagingCenter.Send(Xamarin.Forms.Application.Current, "SelectFileResult",
new Tuple<byte[], string>(memoryStream.ToArray(), Utilities.GetFileName(ApplicationContext, uri)));
}
fileName = Utilities.GetFileName(ApplicationContext, uri);
}
else
{
// camera
var root = new Java.IO.File(global::Android.OS.Environment.ExternalStorageDirectory, "bitwarden");
var file = new Java.IO.File(root, "temp_camera_photo.jpg");
uri = global::Android.Net.Uri.FromFile(file);
fileName = $"photo_{DateTime.UtcNow.ToString("yyyyMMddHHmmss")}.jpg";
}
if(uri == null)
{
return;
}
using(var stream = ContentResolver.OpenInputStream(uri))
using(var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
MessagingCenter.Send(Xamarin.Forms.Application.Current, "SelectFileResult",
new Tuple<byte[], string>(memoryStream.ToArray(), fileName ?? "unknown_file_name"));
}
}
}

View File

@@ -5,6 +5,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

View File

@@ -7,14 +7,24 @@ using Plugin.CurrentActivity;
using System.IO;
using Android.Support.V4.Content;
using Bit.App;
using Bit.App.Resources;
using Android.Provider;
using System.Threading.Tasks;
using Android.OS;
using System.Collections.Generic;
using Android;
using Android.Content.PM;
using Android.Support.V4.App;
namespace Bit.Android.Services
{
public class DeviceActionService : IDeviceActionService
{
private readonly IAppSettingsService _appSettingsService;
private bool _cameraPermissionsDenied;
public DeviceActionService(IAppSettingsService appSettingsService)
public DeviceActionService(
IAppSettingsService appSettingsService)
{
_appSettingsService = appSettingsService;
}
@@ -124,12 +134,86 @@ namespace Bit.Android.Services
}
}
public void SelectFile()
public Task SelectFileAsync()
{
var intent = new Intent(Intent.ActionOpenDocument);
intent.AddCategory(Intent.CategoryOpenable);
intent.SetType("*/*");
CrossCurrentActivity.Current.Activity.StartActivityForResult(intent, Constants.SelectFileRequestCode);
MessagingCenter.Unsubscribe<Application>(Application.Current, "SelectFileCameraPermissionDenied");
var hasStorageWritePermission = !_cameraPermissionsDenied && HasPermission(Manifest.Permission.WriteExternalStorage);
var hasCameraPermission = !_cameraPermissionsDenied && HasPermission(Manifest.Permission.Camera);
if(!_cameraPermissionsDenied && !hasStorageWritePermission)
{
AskCameraPermission(Manifest.Permission.WriteExternalStorage);
return Task.FromResult(0);
}
if(!_cameraPermissionsDenied && !hasCameraPermission)
{
AskCameraPermission(Manifest.Permission.Camera);
return Task.FromResult(0);
}
var docIntent = new Intent(Intent.ActionOpenDocument);
docIntent.AddCategory(Intent.CategoryOpenable);
docIntent.SetType("*/*");
var chooserIntent = Intent.CreateChooser(docIntent, AppResources.FileSource);
if(!_cameraPermissionsDenied && hasCameraPermission && hasStorageWritePermission)
{
var root = new Java.IO.File(global::Android.OS.Environment.ExternalStorageDirectory, "bitwarden");
var file = new Java.IO.File(root, "temp_camera_photo.jpg");
if(!file.Exists())
{
var a = file.ParentFile.Mkdirs();
var b = file.CreateNewFile();
}
var outputFileUri = global::Android.Net.Uri.FromFile(file);
var additionalIntents = GetCameraIntents(outputFileUri);
chooserIntent.PutExtra(Intent.ExtraInitialIntents, additionalIntents.ToArray());
}
CrossCurrentActivity.Current.Activity.StartActivityForResult(chooserIntent, Constants.SelectFileRequestCode);
return Task.FromResult(0);
}
private List<IParcelable> GetCameraIntents(global::Android.Net.Uri outputUri)
{
var intents = new List<IParcelable>();
var pm = CrossCurrentActivity.Current.Activity.PackageManager;
var captureIntent = new Intent(MediaStore.ActionImageCapture);
var listCam = pm.QueryIntentActivities(captureIntent, 0);
foreach(var res in listCam)
{
var packageName = res.ActivityInfo.PackageName;
var intent = new Intent(captureIntent);
intent.SetComponent(new ComponentName(packageName, res.ActivityInfo.Name));
intent.SetPackage(packageName);
intent.PutExtra(MediaStore.ExtraOutput, outputUri);
intents.Add(intent);
}
return intents;
}
private bool HasPermission(string permission)
{
return ContextCompat.CheckSelfPermission(CrossCurrentActivity.Current.Activity, permission) == Permission.Granted;
}
private void AskCameraPermission(string permission)
{
MessagingCenter.Subscribe<Application>(Application.Current, "SelectFileCameraPermissionDenied", (sender) =>
{
_cameraPermissionsDenied = true;
});
AskPermission(permission);
}
private void AskPermission(string permission)
{
ActivityCompat.RequestPermissions(CrossCurrentActivity.Current.Activity, new string[] { permission },
Constants.SelectFilePermissionRequestCode);
}
}
}