static void TurnOnOld() { if (_camera != null) { Debug.LogWarning("Flashlight is already on"); return; } try { AGUtils.RunOnUiThread(() => { using (var camAJC = new AndroidJavaClass(C.AndroidHardwareCamera)) { var cam = camAJC.CallStaticAJO("open"); var camParams = cam.CallAJO("getParameters"); camParams.Call("setFlashMode", CameraParameters_FLASH_MODE_TORCH); cam.Call("setParameters", camParams); cam.Call("startPreview"); _camera = cam; } }); } catch (Exception e) { if (Debug.isDebugBuild) { Debug.Log("Could not enable flashlight:" + e.Message); } } }
/// <summary> /// Shows the multi item choice dialog. /// </summary> /// <returns>The multi item choice dialog.</returns> /// <param name="title">Title.</param> /// <param name="items">Items.</param> /// <param name="checkedItems">Checked items.</param> /// <param name="onItemClicked">On item clicked.</param> /// <param name="positiveButtonText">Positive button text.</param> /// <param name="onPositiveButtonClick">On positive button click.</param> /// <param name="theme">Dialog theme</param> public static void ShowMultiItemChoiceDialog(string title, string[] items, bool[] checkedItems, Action <int, bool> onItemClicked, string positiveButtonText, Action onPositiveButtonClick, AGDialogTheme theme = AGDialogTheme.Default) { if (AGUtils.IsNotAndroidCheck()) { return; } if (items == null) { throw new ArgumentNullException("items", "Items can't be null"); } if (checkedItems == null) { throw new ArgumentNullException("checkedItems", "Checked items can't be null"); } if (onItemClicked == null) { throw new ArgumentNullException("onItemClicked", "Item click callback can't be null"); } if (onPositiveButtonClick == null) { throw new ArgumentNullException("onPositiveButtonClick", "Button click callback can;t be null"); } AGUtils.RunOnUiThread(() => { var builder = CreateMultiChoiceDialogBuilder(title, items, checkedItems, onItemClicked).SetTheme(theme); builder.SetPositiveButton(positiveButtonText, onPositiveButtonClick); var dialog = builder.Create(); dialog.Show(); }); }
/// <summary> /// Displays message dialog with positive, negative buttons and neutral buttons /// </summary> /// <param name="title">Dialog title</param> /// <param name="message">Dialog message</param> /// <param name="positiveButtonText">Text for positive button</param> /// <param name="onPositiveButtonClick">Positive button callback</param> /// <param name="negativeButtonText">Text for negative button</param> /// <param name="onNegativeButtonClick">Negative button callback</param> /// <param name="neutralButtonText">Text for neutral button</param> /// <param name="onNeutralButtonClick">Neutral button callback</param> /// <param name="onDismiss">On dismiss callback</param> /// <param name="theme">Dialog theme</param> public static void ShowMessageDialog(string title, string message, string positiveButtonText, Action onPositiveButtonClick, string negativeButtonText, Action onNegativeButtonClick, string neutralButtonText, Action onNeutralButtonClick, Action onDismiss = null, AGDialogTheme theme = AGDialogTheme.Default) { if (AGUtils.IsNotAndroidCheck()) { return; } if (onPositiveButtonClick == null) { throw new ArgumentNullException("onPositiveButtonClick", "Button callback cannot be null"); } if (onNegativeButtonClick == null) { throw new ArgumentNullException("onNegativeButtonClick", "Button callback cannot be null"); } if (onNeutralButtonClick == null) { throw new ArgumentNullException("onNeutralButtonClick", "Button callback cannot be null"); } AGUtils.RunOnUiThread(() => { var builder = CreateMessageDialogBuilder(title, message, positiveButtonText, onPositiveButtonClick, onDismiss).SetTheme(theme); builder.SetNegativeButton(negativeButtonText, onNegativeButtonClick); builder.SetNeutralButton(neutralButtonText, onNeutralButtonClick); var dialog = builder.Create(); dialog.Show(); }); }
/// <summary> /// Shows the dialog on screen. /// </summary> public void Show() { if (AGUtils.IsNotAndroid()) { return; } AGUtils.RunOnUiThread(() => _dialog.Call("show")); }
/// <summary> /// Sets the progress of the dialog. Call this only on horizontal progress bar dialog /// </summary> /// <param name="value">Progress value.</param> public void SetProgress(int value) { if (AGUtils.IsNotAndroid()) { return; } AGUtils.RunOnUiThread(() => _dialog.Call("setProgress", value)); }
/// <summary> /// Dismisses the dialog. /// </summary> public void Dismiss() { if (AGUtils.IsNotAndroid()) { return; } AGUtils.RunOnUiThread(() => { _dialog.Call("dismiss"); _dialog.Dispose(); }); }
/// <summary> /// Shows the default Android time picker. /// </summary> /// <param name="hourOfDay">Hour of day.</param> /// <param name="minute">Minute. Not Zero-base as on Android!</param> /// <param name="onTimePicked">Time was picked callback.</param> /// <param name="onCancel">Dialog was cancelled callback.</param> /// <param name="theme">Dialog theme</param> /// <param name="is24HourFormat">If the picker is in 24 hour format</param> public static void ShowTimePicker(int hourOfDay, int minute, OnTimePicked onTimePicked, Action onCancel, AGDialogTheme theme = AGDialogTheme.Default, bool is24HourFormat = true) { if (AGUtils.IsNotAndroid()) { return; } AGUtils.RunOnUiThread(() => { var dialog = CreateBaseTimePicker(hourOfDay, minute, onTimePicked, onCancel, theme, is24HourFormat); AndroidDialogUtils.ShowWithImmersiveModeWorkaround(dialog); }); }
public static void RemoveUpdates() { if (AGUtils.IsNotAndroid()) { return; } if (_currentListener == null) { return; } AGUtils.RunOnUiThread(() => { AGSystemService.LocationService.Call("removeUpdates", _currentListener); }); }
static void TurnOffOld() { if (_camera == null) { return; } AGUtils.RunOnUiThread(() => { _camera.Call("stopPreview"); _camera.Call("release"); _camera.Dispose(); _camera = null; }); }
/// <summary> /// Shows the default Android date picker. /// </summary> /// <param name="year">Year.</param> /// <param name="month">Month.</param> /// <param name="day">Day.</param> /// <param name="onDatePicked">Date was picked callback.</param> /// <param name="onCancel">Dialog was cancelled callback.</param> /// <param name="theme">Dialog theme</param> public static void ShowDatePicker(int year, int month, int day, OnDatePicked onDatePicked, Action onCancel, AGDialogTheme theme = AGDialogTheme.Default) { if (AGUtils.IsNotAndroid()) { return; } AGUtils.RunOnUiThread(() => { var dialog = CreateDatePickerDialog(year, month, day, onDatePicked, onCancel, theme); AndroidDialogUtils.ShowWithImmersiveModeWorkaround(dialog); }); }
public static void HideStatusBar() { if (AGUtils.IsNotAndroid()) { return; } AGUtils.RunOnUiThread( () => { using (var window = AGUtils.Window) { window.Call("addFlags", SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } }); }
/// <summary> /// Takes the small photo. This thumbnail image might be good for an icon, but not a lot more. /// </summary> /// <param name="onSuccess">On success callback. Image is received as callback parameter</param> /// <param name="onCancel">On cancel callback.</param> public static void TakeSmallPhoto(Action <ImagePickResult> onSuccess, Action onCancel) { if (AGUtils.IsNotAndroidCheck()) { return; } if (onSuccess == null) { throw new ArgumentNullException("onSuccess", "Success callback cannot be null"); } var listener = new AGActivityUtils.OnPickPhotoListener(onSuccess, onCancel); AGUtils.RunOnUiThread(() => AGActivityUtils.TakePhotoSmall(listener)); }
/// <summary> /// Shows the chooser dialog to choose one item from the list. Dialog is dismissed on item click. /// </summary> /// <param name="title">Dialog title</param> /// <param name="items">Itmes to choose from</param> /// <param name="onClickCallback">Invoked on item click</param> /// <param name="theme">Dialog theme</param> public static void ShowChooserDialog(string title, string[] items, Action <int> onClickCallback, AGDialogTheme theme = AGDialogTheme.Default) { if (AGUtils.IsNotAndroidCheck()) { return; } AGUtils.RunOnUiThread(() => { var builder = new Builder().SetTitle(title).SetTheme(theme); builder.SetItems(items, onClickCallback); var dialog = builder.Create(); dialog.Show(); }); }
public static void RequestLocationUpdates(long minTime, float minDistance, Action <Location> onLocationChangedCallback) { if (AGUtils.IsNotAndroid()) { return; } if (minTime < 0) { throw new ArgumentOutOfRangeException("minTime", "Time cannot be less then zero"); } if (minDistance < 0) { throw new ArgumentOutOfRangeException("minDistance", "minDistance cannot be less then zero"); } if (onLocationChangedCallback == null) { throw new ArgumentNullException("onLocationChangedCallback", "Location changed callback cannot be null"); } if (!AGPermissions.IsPermissionGranted(AGPermissions.ACCESS_FINE_LOCATION)) { Debug.LogError(AGUtils.GetPermissionErrorMessage(AGPermissions.ACCESS_FINE_LOCATION)); return; } _currentListener = new LocationListenerProxy(onLocationChangedCallback); try { AGUtils.RunOnUiThread(() => AGSystemService.LocationService.Call("requestLocationUpdates", GPS_PROVIDER, minTime, minDistance, _currentListener)); } catch (Exception e) { if (Debug.isDebugBuild) { Debug.LogWarning( "Failed to register for location updates. Current device probably does not have GPS. Please check if device has GPS before invoking this method. " + e.Message); } } }
/// <summary> /// Shows the toast with specified text. /// </summary> /// <param name="text">Text to display on toast.</param> /// <param name="length">Duration to show.</param> public static void ShowToast(string text, ToastLength length = ToastLength.Short) { if (AGUtils.IsNotAndroidCheck()) { return; } AGUtils.RunOnUiThread(() => { using (var toast = new AndroidJavaClass(C.AndroidWidgetToast)) { var toastInstance = toast.CallStaticAJO("makeText", AGUtils.Activity, text, (int)length); toastInstance.Call("show"); } } ); }
public static void SetClipBoardText([NotNull] string label, [NotNull] string text) { if (label == null) { throw new ArgumentNullException("label"); } if (text == null) { throw new ArgumentNullException("text"); } AGUtils.RunOnUiThread(() => { var clip = C.AndroidContentClipData.AJCCallStaticOnceAJO("newPlainText", label, text); AGSystemService.ClipboardService.Call("setPrimaryClip", clip); }); }
/// <summary> /// Required permissions: /// <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> /// /// Launches the camera app to take a photo and returns resulting Texture2D in callback. The photo is also saved to the device gallery. /// /// IMPORTANT! : You don't need any permissions to use this method. It works using Android intent. /// </summary> /// <param name="onSuccess">On success callback. Image is received as callback parameter</param> /// <param name="onCancel">On cancel callback.</param> /// <param name="maxSize">Max image size. If provided image will be downscaled.</param> /// <param name="albumName">Album where photo will be stored.</param> public static void TakePhoto(Action <ImagePickResult> onSuccess, Action onCancel, ImageResultSize maxSize = ImageResultSize.Original, string albumName = DefaultAlbumName) { if (AGUtils.IsNotAndroidCheck()) { return; } if (onSuccess == null) { throw new ArgumentNullException("onSuccess", "Success callback cannot be null"); } var listener = new AGActivityUtils.OnPickPhotoListener(onSuccess, onCancel); AGUtils.RunOnUiThread(() => AGActivityUtils.TakePhotoBig(listener, maxSize, albumName)); }
/// <summary> /// Picks the image from gallery. /// </summary> /// <param name="onSuccess">On success callback. Image is received as callback parameter</param> /// <param name="onCancel">On cancel callback.</param> /// <param name="imageFormat">Image format.</param> /// <param name="maxSize">Max image size. If provided image will be downscaled.</param> public static void PickImageFromGallery(Action <ImagePickResult> onSuccess, Action onCancel, ImageFormat imageFormat = ImageFormat.PNG, ImageResultSize maxSize = ImageResultSize.Original) { if (AGUtils.IsNotAndroidCheck()) { return; } if (onSuccess == null) { throw new ArgumentNullException("onSuccess", "Success callback cannot be null"); } AGUtils.RunOnUiThread( () => AGActivityUtils.PickPhotoFromGallery( new AGActivityUtils.OnPickPhotoListener(onSuccess, onCancel), imageFormat, maxSize)); }
/// <summary> /// Required permissions: /// <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> /// /// Launches the camera app to take a photo and returns resulting Texture2D in callback. The photo is also saved to the device gallery. /// /// IMPORTANT! : You don't need any permissions to use this method. It works using Android intent. /// </summary> /// <param name="onSuccess">On success callback. Image is received as callback parameter</param> /// <param name="onError">On error/cancel callback.</param> /// <param name="maxSize">Max image size. If provided image will be downscaled.</param> /// <param name="shouldGenerateThumbnails">Whether thumbnail images will be generated. Used to show small previews of image.</param> public static void TakePhoto(Action <ImagePickResult> onSuccess, Action <string> onError, ImageResultSize maxSize = ImageResultSize.Original, bool shouldGenerateThumbnails = true) { if (AGUtils.IsNotAndroidCheck()) { return; } if (onSuccess == null) { throw new ArgumentNullException("onSuccess", "Success callback cannot be null"); } _onSuccessAction = onSuccess; _onCancelAction = onError; AGUtils.RunOnUiThread(() => AGActivityUtils.TakePhoto(maxSize, shouldGenerateThumbnails)); }
/// <summary> /// Shows the default Android time picker. /// </summary> /// <param name="hourOfDay">Hour of day.</param> /// <param name="minute">Minute. Not Zero-base as on Android!</param> /// <param name="onTimePicked">Time was picked callback.</param> /// <param name="onCancel">Dialog was cancelled callback.</param> /// <param name="theme">Dialog theme</param> public static void ShowTimePicker(int hourOfDay, int minute, OnTimePicked onTimePicked, Action onCancel, AGDialogTheme theme = AGDialogTheme.Default) { if (AGUtils.IsNotAndroidCheck()) { return; } AGUtils.RunOnUiThread(() => { var listener = new AGDateTimePicker.OnTimeSetListenerPoxy(onTimePicked); int themeResource = AndroidDialogUtils.GetDialogTheme(theme); var dialog = AndroidDialogUtils.IsDefault(themeResource) ? new AndroidJavaObject(TimePickerClass, AGUtils.Activity, listener, hourOfDay, minute, true) : new AndroidJavaObject(TimePickerClass, AGUtils.Activity, themeResource, listener, hourOfDay, minute, true); dialog.Call("setOnCancelListener", new DialogOnCancelListenerPoxy(onCancel)); dialog.Call("show"); }); }
/// <summary> /// Shows the default Android time picker. /// </summary> /// <param name="hourOfDay">Hour of day.</param> /// <param name="minute">Minute. Not Zero-base as on Android!</param> /// <param name="onTimePicked">Time was picked callback.</param> /// <param name="onCancel">Dialog was cancelled callback.</param> /// <param name="theme">Dialog theme</param> /// <param name="is24HourFormat">If the picker is in 24 hour format</param> public static void ShowTimePicker(int hourOfDay, int minute, OnTimePicked onTimePicked, Action onCancel, AGDialogTheme theme = AGDialogTheme.Default, bool is24HourFormat = true) { if (AGUtils.IsNotAndroidCheck()) { return; } AGUtils.RunOnUiThread(() => { var listener = new OnTimeSetListenerPoxy(onTimePicked); int themeResource = AndroidDialogUtils.GetDialogTheme(theme); var dialog = AndroidDialogUtils.IsDefault(themeResource) ? new AndroidJavaObject(TimePickerClass, AGUtils.Activity, listener, hourOfDay, minute, is24HourFormat) : new AndroidJavaObject(TimePickerClass, AGUtils.Activity, themeResource, listener, hourOfDay, minute, is24HourFormat); dialog.Call("setOnCancelListener", new DialogOnCancelListenerPoxy(onCancel)); AndroidDialogUtils.ShowWithImmersiveModeWorkaround(dialog); }); }
public static void ShowDatePickerWithLimits(int year, int month, int day, OnDatePicked onDatePicked, Action onCancel, DateTime minDate, DateTime maxDate, AGDialogTheme theme = AGDialogTheme.Default) { if (AGUtils.IsNotAndroid()) { return; } AGUtils.RunOnUiThread(() => { var dialog = CreateDatePickerDialog(year, month, day, onDatePicked, onCancel, theme); var picker = dialog.CallAJO("getDatePicker"); picker.Call("setMinDate", minDate.ToMillisSinceEpoch()); picker.Call("setMaxDate", maxDate.ToMillisSinceEpoch()); AndroidDialogUtils.ShowWithImmersiveModeWorkaround(dialog); }); }
// Enables Immersive Full-Screen Mode on Android device // Unity 5 has added immersive mode by default, so if your using Unity 5 or above, this method is redundant. public static void EnableImmersiveMode(bool sticky = true) { if (AGUtils.IsNotAndroidCheck()) { return; } GoodiesSceneHelper.IsInImmersiveMode = true; int mode = sticky ? ImmersiveFlagSticky : ImmersiveFlagNonSticky; AGUtils.RunOnUiThread( () => { using (var decorView = AGUtils.ActivityDecorView) { decorView.Call("setSystemUiVisibility", mode); } }); }
/// <summary> /// /// Turns on the camera flashlight if available /// /// Required permissions in manifest: /// <uses-permission android:name="android.permission.CAMERA" /> /// <uses-feature android:name="android.hardware.camera" /> /// /// <uses-permission android:name="android.permission.FLASHLIGHT"/> /// <uses-feature android:name="android.hardware.camera.flash" android:required="false" /> /// </summary> public static void Enable() { if (AGUtils.IsNotAndroidCheck()) { return; } if (!HasFlashlight()) { Debug.LogWarning("This device does not have a flashlight"); return; } if (_camera != null) { Debug.LogWarning("Flashlight is already on"); return; } try { AGUtils.RunOnUiThread(() => { using (var camAJC = new AndroidJavaClass(CameraClass)) { var cam = camAJC.CallStaticAJO("open"); var camParams = cam.CallAJO("getParameters"); camParams.Call("setFlashMode", CameraParameters_FLASH_MODE_TORCH); cam.Call("setParameters", camParams); cam.Call("startPreview"); _camera = cam; } }); } catch (Exception e) { if (Debug.isDebugBuild) { Debug.Log("Could not enable flashlight:" + e.Message); } } }
/// <summary> /// Turns off the camera flashlight /// </summary> public static void Disable() { if (AGUtils.IsNotAndroidCheck()) { return; } if (_camera == null) { return; } AGUtils.RunOnUiThread(() => { _camera.Call("stopPreview"); _camera.Call("release"); _camera.Dispose(); _camera = null; }); }
/// <summary> /// Shows the default Android date picker. /// </summary> /// <param name="year">Year.</param> /// <param name="month">Month.</param> /// <param name="day">Day.</param> /// <param name="onDatePicked">Date was picked callback.</param> /// <param name="onCancel">Dialog was cancelled callback.</param> /// <param name="theme">Dialog theme</param> public static void ShowDatePicker(int year, int month, int day, OnDatePicked onDatePicked, Action onCancel, AGDialogTheme theme = AGDialogTheme.Default) { if (AGUtils.IsNotAndroidCheck()) { return; } AGUtils.RunOnUiThread(() => { var listener = new AGDateTimePicker.OnDateSetListenerPoxy(onDatePicked); int themeResource = AndroidDialogUtils.GetDialogTheme(theme); // Month! (0-11 for compatibility with MONTH) var dialog = AndroidDialogUtils.IsDefault(themeResource) ? new AndroidJavaObject(DatePickerClass, AGUtils.Activity, listener, year, month - 1, day) : new AndroidJavaObject(DatePickerClass, AGUtils.Activity, themeResource, listener, year, month - 1, day); dialog.Call("setOnCancelListener", new DialogOnCancelListenerPoxy(onCancel)); dialog.Call("show"); }); }
/// <summary> /// Requests the required runtime permissions for your application. /// </summary> /// <param name="permissions">Permissions to request.</param> /// <param name="onRequestPermissionsResults">Callback with results.</param> public static void RequestPermissions(string[] permissions, Action <PermissionRequestResult[]> onRequestPermissionsResults) { if (permissions == null || permissions.Length == 0) { throw new ArgumentException("Requested permissions array must not be null or empty", "permissions"); } if (onRequestPermissionsResults == null) { throw new ArgumentNullException("onRequestPermissionsResults", "Listener cannot be null"); } if (AGUtils.IsNotAndroidCheck()) { return; } if (IsPriorToMarshmellow()) { return; } try { var listener = new OnRequestPermissionsResultsListener(onRequestPermissionsResults); AGUtils.RunOnUiThread(() => { AGActivityUtils.AndroidGoodiesActivityClass.CallStatic("prepareToRequestPermissions", listener, permissions); AGActivityUtils.StartAndroidGoodiesActivity(); }); } catch (Exception ex) { if (Debug.isDebugBuild) { Debug.LogWarning("Could not request runtime permissions. " + ex.Message); } } }
public static void ShareVideo(string videoPathOnDisc, string title, string chooserTitle = "Share Video") { if (AGUtils.IsNotAndroid()) { return; } if (!File.Exists(videoPathOnDisc)) { Debug.LogError("File (video) does not exist to share: " + videoPathOnDisc); return; } AGUtils.RunOnUiThread(() => AndroidPersistanceUtilsInternal.ScanFile(videoPathOnDisc, (path, uri) => { var intent = new AndroidIntent(AndroidIntent.ActionSend); intent.SetType("video/*"); intent.PutExtra(AndroidIntent.ExtraSubject, title); intent.PutExtra(AndroidIntent.ExtraStream, uri); AGUtils.StartActivityWithChooser(intent.AJO, chooserTitle); })); }
AGProgressDialog(Style style, string title, string message, AGDialogTheme theme, int maxValue = 100) { AGUtils.RunOnUiThread( () => { var d = CreateDialog(theme); d.Call("setProgressStyle", (int)style); d.Call("setCancelable", false); d.Call("setTitle", title); d.Call("setMessage", message); d.Call("setCancelable", false); if (style == Style.Spinner) { d.Call("setIndeterminate", true); } else { d.Call("setIndeterminate", false); d.Call("setProgress", 0); d.Call("setMax", maxValue); } _dialog = d; }); }
public static void ShowStatusBar(Color color = default(Color)) { if (AGUtils.IsNotAndroid()) { return; } AGUtils.RunOnUiThread( () => { using (var window = AGUtils.Window) { window.Call("clearFlags", SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); if (AGDeviceInfo.SDK_INT >= AGDeviceInfo.VersionCodes.LOLLIPOP) { window.Call("setStatusBarColor", color.ToAndroidColor()); } else if (color != default(Color)) { Debug.LogWarning("Changing the status bar color is not supported on Android API lower than Lollipop."); } } }); }