Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Xperia Play Keypad issues

Discussion in 'Android' started by jashan, Apr 13, 2011.

  1. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    View attachment 19448 I thought I'd best post this as a separate thread. This is a follow up to Xperia Play Keycodes in Unity?

    colargol and I found out that there's a really nasty issue going on with the Xperia Play and its great PS-style slide out keypad:

    It's the same "device", same Google Android version - but different firmwares for different locations - behaving differently without warning. So, while the code example for determining whether the user has the keypad slid out in Xperia™ PLAY tutorial – Angry Mob Games’ optimisation tips using Unity’s tool chain works fine on some devices, it doesn't on others. In particular, that code will make the keypad appear to be available on a Google Nexus One (which doesn't even have a slide-out keypad at all), and probably other devices as well.

    It worked for colargol and didn't work for me, so we compared firmware versions, and I have 3.0.A.2.179 (EDIT: Actually, I've had 3.0.A.181 all along; not sure where this 179 was coming from) while he has 3.0.E.2.52. This appears to be different "releases" but it's actually firmwares for different locations. And while you have to use navigationHidden on the ".E." devices, you have to use hardKeyboardHidden on ".A." devices (and devices like the Google Nexus One). That much about "device fragmentation on Android" (what a mess!!!)

    We've come up with some simple code that should give proper results on all Android devices - and it would be great if people could test this with different devices and different firmwares to make sure it *really* does the trick. I've attached a test project - feel free to use this and please report your results in this thread to help everyone benefit from those tests. Here's the interesting code snippet (see the test project for details and context):

    Code (csharp):
    1. nav = currentConfig.Get<int>("hardKeyboardHidden");
    2. if (SystemInfo.operatingSystem.Contains(".E.")
    3.      (iPhoneSettings.model.Contains("R800") || iPhoneSettings.model.Contains("Z1i"))) {
    4.     // override with navigationHidden because Sony Ericsson tried to be really really funny and
    5.     // uses hardKeyboardHidden on some devices and navigationHidden on others
    6.     nav = currentConfig.Get<int>("navigationHidden");
    7. }
    8. if (nav == NAVIGATIONHIDDEN_YES || nav == NAVIGATIONHIDDEN_UNDEFINED) {
    9.     keypadAvailable = false;
    10. } else {
    11.     keypadAvailable = true;
    12. }
     

    Attached Files:

    Last edited: Apr 18, 2011
  2. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    My results so far (EDIT: I've now added Configuration.navigation to the output; this is done with XperiaPlayKeypadTestV3.zip that I have just uploaded):

    Sony Ericsson R800i, Android OS 2.3.2 (3.0.A.2.181)
    Works correctly (both states are correctly shown, available/hidden), using hack: false (nav=2)

    HTC Nexus One, Android OS 2.2 (FRG33)
    Works correctly (keypad always hidden since there is no keypad), using hack: false (nav=3)

    HTC Nexus One, Android OS 2.3.3 (GRI40)
    Works correctly (keypad always hidden since there is no keypad), using hack: false (nav=3)
     
    Last edited: Apr 18, 2011
  3. Enzign

    Enzign

    Joined:
    Aug 20, 2010
    Posts:
    169
    Awsome. Thnx for the code. I will try this on my HTC Desire. Would be great to have native support for Xperia Play.
    Btw, will i have to always use NativeActivity for Xperia Play to work.
     
    Last edited: Apr 15, 2011
  4. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    Well, the Xperia Play is fully supported by Unity - it's just the status of the keypad you need to figure out this way.

    Only for the second touchpad to work.
     
  5. colargol

    colargol

    Joined:
    Mar 31, 2010
    Posts:
    65
    Only if you want to use Xperia Play Touchpad.
    If you want it to have in one build compatible with < 2.3 devices, this is temporary solution for one build.

    It starts NativeActivity only on 2.3 and higher devices.
    "Use NativeActivity" should be false in Unity PlayerSettings.
    It should be build similar to e.g. Ad-Mob plug-in in yours Plugins/Android directory.

    UnityPlayerActivityEx.java
    Code (csharp):
    1.  
    2. package com.unity3d.player;
    3.  
    4. import android.os.Bundle;
    5. import android.util.Log;
    6. import android.app.Activity;
    7. import android.content.Intent;
    8. import android.os.Build;
    9.  
    10. public class UnityPlayerActivityEx extends Activity
    11. {
    12.     protected void onCreate(Bundle savedInstanceState)
    13.     {      
    14.         // super (UnityPlayerActivity) will use setContentView() ...
    15.         super.onCreate(savedInstanceState);
    16.        
    17.         Intent intent = new Intent(Intent.ACTION_MAIN);
    18.        
    19.         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD)
    20.         {
    21.             intent.setClassName(this, "com.unity3d.player.UnityPlayerActivity");           
    22.         }
    23.         else
    24.         {
    25.             intent.setClassName(this, "com.unity3d.player.UnityPlayerNativeActivity"); 
    26.         }
    27.         this.startActivity(intent);
    28.  
    29.         finish();
    30.     }
    31. }
    AndroidManifest.xml
    Code (csharp):
    1.  
    2. <?xml version="1.0" encoding="utf-8"?>
    3. <manifest
    4.     xmlns:android="http://schemas.android.com/apk/res/android"
    5.     package="com.unity3d.player"
    6.     android:installLocation="preferExternal"
    7.     android:versionCode="1"
    8.     android:versionName="1.0">
    9.     <supports-screens
    10.         android:smallScreens="true"
    11.         android:normalScreens="true"
    12.         android:largeScreens="true"
    13.         android:xlargeScreens="true"
    14.         android:anyDensity="true"/>
    15.  
    16.     <application
    17.         android:icon="@drawable/app_icon"
    18.         android:label="@string/app_name"
    19.         android:debuggable="true">
    20.         <activity android:name="com.unity3d.player.UnityPlayerActivityEx"
    21.                   android:label="@string/app_name"
    22.                   android:configChanges="keyboardHidden|orientation">
    23.             <intent-filter>
    24.                 <action android:name="android.intent.action.MAIN" />
    25.                 <category android:name="android.intent.category.LAUNCHER" />
    26.             </intent-filter>
    27.         </activity>
    28.  
    29.         <activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="@string/app_name" android:configChanges="keyboardHidden|orientation" android:screenOrientation="landscape">
    30.             <meta-data android:name="android.app.lib_name" android:value="unity" />
    31.     </activity>
    32.  
    33.     <activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="@string/app_name" android:configChanges="keyboardHidden|orientation" android:screenOrientation="landscape">
    34.     </activity>
    35.  
    36.         <activity android:name="com.unity3d.player.VideoPlayer"
    37.                   android:label="@string/app_name"
    38.                   android:configChanges="keyboardHidden|orientation">
    39.         </activity>
    40.  
    41.     </application>
    42.  
    43. </manifest>
     
  6. aaronthom

    aaronthom

    Joined:
    Jun 14, 2011
    Posts:
    2
    i dont find any issues with my play keypad even after utilizing it for as much as 6 mnths and i dnt feel keypad is goin to create issues on a long run but it mainly depends for what you are utilizing your play like i am crazily playing N.O.V.A non stop on my play and i'll appreciate xperia for such a wonderful gaming instrument coz recently i bought 1 and i m getting much and much addicted to it. Keeping in the mind that sony ericsson xperia play is basically a gaming phone, obviously it has high specs like 4 inch high video display screen specially built for high resolution gaming and video watching with a soft and very attractive gaming keypad same as that found on psp (so my point is to say keypad issues have been jst hyped ...) but rather considering it as only a gaming instrument with speedy scorpion processor i would say it has a lot of features of that of other android phones so bingo :) gaming(instrument) and phone togather that makes it a gaming phone...
     
  7. Jirka United

    Jirka United

    Joined:
    Mar 15, 2011
    Posts:
    2
    Hi Colargol,
    I'm trying to create one build for both Xperia and regular androids, just like you did in Air Attack HD. I'm using your exemple above, however I'm getting error at application startup:

    E AndroidRuntime: java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.unity3d.player/com.unity3d.player.UnityPlayerActivityEx}: java.lang.ClassNotFoundException: com.unity3d.player.UnityPlayerActivityEx in loader dalvik.system.PathClassLoader[/data/app/com.unity3d.player-1.apk]

    Renamed package in java file, playersettings and manifest to be the same, but no success. Could you list what essential steps are needed, beside creating java file and manifest?

    Thanks in advance
    Jirka
     
  8. Be-Rad

    Be-Rad

    Joined:
    Feb 5, 2009
    Posts:
    34
    Thanks for the code, Jashan.

    My Xperia Play came directly from Sony Ericson and had a different string for the "operating system" so I had to rip out this part from the if statement:
    Works great, but I only have an Xperia Play and Nexus One so I haven't tested on other devices.
     
  9. FenixFire

    FenixFire

    Joined:
    Aug 17, 2011
    Posts:
    4
    We tried something similar but found that some devices thought they were the Xperia Play. Therefore, we went really strict with our Xperia Play device detection and have had 0 bugs so far with this:

    public void Awake()
    {
    if(SystemInfo.deviceModel.Contains("Sony Ericsson") SystemInfo.deviceModel.Contains("R800") || SystemInfo.deviceModel.Contains("Z1i"))
    {
    PlayerPrefs.SetInt("SonyEricssonDevice", 1);
    SonyEricssonDevice = 1;
    }
    else
    {
    PlayerPrefs.SetInt("SonyEricssonDevice", 0);
    SonyEricssonDevice = 0;
    }
    }

    public void Update()
    {
    //XPERIA PLAY INPUT
    if(SonyEricssonDevice == 1)
    {
    nav = currentConfig.Get<int>("navigationHidden");
    }
    else
    {
    return;
    }

    if (nav == NAVIGATIONHIDDEN_NO)
    {
    KeypadVisible = 1;
    }
    else if(nav == NAVIGATIONHIDDEN_YES)
    {
    KeypadVisible = 0;
    }
    else if(nav == NAVIGATIONHIDDEN_UNDEFINED)
    {
    KeypadVisible = 0;
    }
    else
    {
    KeypadVisible = 0;
    }
    }
     
  10. viktors

    viktors

    Joined:
    Nov 7, 2011
    Posts:
    6
    Do you still need to use that temp fix colargol posted when using Unity 3.4.2? It seems like Unity handles that part it self now or am I wrong?
    Is there any other changes to this code in Unity 3.4.2? It's seems that some Xperia PLAY phones doesn't get "the lid is open" when using the code below:


    Code (csharp):
    1.  
    2. private AndroidJavaObject currentConfig = null;
    3.  
    4. public void Start () {
    5.     using (AndroidJavaClass player = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {
    6.         AndroidJavaObject activity = player.GetStatic<AndroidJavaObject>("currentActivity");
    7.         currentConfig = activity.Call<AndroidJavaObject>("getResources").Call<AndroidJavaObject>("getConfiguration");
    8.     }
    9. }
    10.  
    11. bool IsNavigationVisible()
    12. {
    13.     const int NAVIGATIONHIDDEN_NO = 1;
    14.        
    15.     int nav = currentConfig.Get<int>("hardKeyboardHidden");
    16.     if (SystemInfo.operatingSystem.Contains(".E.")
    17.          (SystemInfo.deviceModel.Contains("R800") || SystemInfo.deviceModel.Contains("Z1i")))
    18.     {
    19.         nav = currentConfig.Get<int>("navigationHidden");
    20.     }
    21.  
    22.     return (nav == NAVIGATIONHIDDEN_NO);
    23. }
    24.  
    Maybe I have to rip the SystemInfo.operatingSystem.Contains(".E.") out of the code as radishan did? Or should I use
    SystemInfo.deviceModel.Contains("Sony Ericsson") || SystemInfo.operatingSystem.Contains(".E.") instead?

    Maybe a dumb question, but could a rooted phone make this code malfunction?
     
    Last edited: Nov 22, 2011
  11. colargol

    colargol

    Joined:
    Mar 31, 2010
    Posts:
    65
    This is handled by Unity 3.4.x, don't use the temporal fix.
    This was there, because at 04/2011 there was difference between "A" and "E" firmwares.
    Since 3.0.A.2.184 it should be the same, "navigationHidden" should be used...
    I have "E" version, so I can't confirm this.
     
    Last edited: Nov 22, 2011
  12. Panajev

    Panajev

    Joined:
    Mar 26, 2012
    Posts:
    42
    Hello,

    thank you all so much for this thread. With Unity being broken on iOS and latest Xcode right now (I do not have the Pro version so I am having issues with the Splash Screen), I like being able to test on Android and the fact that the Xperia Play's DPad works out of the box.

    I modified your code to allow users to detect if the Keypad is showing or hidden in JavaScript. Minor note: I am using an Actor class and a Player subclass so the code is divided between the two (the actor is not driven by user's input directly for example).

    Actor.js:
    Code (csharp):
    1.    
    2.  
    3. [...]
    4.  
    5. //Checks for Android and Xperia Play's hardware joypad availabilityt.
    6.     protected var isSonyEricssonDevice : boolean = false;
    7.     protected var navHidden : int = 0;  //Is the Xperia Play's KeyPad status set to hidden?
    8.     protected var isKeypadVisible : boolean = false;
    9.     protected var player : AndroidJavaClass = null;
    10.     protected var activity : AndroidJavaObject = null;
    11.     protected var currentConfig : AndroidJavaObject = null;
    12.    
    13.     protected var NAVIGATIONHIDDEN_UNDEFINED : int = 0;
    14.     protected var NAVIGATIONHIDDEN_NO : int = 1;
    15.     protected var NAVIGATIONHIDDEN_YES : int = 2;
    16.     ///////////////////////////////////////
    17.  
    18.     function Awake() {
    19.        
    20. #if UNITY_ANDROID
    21.         player = AndroidJavaClass("com.unity3d.player.UnityPlayer");
    22.         activity = player.GetStatic.<AndroidJavaObject>("currentActivity");
    23.         currentConfig = activity.Call.<AndroidJavaObject>("getResources").Call.<AndroidJavaObject>("getConfiguration");
    24.    
    25.         if(SystemInfo.deviceModel.Contains("Sony Ericsson")  SystemInfo.deviceModel.Contains("R800") || SystemInfo.deviceModel.Contains("Z1i"))
    26.         {
    27.             PlayerPrefs.SetInt("SonyEricssonDevice", 1);
    28.             isSonyEricssonDevice = true;
    29.         }
    30.         else
    31.         {
    32.             PlayerPrefs.SetInt("SonyEricssonDevice", 0);
    33.             isSonyEricssonDevice = false;
    34.         }
    35. #endif
    36.     }
    37.  
    38. [...]
    39.  
    40.  

    Player.js:
    Code (csharp):
    1.    
    2.  
    3. [...]
    4.  
    5. function checkInput() {
    6.         //Debug.Log("Player input check...");
    7.         isKeypadVisible = false;
    8.        
    9.         if(isSonyEricssonDevice == true ) {
    10.             navHidden = currentConfig.Get.<int>("navigationHidden");
    11.         }
    12.         else {
    13.             processTouchInput();
    14.         }
    15.        
    16.         if (navHidden == NAVIGATIONHIDDEN_NO) {
    17.             isKeypadVisible = true;
    18.         }
    19.         else if(navHidden == NAVIGATIONHIDDEN_YES || navHidden == NAVIGATIONHIDDEN_UNDEFINED) {
    20.             isKeypadVisible = false;
    21.         }
    22.        
    23.         if (isKeypadVisible) {
    24.             //Debug.Log("Keypad showing...");
    25.             processJoypadInput();
    26.         }
    27.         else {
    28.             //Debug.Log("Keypad hidden...");
    29.         }
    30.     }
    31.  
    32. [...]
    33.  
    34.  
     
  13. deltawave

    deltawave

    Joined:
    Apr 21, 2010
    Posts:
    17
    Just to concur with radishan, I have an 02 ( UK ) Xperia, build 4.0.2.A.0.42 and I also got jashan's script working by simply commenting out the SystemInfo.operatingSystem.Contains(".E.") part of the code.

    Has anyone coded/planned on coding a complete Xperia Control Pad function, to check the firmware and give access to all the buttons?
    Would be a worthy addition to the Unity Store.
     
  14. Panajev

    Panajev

    Joined:
    Mar 26, 2012
    Posts:
    42
    The code I posted below works on an Italian Xperia Play and on an Optimus 3D by LG (meaning that it shows the virtual pad because it detects the hardware pad is not available on the LG phone).