I have an android application developed by Unity3D written by C# and I wan to hide the bottom bar when running my app. So I searched around and found that I need to use setSystemUiVisibility function from Java. Here is the code I found:
using UnityEngine;
public class DisableSystemUI
{
static AndroidJavaObject activityInstance;
static AndroidJavaObject windowInstance;
static AndroidJavaObject viewInstance;
public delegate void RunPtr();
public static void Run()
{
if (viewInstance != null) {
viewInstance.Call("setSystemUiVisibility", 2);
}
}
static DisableSystemUI()
{
if (Application.platform != RuntimePlatform.Android)
return;
DisableNavUI();
}
static void DisableNavUI()
{
if (Application.platform != RuntimePlatform.Android)
return;
using (AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
activityInstance = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");
windowInstance = activityInstance.Call<AndroidJavaObject>("getWindow");
viewInstance = windowInstance.Call<AndroidJavaObject>("getDecorView");
AndroidJavaRunnable RunThis;
RunThis = new AndroidJavaRunnable(new RunPtr(Run));
activityInstance.Call("runOnUiThread", RunThis);
}
}
}
I tried to call DisableSystemUI.Run(); in my main scene. I rooted my device but the app quits after I run it. Not sure what's wrong with it? Thanks for help.
it would be better to understand if you post the java code
i too had a same problem
try this
viewInstance.Call("setSystemUiVisibility", "SYSTEM_UI_FLAG_FULLSCREEN");
or this
viewInstance.Call("setSystemUiVisibility", "SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN");
should work....
Related
I am trying to use ads In my game . They are properly working in Unity but not in Android. Because of I am using unity 2018.4.25f1 personal so it's supporting older version of unity monetization asset. Maybe it's a problem but here is my code of Rewarded Video CSharp file
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Advertisements;
[RequireComponent(typeof(Button))]
public class RewardedVideo : MonoBehaviour, IUnityAdsListener
{
#if UNITY_IOS
private string gameId = "3853032";
#elif UNITY_ANDROID
private string gameId = "3853033";
#endif
[SerializeField]Button myButton;
[SerializeField]GameObject errorMessage;
public string myPlacementId = "rewardedVideo";
void Start()
{
// Map the ShowRewardedVideo function to the button’s click listener:
if (myButton)
myButton.onClick.AddListener(ShowRewardedVideo);
// Initialize the Ads listener and service:
Advertisement.AddListener(this);
Advertisement.Initialize(gameId, true);
}
public void okError()
{
errorMessage.SetActive(false);
}
// Implement a function for showing a rewarded video ad:
public void ShowRewardedVideo()
{
if(Advertisement.IsReady() == true)
Advertisement.Show(myPlacementId);
else
errorMessage.SetActive(true);
}
// Implement IUnityAdsListener interface methods:
public void OnUnityAdsReady(string placementId)
{
// If the ready Placement is rewarded, activate the button:
if (placementId == myPlacementId)
{
// myButton.interactable = true;
}
}
public void OnUnityAdsDidFinish(string placementId, ShowResult showResult)
{
// Define conditional logic for each ad completion status:
if (showResult == ShowResult.Finished)
{
int levels = PlayerPrefs.GetInt("unlockedLevel", 1);
if(levels != 5)
{
PlayerPrefs.SetInt("unlockedLevel", levels+1);
}
}
else if (showResult == ShowResult.Skipped)
{
// Do not reward the user for skipping the ad.
}
else if (showResult == ShowResult.Failed)
{
Debug.LogError("The ad did not finish due to an error");
}
}
public void OnUnityAdsDidError(string message)
{
// Log the error.
}
public void OnUnityAdsDidStart(string placementId)
{
// Optional actions to take when the end-users triggers an ad.
}
}
Downloaded asset from Assets store not from package manager. I saw Unity help, unity forum, stackoverflow but nothing solved my problem
Have you any suggestion?
I am gonna build Xamarin.Forms app which play music from url.
I used dependency service for each platform implementation.
[assembly: Dependency(typeof(AudioSerivce))]
namespace xxx.Droid
{
public class AudioSerivce : IAudio
{
int clicks = 0;
MediaPlayer player;
public AudioSerivce()
{
}
public bool Play_Pause (string url)
{
if (clicks == 0) {
this.player = new MediaPlayer();
this.player.SetDataSource(url);
this.player.SetAudioStreamType(Stream.Music);
this.player.PrepareAsync();
this.player.Prepared += (sender, args) =>
{
this.player.Start();
};
clicks++;
} else if (clicks % 2 != 0) {
this.player.Pause();
clicks++;
} else {
this.player.Start();
clicks++;
}
return true;
}
public bool Stop (bool val)
{
this.player.Stop();
clicks = 0;
return true;
}
}
}
and calling it
DependencyService.Get<IAudio>().Play_Pause("https://www.searchgurbani.com/audio/sggs/1.mp3");
If I check log, it seems everything is ok.
But I can't hear sound on android phone.
If anyone has some suggestion, please let me know.
Thanks
From:
https://forums.xamarin.com/discussion/64218/no-video-player-really
I suspect that there may be a problem related to an incompatibility between Octane Video player and Android Emulator, are you using a emulator/simulator?
Also another suggestion is to add this permissions:
INTERNET
WRITE_EXTERNAL_STORAGE
READ_EXTERNAL_STORAGE
To your Android app.
If that does not work try to use another url and compare if it working with other url's.
I have a number of functions on different scripts that I am trying to using in a win.cs
for example.
team.cs
PlayGame();
.
score.cs
UpdateScore();
I have some of the variable set to static, but not all of them, because it isn't needed (yet?)
I tried to put PlayGame(); and UpdateScore(); on the win.cs. This requires me to do a:
public static void UpdateScore(){}
now that this is static I have to go and make all the other vairables associated with the UpdateScore static and then the code breaks.
Is there a better way to do what I am doing?
I have tried using team.PlayGame() as the variable, but that requires the whole static thing too.
Sorry this is kind of hard to explain.
Note:All of the functions are public.
if Win.cs needs to call UpdateScore on Score.cs then you go as such:
public class Win : MonoBehaviour{
[SerializeField]private Score score = null;
private void Start(){
if(this.score == null){
this.score = this.gameObject.GetComponent<Score>();
}
}
// Then you can use this.score.UpdateScore when needed
}
It is possible to do the same action the other way around using event.
public class Win:MonoBehaviour{
public EventHandler<System.EventArg> RaiseUpdateScore;
protected void OnUpdateScore(EventArg args){
if(RaiseUpdateScore != null){
RaiseUpdateScore(this, args);
}
}
public void SomeAction(){
if(someCondition){
OnUpdateScore(null);
}
}
void OnDestroy(){ RaiseUpdateScore = null; }
}
then on Score.cs
public class Score:MonoBehaviour{
private Win win = null;
private void Start(){
this.win = this.gameObject.GetComponent<Win>();
this.win.RaiseUpdateScore += HandleUpdateScore;
}
private void HandleUpdateScore(object sender , System.EventArg args){}
private void OnDestroy(){
if(this.win != null){
this.win.RaiseUpdateScore -= HandleUpdateScore;
}
}
}
You can simply use Component.SendMessage to call a method of a script from another script.
Someting like this from win.cs script:
team teamScript = GameObject.Find("Object that team script is on that").GetComponent<team>();
teamScript.SendMessage("PlayGame", you parameter);
Update
While not the most elegant solution, one method that seems to work is to watch the relevant registry value. Here's an example using WMI to do this. I'd be happy to hear from anyone if there's a better solution than this.
using System;
using System.Management;
using System.Security.Principal;
using System.Windows.Forms;
using Microsoft.Win32;
public partial class MainForm : Form
{
public MainForm()
{
this.InitializeComponent();
this.UpdateModeFromRegistry();
var currentUser = WindowsIdentity.GetCurrent();
if (currentUser != null && currentUser.User != null)
{
var wqlEventQuery = new EventQuery(string.Format(#"SELECT * FROM RegistryValueChangeEvent WHERE Hive='HKEY_USERS' AND KeyPath='{0}\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ImmersiveShell' AND ValueName='TabletMode'", currentUser.User.Value));
var managementEventWatcher = new ManagementEventWatcher(wqlEventQuery);
managementEventWatcher.EventArrived += this.ManagementEventWatcher_EventArrived;
managementEventWatcher.Start();
}
}
private void ManagementEventWatcher_EventArrived(object sender, EventArrivedEventArgs e)
{
this.UpdateModeFromRegistry();
}
private void UpdateModeFromRegistry()
{
var tabletMode = (int)Registry.GetValue("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ImmersiveShell", "TabletMode", 0);
if (tabletMode == 1)
{
Console.Write(#"Tablet mode is enabled");
}
else
{
Console.Write(#"Tablet mode is disabled");
}
}
}
Original Question
I'm interested in make some optimizations in my Windows Forms application based on whether a user is in "Tablet Mode" (or not) using the new Windows 10 Continuum feature.
There is some guidance on how to do this in a UWP project at https://msdn.microsoft.com/en-us/library/windows/hardware/dn917883(v=vs.85).aspx (i.e. check the current view's UserInteractionMode to see if it's UserInteractionMode.Mouse or UserInteractionMode.Touch), however I'm not sure if or how I can do the same in Windows Forms.
Would there be any way I can call the necessary UWP APIs from my Windows Forms application, or is there some Windows Forms equivalent I can use?
To get whether the system is in tablet mode or not, query the system metric ConvertibleSlateMode like so (not tested, but it should work fine as far back as XP):
public static class TabletPCSupport
{
private static readonly int SM_CONVERTIBLESLATEMODE = 0x2003;
private static readonly int SM_TABLETPC = 0x56;
private static Boolean isTabletPC = false;
public static Boolean SupportsTabletMode { get { return isTabletPC; }}
public static Boolean IsTabletMode
{
get
{
return QueryTabletMode();
}
}
static TabletPCSupport ()
{
isTabletPC = (GetSystemMetrics(SM_TABLETPC) != 0);
}
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto, EntryPoint = "GetSystemMetrics")]
private static extern int GetSystemMetrics (int nIndex);
private static Boolean QueryTabletMode ()
{
int state = GetSystemMetrics(SM_CONVERTIBLESLATEMODE);
return (state == 0) && isTabletPC;
}
}
(Documentation here)
I have looked everywhere for how to tell if Windows 10 is in tablet mode and here is the simplest solution I found:
bool bIsTabletMode = false;
var uiMode = UIViewSettings.GetForCurrentView().UserInteractionMode;
if (uiMode == Windows.UI.ViewManagement.UserInteractionMode.Touch)
bIsTabletMode = true;
else
bIsTabletMode = false;
// (Could also compare with .Mouse instead of .Touch)
According to this article, you cant listen to WM_SETTINGCHANGE message. Here is a short c# sample :
protected override void WndProc(ref Message m)
{
const int WM_WININICHANGE = 0x001A,
WM_SETTINGCHANGE = WM_WININICHANGE;
if (m.Msg == WM_SETTINGCHANGE)
{
if (Marshal.PtrToStringUni(m.LParam) == "UserInteractionMode")
{
MessageBox.Show(Environment.OSVersion.VersionString);
}
}
base.WndProc(ref m);
}
For Windows 10 you should then perform some COM Interfacing with some WinRT stuff, to check if you are in UserInteractionMode.Mouse (desktop) or UserInteractionMode.Touch (tablet).
The Com Interop stuff looks rather tricky but it seems to be the only way if you are in a stock win32 app.
In my Microsoft Surface application I'd like to use voice capture. So I followed the tutorial metioned here (http://opensebj.blogspot.com/2009/04/naudio-tutorial-5-recording-audio.html) and modified the NAudio.dll to be able to execute the following code:
class AudioRecording
{
private WaveMixerStream32 mixer;
public AudioRecording()
{
mixer = new WaveMixerStream32();
mixer.AutoStop = false;
}
public void start()
{
Console.WriteLine("Start recording");
mixer.StreamMixToDisk("Test.wav");
mixer.StartStreamingToDisk();
}
public void stop()
{
Console.WriteLine("Stop recording");
mixer.StopStreamingToDisk();
}
}
But this doesn't really capture the sound. I just create a file of 58 bytes, that is empty. What Am I doing wrong?
Problem is sovled here:
http://naudio.codeplex.com/Thread/View.aspx?ThreadId=239825