iBeacon Receiver and Vuforia Autofocus not work on an Android tablet [Unity3d] - android

I have two problems, about autofocus on Vuforia's AR-camera and iBeacon receiver. These are not work.
However, I see these problem just on an Android tablet(me173x).
I tried with 3 Android phones and iPhone5, 5s and 6+. No problem on them.
Development Environments are:
MacBookPro-Retina15-Early2012 (FullSpec)
OSX 10.10.4 (Latest)
Unity 5.1.1p2 (Latest), Professional (but no iOS-Pro and no Android-Pro)
Vuforia 4.2.3 (Latest)
I captured screenshot of terminal running 'pidcat --min-level w' (levels above warning), because so many logs.
No other logs above warning.
Error logs about linking of class for iBeacon found.
The tablet supports bluetooth 4.0 and BLE, and some camera apps support autofocus.
I guess... these problems due to the device architecture.
Please help me!
P.S.
thank you for your response, jacob.
my code to enable autofocus is:
using UnityEngine;
using Vuforia;
using System;
public class VuforiaARCameraAutoFocusMultiSelect : MonoBehaviour {
[SerializableAttribute]
public struct FocusModes {
public CameraDevice.FocusMode secondary;
public CameraDevice.FocusMode primary;
}
public FocusModes iOSFocusModes;
public FocusModes androidFocusModes;
public FocusModes defaultFocusModes;
void Start() {
var qcar = FindObjectOfType<QCARAbstractBehaviour>();
if (qcar != null) {
qcar.RegisterQCARStartedCallback(OnQCARStarted);
qcar.RegisterOnPauseCallback(OnQCARPaused);
Debug.Log("QCARBehaviour Found in current scene");
} else
Debug.LogError("Failed to find QCARBehaviour in current scene..");
}
/// <summary>
/// Raises the QCAR started event.
/// </summary>
private void OnQCARStarted() {
Debug.Log("OnQCARStarted");
SetFocusMode();
}
/// <summary>
/// Raises the QCAR paused event.
/// </summary>
/// <param name="paused">true: paused, false: resumed</param>
private void OnQCARPaused(bool paused) {
if (paused) {
Debug.Log("OnQCARPaused");
} else {
Debug.Log("OnQCARResumed");
SetFocusMode();
}
}
private void SetFocusMode() {
FocusModes modes;
#if UNITY_IOS
modes = iOSFocusModes;
#elif UNITY_ANDROID
modes = androidFocusModes;
#else
modes = defaultFocusModes;
#endif
if (CameraDevice.Instance.SetFocusMode(modes.primary))
Debug.LogFormat("Successfully enabled autofocus mode: {0}", modes.primary);
else if (CameraDevice.Instance.SetFocusMode(modes.secondary))
Debug.LogFormat("Successfully enabled autofocus mode: {0}", modes.secondary);
else
Debug.LogError("Couldn't enabled autofocus!!");
}
}
This code attached to the 'AR Camera' gameobject in the scene.

Related

Is it possible to generate an apk in Unity that works differently depending on whether it is Quest 2 or a phone? [duplicate]

How can I set the display to stereoscopic programmatically in Unity for an app deployed to an Android device?
I want a UI menu where the user can toggle between "VR mode" and normal mode. I do not want VR mode by default as it should be an option at run-time. I know there is a setting for "Virtual Reality Supported" in the build settings, but again, I do not want this enabled by default.
Include using UnityEngine.XR; at the top.
Call XRSettings.LoadDeviceByName("") with empty string followed by XRSettings.enabled = false; to disable VR in the start function to disable VR.
When you want to enable it later on, call XRSettings.LoadDeviceByName("daydream") with the VR name followed by XRSettings.enabled = true;.
You should wait for a frame between each function call. That requires this to be done a corutine function.
Also, On some VR devices, you must go to Edit->Project Settings->Player and make sure that Virtual Reality Supported check-box is checked(true) before this will work. Then you can disable it in the Start function and enable it whenever you want.
EDIT:
This is known to work on some VR devices and not all VR devices. Although, it should work on Daydream VR. Complete code sample:
IEnumerator LoadDevice(string newDevice, bool enable)
{
XRSettings.LoadDeviceByName(newDevice);
yield return null;
XRSettings.enabled = enable;
}
void EnableVR()
{
StartCoroutine(LoadDevice("daydream", true));
}
void DisableVR()
{
StartCoroutine(LoadDevice("", false));
}
Call EnableVR() to enable vr and DisableVR() to disable it. If you are using anything other than daydream, pass the name of that VR device to the LoadDevice function in the EnableVR() function.
For newer builds of Unity (e.g. 2019.4.0f1) you can use the XR Plugin Management package.
To enable call:
XRGeneralSettings.Instance.Manager.InitializeLoader();
To disable call:
XRGeneralSettings.Instance.Manager.DeinitializeLoader();
I'm using Unity 2021 but this probably works in earlier versions, I'm also using XR Plug-in Management.
Start:
XRGeneralSettings.Instance.Manager.StartSubsystems();
Stop:
XRGeneralSettings.Instance.Manager.StopSubsystems();
Full documentation at:
https://docs.unity3d.com/Packages/com.unity.xr.management#4.0/manual/EndUser.html
2020.3.14f1
Doesn't work for me, I get this error when running my Android app.
Call to DeinitializeLoader without an initialized manager.Please make
sure wait for initialization to complete before calling this API.
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
static void TryToDeinitializeOculusLoader()
{
XRGeneralSettings.Instance.Manager.DeinitializeLoader();
}
More context.
I try to unload the Oculus loader, before he manages to load the plugin.
I have an Android app, and the Oculus loader calls Application.Quit because the device is not an Oculus headset.
Waiting for XRGeneralSettings.Instance.Manager.isInitializationComplete takes too long.
Tried all RuntimeInitializeLoadType annotations.
OculusLoader.cs
#elif (UNITY_ANDROID && !UNITY_EDITOR)
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
static void RuntimeLoadOVRPlugin()
{
var supported = IsDeviceSupported();
if (supported == DeviceSupportedResult.ExitApplication)
{
Debug.LogError("\n\nExiting application:\n\nThis .apk was built with the Oculus XR Plugin loader enabled, but is attempting to run on a non-Oculus device.\nTo build for general Android devices, please disable the Oculus XR Plugin before building the Android player.\n\n\n");
Application.Quit();
}
if (supported != DeviceSupportedResult.Supported)
return;
try
{
if (!NativeMethods.LoadOVRPlugin(""))
Debug.LogError("Failed to load libOVRPlugin.so");
}
catch
{
// handle Android standalone build with Oculus XR Plugin installed but disabled in loader list.
}
}
#endif
SOLUTION
Made my build class extend IPreprocessBuildWithReport
public void OnPreprocessBuild(BuildReport report)
{
DisableXRLoaders(report);
}
///https://docs.unity3d.com/Packages/com.unity.xr.management#3.2/manual/EndUser.html
/// Do this as a setup step before you start a build, because the first thing that XR Plug-in Manager does at build time
/// is to serialize the loader list to the build target.
void DisableXRLoaders(BuildReport report)
{
XRGeneralSettingsPerBuildTarget buildTargetSettings;
EditorBuildSettings.TryGetConfigObject(XRGeneralSettings.k_SettingsKey, out buildTargetSettings);
if (buildTargetSettings == null)
{
return;
}
XRGeneralSettings settings = buildTargetSettings.SettingsForBuildTarget(report.summary.platformGroup);
if (settings == null)
{
return;
}
XRManagerSettings loaderManager = settings.AssignedSettings;
if (loaderManager == null)
{
return;
}
var loaders = loaderManager.activeLoaders;
// If there are no loaders present in the current manager instance, then the settings will not be included in the current build.
if (loaders.Count == 0)
{
return;
}
var loadersForRemoval = new List<XRLoader>();
loadersForRemoval.AddRange(loaders);
foreach (var loader in loadersForRemoval)
{
loaderManager.TryRemoveLoader(loader);
}
}
public void Awake() {
StartCoroutine(SwitchToVR(()=>{
Debug.Log("Switched to VR Mode");
}));
//For disable VR Mode
XRSettings.enabled = false;
}
IEnumerator SwitchToVR(Action callback) {
// Device names are lowercase, as returned by `XRSettings.supportedDevices`.
// Google original, makes you specify
// string desiredDevice = "daydream"; // Or "cardboard".
// XRSettings.LoadDeviceByName(desiredDevice);
// this is slightly better;
string[] Devices = new string[] { "daydream", "cardboard" };
XRSettings.LoadDeviceByName(Devices);
// Must wait one frame after calling `XRSettings.LoadDeviceByName()`.
yield return null;
// Now it's ok to enable VR mode.
XRSettings.enabled = true;
callback.Invoke();
}

How to change Vuforia AR camera focus mode?

I am using Vuforia 6.2 AR SDK for in Unity. But while I test the application in Android phone the camera seems like blurry. I searched in Vuforia's developer website and found some camera focus mode but I can't implement because that guideline was for older Vuforia SDK, I can't find the script they mentioned in their website. Here is their code sample but it's not working. I created different script and run this line on Start() function, but still not working.
CameraDevice.Instance.SetFocusMode(
CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
try this
void Start ()
{
VuforiaARController.Instance.RegisterVuforiaStartedCallback(OnVuforiaStarted);
VuforiaARController.Instance.RegisterOnPauseCallback(OnPaused);
}
private void OnVuforiaStarted()
{
CameraDevice.Instance.SetFocusMode(
CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
}
private void OnPaused(bool paused)
{
if (!paused) // resumed
{
// Set again autofocus mode when app is resumed
CameraDevice.Instance.SetFocusMode(
CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
}
}
This code is the right code.
bool cameramode = false;
public void OnCameraChangeMode()
{
Vuforia.CameraDevice.CameraDirection currentDir = Vuforia.CameraDevice.Instance.GetCameraDirection();
if (!cameramode) {
RestartCamera(Vuforia.CameraDevice.CameraDirection.CAMERA_FRONT);
camBtnTxt.text = "Back Camera";
} else {
RestartCamera(Vuforia.CameraDevice.CameraDirection.CAMERA_BACK);
camBtnTxt.text = "Front Camera";
}
}
private void RestartCamera(Vuforia.CameraDevice.CameraDirection newDir)
{
Vuforia.CameraDevice.Instance.Stop();
Vuforia.CameraDevice.Instance.Deinit();
Vuforia.CameraDevice.Instance.Init(newDir);
Vuforia.CameraDevice.Instance.Start();
}

Bug after Samsung update | Monogame | Detecting viewport.height as devices width

UPDATE
This issue have also been discussed in: https://github.com/mono/MonoGame/issues/2492
The problem is if the app is only allowed to run in Landscape orientation, not when you use Portrait or both.
Got a android game coded in monogame, where I got a GraphicsDeviceManager which are set to FullScreen=true.
I use the GraphicsDevice.Viewport.Height and the GraphicsDevice.Viewport.Width to determine the resolution of the device.
This was working very good until I got an samsung update and had to turn FastDev off.
The big mysterious problem:
When I debug with the pc, the height and width of the viewport is set correct. But when i unplug and play the app after 1-2 times the viewport.Height becomes the devices width, and the viewport.Width becomes the device height, which completely makes the game unplayable.
Its very hard to find the solution, since this is never happening when i debug and got the cable in from pc to the device.
Anyone got any ideas what it can be?
I can now confirm that it is because of the samsung update
I made worlds simplest android app to test it, just got a mainframe with a background image called "bg" and a spritefront printing out the viewport.Width and viewport.Height.
Here's the code:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace TestRes
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont font;
Rectangle _mainFrame;
Texture2D _background;
string text;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.IsFullScreen = true;
//graphics.PreferredBackBufferWidth = 800;
// graphics.PreferredBackBufferHeight = 480;
graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft;
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting
/// This is where it can query for any required services and load any non-
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
text = "";
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
_background = Content.Load<Texture2D>("Bilder/bg");
_mainFrame = new Rectangle(0, 0, this.GraphicsDevice.Viewport.Width, this.GraphicsDevice.Viewport.Height);
// TODO: use this.Content to load your game content here
font = Content.Load<SpriteFont>("spriteFont1");
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
{
Exit();
}
text = "ScreenWidth: " + this.GraphicsDevice.Viewport.Width + ", screenheight: " + this.GraphicsDevice.Viewport.Height;
// TODO: Add your update logic here
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(_background, _mainFrame, Color.White);
spriteBatch.DrawString(font, text, new Vector2(16, 1000), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
When deploying from VS everything is good, the viewport.width is the actual device width and the viewport.height is the actual device height. But when trying to deploy it from the Samsung Galaxy S4 active (sometimes you need to try 2-3 times) then all of a sudden Viewport.Height is the device Width and the other way around, which makes the background picture just cover a bit of the screen.
Have taken pictures to show it:
Checked in version 3.6 , and the bug is fixed.

Android test if front camera supports flash

I know is possible to detect if camera has flash integrated, using a method like this:
/**
* #return true if a flash is available, false if not
*/
public static boolean isFlashAvailable(Context context) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
}
but if the device has 2 cameras how can I test for each of them if has flash available?
For example on a Samsung S2 device, on native camera application when using the front camera the flash button is disabled, meaning is not available.
Thanks.
Paul's answer didn't work for me.
The front camera on a Galaxy Nexus has a valid flash-mode of FLASH_MODE_OFF, but it is the only supported option. This method will work in all situations:
private boolean hasFlash(){
Parameters params = mCamera.getParameters();
List<String> flashModes = params.getSupportedFlashModes();
if(flashModes == null) {
return false;
}
for(String flashMode : flashModes) {
if(Parameters.FLASH_MODE_ON.equals(flashMode)) {
return true;
}
}
return false;
}
If your app supports more than just FLASH_MODE_OFF and FLASH_MODE_ON, you'll need to tweak the if-check inside the loop.
-- Update --
Also you can add torch for flash in if condition if you really need to use torch.
if (Camera.Parameters.FLASH_MODE_ON.equals(flashMode) || Camera.Parameters.FLASH_MODE_TORCH.equals(flashMode)) {
I figured this by myself and I post here the solution, which is actually very simple:
/**
* Check if Hardware Device Camera can use Flash
* #return true if can use flash, false otherwise
*/
public static boolean hasCameraFlash(Camera camera) {
Camera.Parameters p = camera.getParameters();
return p.getFlashMode() == null ? false : true;
}
The above method is different by this one:
/**
* Checking availability of flash in device.
* Obs.: If device has 2 cameras, this method doesn't ensure both cameras can use flash.
* #return true if a flash is available in device, false if not
*/
public static boolean isFlashAvailable(Context context) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
}

Camera.Parameters.FLASH_MODE_TORCH replacement for Android 2.1

I am trying to write an app that requires the LED flash to go into torch mode. The problem is, Android 2.1 does not support this mode and therefore I cannot support the platform yet. Wouldn't be an issue, but I am writing it for my fiance and her Epic 4G only has 2.1 right now. I found some code samples that use some undocumented API calls and therefore work on the Motorola Droid and such, but they do not work on the Epic. Does anyone have some suggestions on where to look to find code that should help me get this working?
I'm finding that torch mode is generally working fine on 2.1 but I had the same problem with the Samsung Epic and found a hack around it.
Looking at the params returned by Camera.getParameters() when run on the Samsung Epic, I noticed that the flash-modes it claims to support are: flash-mode-values=off,on,auto;
torch-mode is not listed, implying it's not supported.
However, I found that this model would still accept that mode and WOULD turn the LED on! The bad news was that when later setting the flash-mode back to auto or off left the LED still lit! It will not turn off until you call Camera.release().
I guess that's why Samsung dont include it in the list of supported!?!
So...the method I use to toggle torch in a CameraHelper class is...
/***
* Attempts to set camera flash torch/flashlight mode on/off
* #param isOn true = on, false = off
* #return boolean whether or not we were able to set it
*/
public boolean setFlashlight(boolean isOn)
{
if (mCamera == null)
{
return false;
}
Camera.Parameters params = mCamera.getParameters();
String value;
if (isOn) // we are being ask to turn it on
{
value = Camera.Parameters.FLASH_MODE_TORCH;
}
else // we are being asked to turn it off
{
value = Camera.Parameters.FLASH_MODE_AUTO;
}
try{
params.setFlashMode(value);
mCamera.setParameters(params);
String nowMode = mCamera.getParameters().getFlashMode();
if (isOn && nowMode.equals(Camera.Parameters.FLASH_MODE_TORCH))
{
return true;
}
if (! isOn && nowMode.equals(Camera.Parameters.FLASH_MODE_AUTO))
{
return true;
}
return false;
}
catch (Exception ex)
{
MyLog.e(mLOG_TAG, this.getClass().getSimpleName() + " error setting flash mode to: "+ value + " " + ex.toString());
}
}
The activities that use this call it as follows...
private void toggleFlashLight()
{
mIsFlashlightOn = ! mIsFlashlightOn;
/**
* hack to fix an issue where the Samsung Galaxy will turn torch on,
* even though it says it doesnt support torch mode,
* but then will NOT turn it off via this param.
*/
if (! mIsFlashlightOn && Build.MANUFACTURER.equalsIgnoreCase("Samsung"))
{
this.releaseCameraResources();
this.initCamera();
}
else
{
boolean result = mCamHelper.setFlashlight(mIsFlashlightOn);
if (! result)
{
alertFlashlightNotSupported();
}
}
}
The magic that makes this work in releaseCameraResources() is that it calls Camera.release()....and then I have to reinitialize all my camera stuff for Samsung devices.
Not pretty but seems to be working for plenty of users.
Note that I do have a report of torch mode not working at all with this code on Nexus one but have been able to dig into it. It definitely works on HTC EVO and Samsung Epic.
Hope this helps.
In my case for Samsung devices I needed to set focus mode to infinity and it started to work
params.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
mCamera.setParameters(params);
mCamera.startPreview();

Categories

Resources