diff --git a/src/Android/Properties/AndroidManifest.xml b/src/Android/Properties/AndroidManifest.xml
index 1c9f45819..8fd7e6da3 100644
--- a/src/Android/Properties/AndroidManifest.xml
+++ b/src/Android/Properties/AndroidManifest.xml
@@ -13,6 +13,9 @@
+
+
+
(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 additionalIntents = new List();
+ if(Forms.Context.PackageManager.HasSystemFeature(PackageManager.FeatureCamera))
+ {
+ 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);
+ }
+
+ if(!_cameraPermissionsDenied && hasCameraPermission && hasStorageWritePermission)
+ {
+ try
+ {
+ 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())
+ {
+ file.ParentFile.Mkdirs();
+ file.CreateNewFile();
+ }
+ var outputFileUri = global::Android.Net.Uri.FromFile(file);
+ additionalIntents.AddRange(GetCameraIntents(outputFileUri));
+ }
+ catch(Java.IO.IOException) { }
+ }
+ }
var docIntent = new Intent(Intent.ActionOpenDocument);
docIntent.AddCategory(Intent.CategoryOpenable);
docIntent.SetType("*/*");
var chooserIntent = Intent.CreateChooser(docIntent, AppResources.FileSource);
-
- if(!_cameraPermissionsDenied && hasCameraPermission && hasStorageWritePermission)
- {
- try
- {
- 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())
- {
- file.ParentFile.Mkdirs();
- file.CreateNewFile();
- }
- var outputFileUri = global::Android.Net.Uri.FromFile(file);
- additionalIntents.AddRange(GetCameraIntents(outputFileUri));
- }
- catch(Java.IO.IOException) { }
- }
-
if(additionalIntents.Count > 0)
{
chooserIntent.PutExtra(Intent.ExtraInitialIntents, additionalIntents.ToArray());
diff --git a/src/Android/Services/DeviceInfoService.cs b/src/Android/Services/DeviceInfoService.cs
index e6514a8b6..222df7b2c 100644
--- a/src/Android/Services/DeviceInfoService.cs
+++ b/src/Android/Services/DeviceInfoService.cs
@@ -1,4 +1,5 @@
using Android.App;
+using Android.Content.PM;
using Android.OS;
using Bit.App.Abstractions;
@@ -42,5 +43,6 @@ namespace Bit.Android.Services
}
}
public bool NfcEnabled => Utilities.NfcEnabled();
+ public bool HasCamera => Xamarin.Forms.Forms.Context.PackageManager.HasSystemFeature(PackageManager.FeatureCamera);
}
}
diff --git a/src/App/Abstractions/Services/IDeviceInfoService.cs b/src/App/Abstractions/Services/IDeviceInfoService.cs
index 4e87274b6..706a4cda1 100644
--- a/src/App/Abstractions/Services/IDeviceInfoService.cs
+++ b/src/App/Abstractions/Services/IDeviceInfoService.cs
@@ -6,5 +6,6 @@
int Version { get; }
float Scale { get; }
bool NfcEnabled { get; }
+ bool HasCamera { get; }
}
}
diff --git a/src/App/Pages/Vault/VaultAddLoginPage.cs b/src/App/Pages/Vault/VaultAddLoginPage.cs
index be92cf2a2..3b51c5ccc 100644
--- a/src/App/Pages/Vault/VaultAddLoginPage.cs
+++ b/src/App/Pages/Vault/VaultAddLoginPage.cs
@@ -25,6 +25,7 @@ namespace Bit.App.Pages
private readonly IGoogleAnalyticsService _googleAnalyticsService;
private readonly ISettings _settings;
private readonly IAppInfoService _appInfoService;
+ private readonly IDeviceInfoService _deviceInfo;
private readonly string _defaultUri;
private readonly string _defaultName;
private readonly bool _fromAutofill;
@@ -43,6 +44,7 @@ namespace Bit.App.Pages
_googleAnalyticsService = Resolver.Resolve();
_settings = Resolver.Resolve();
_appInfoService = Resolver.Resolve();
+ _deviceInfo = Resolver.Resolve();
Init();
}
@@ -61,8 +63,11 @@ namespace Bit.App.Pages
NotesCell = new FormEditorCell(height: 180);
TotpCell = new FormEntryCell(AppResources.AuthenticatorKey, nextElement: NotesCell.Editor,
- useButton: true);
- TotpCell.Button.Image = "camera";
+ useButton: _deviceInfo.HasCamera);
+ if(_deviceInfo.HasCamera)
+ {
+ TotpCell.Button.Image = "camera";
+ }
TotpCell.Entry.DisableAutocapitalize = true;
TotpCell.Entry.Autocorrect = false;
TotpCell.Entry.FontFamily = Helpers.OnPlatform(iOS: "Courier", Android: "monospace", WinPhone: "Courier");
@@ -142,7 +147,12 @@ namespace Bit.App.Pages
}
else if(Device.RuntimePlatform == Device.Android)
{
- PasswordCell.Button.WidthRequest = TotpCell.Button.WidthRequest = 40;
+ PasswordCell.Button.WidthRequest = 40;
+
+ if(TotpCell.Button != null)
+ {
+ TotpCell.Button.WidthRequest = 40;
+ }
}
var saveToolBarItem = new ToolbarItem(AppResources.Save, null, async () =>
@@ -234,7 +244,10 @@ namespace Bit.App.Pages
TotpCell.InitEvents();
FolderCell.InitEvents();
PasswordCell.Button.Clicked += PasswordButton_Clicked;
- TotpCell.Button.Clicked += TotpButton_Clicked;
+ if(TotpCell?.Button != null)
+ {
+ TotpCell.Button.Clicked += TotpButton_Clicked;
+ }
GenerateCell.Tapped += GenerateCell_Tapped;
if(!_fromAutofill && !_settings.GetValueOrDefault(AddedLoginAlertKey, false))
@@ -266,7 +279,10 @@ namespace Bit.App.Pages
TotpCell.Dispose();
FolderCell.Dispose();
PasswordCell.Button.Clicked -= PasswordButton_Clicked;
- TotpCell.Button.Clicked -= TotpButton_Clicked;
+ if(TotpCell?.Button != null)
+ {
+ TotpCell.Button.Clicked -= TotpButton_Clicked;
+ }
GenerateCell.Tapped -= GenerateCell_Tapped;
}
diff --git a/src/App/Pages/Vault/VaultEditLoginPage.cs b/src/App/Pages/Vault/VaultEditLoginPage.cs
index f70dc3891..aa7a0f30f 100644
--- a/src/App/Pages/Vault/VaultEditLoginPage.cs
+++ b/src/App/Pages/Vault/VaultEditLoginPage.cs
@@ -19,6 +19,7 @@ namespace Bit.App.Pages
private readonly IFolderService _folderService;
private readonly IUserDialogs _userDialogs;
private readonly IConnectivity _connectivity;
+ private readonly IDeviceInfoService _deviceInfo;
private readonly IGoogleAnalyticsService _googleAnalyticsService;
private DateTime? _lastAction;
@@ -29,6 +30,7 @@ namespace Bit.App.Pages
_folderService = Resolver.Resolve();
_userDialogs = Resolver.Resolve();
_connectivity = Resolver.Resolve();
+ _deviceInfo = Resolver.Resolve();
_googleAnalyticsService = Resolver.Resolve();
Init();
@@ -58,9 +60,12 @@ namespace Bit.App.Pages
NotesCell.Editor.Text = login.Notes?.Decrypt(login.OrganizationId);
TotpCell = new FormEntryCell(AppResources.AuthenticatorKey, nextElement: NotesCell.Editor,
- useButton: true);
+ useButton: _deviceInfo.HasCamera);
+ if(_deviceInfo.HasCamera)
+ {
+ TotpCell.Button.Image = "camera";
+ }
TotpCell.Entry.Text = login.Totp?.Decrypt(login.OrganizationId);
- TotpCell.Button.Image = "camera";
TotpCell.Entry.DisableAutocapitalize = true;
TotpCell.Entry.Autocorrect = false;
TotpCell.Entry.FontFamily = Helpers.OnPlatform(iOS: "Courier", Android: "monospace", WinPhone: "Courier");
@@ -161,7 +166,12 @@ namespace Bit.App.Pages
}
else if(Device.RuntimePlatform == Device.Android)
{
- PasswordCell.Button.WidthRequest = TotpCell.Button.WidthRequest = 40;
+ PasswordCell.Button.WidthRequest = 40;
+
+ if(TotpCell.Button != null)
+ {
+ TotpCell.Button.WidthRequest = 40;
+ }
}
var saveToolBarItem = new ToolbarItem(AppResources.Save, null, async () =>
diff --git a/src/iOS.Core/Services/DeviceInfoService.cs b/src/iOS.Core/Services/DeviceInfoService.cs
index 60b0cafa4..e6dc774bc 100644
--- a/src/iOS.Core/Services/DeviceInfoService.cs
+++ b/src/iOS.Core/Services/DeviceInfoService.cs
@@ -23,5 +23,6 @@ namespace Bit.iOS.Core.Services
}
public float Scale => (float)UIScreen.MainScreen.Scale;
public bool NfcEnabled => false;
+ public bool HasCamera => true;
}
}