Android笔记:Unity3D与android项目交互中无法监听back键返回的解决办法

转载 2013年12月04日 02:40:50

 这两天为解决unity3d与android项目整合中出现的无法监听真机back实体键的问题找了很多资料,最后还是在不断的测试中解决了这个问题。

   实现目的是从A_Activity跳转到UnityPlayerNativeActivity,传入参数加载对应的三维图,按返回键或home键分别返回上一个activity和返回桌面。默认情况下按home键会返回桌面,但是按back键则无法监听到,没有任何反应。


===========UnityPlayer相关==============================

   UnityPlayer里有三个类,分别是UnityPlayerProxyActivity、UnityPlayerActivity、UnityPlayerNativeActivity。

   UnityPlayerProxyActivity用来判断手机的系统版本,从而确定启动UnityPlayerActivity还是UnityPlayerNativeActivity。所以UnityPlayerProxyActivity这个类自己就直接去掉不用了。

   UnityPlayerNativeActivity这个类的加载速率据说会比较快,系统版本要求2.3以上,之前也一直用这个类整合使用。但是这两天在使用这个类时一直没法解决实体按键事件的问题,具体可以看下这段介绍:


UnityPlayerNativeActivity

同样我们可以创建UnityPlayerNativeActivity的子类,这与创建UnityPlayerActivity的子类具有相同的效果,但是会有较小的输入延迟。但是,需要明白的是,NativeActivity是在Gingerbread中引入的(即android 2.3),老的android版本没有这个特性,因为在NativeActivity中,触摸事件都是在native代码中处理的,java视图正常情况下是无法获取这些事件的,不过在unity3d中,有允许将事件传到DalvikVM的转发机制,要应用这个转发机制,必须修改manifest文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.product">
  <application android:icon="@drawable/app_icon" android:label="@string/app_name">
    <activity android:name=".OverrideExampleNative"
              android:label="@string/app_name"
              android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
  <meta-data android:name="android.app.lib_name" android:value="unity" />
  <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
  </application>
</manifest>


参考资料:http://blog.csdn.net/topgun_chenlingyun/article/details/8258440。

   即使按照上述的xml配置后,进入三维图的UnityPlayerNativeActivity后,除home键外,其他按键都没法监听到。




======================在Unity中捕捉Android的常用按钮返回事件=============

   另有一种办法是可以在jni脚本文件里监听到实体按键,可以在脚本文件里对按键事件进行处理。不过针对返回键只有一个方法可以调用,即Application.Quit();但是这个方法会退出整个application,按下返回键后,三维图页面退出了,同时其他页面也闪退了,无法返回到上一个activity的页面。

1
2
3
4
5
6
7
8
9
10
#pragma strict
function Start () {
}
function Update () {
    if(Input.GetKey(KeyCode.Escape)){
        Application.Quit();
    }
}
function OnGUI () {
}


参考资料:http://blog.sina.com.cn/s/blog_48901d6e0101d9dt.html




================使用UnityPlayerActivity监听按键事件=======================

   于是改用UnityPlayerActivity这个类进行尝试,通过测试终于发现可以直接在这个类里监听到按键,但是却无法识别按键。

1
2
3
4
5
6
7
8
9
10
11
12
13
// Pass any keys not handled by (unfocused) views straight to UnityPlayer
public boolean onKeyMultiple(int keyCode, int count, KeyEvent event)
{
    return mUnityPlayer.onKeyMultiple(keyCode, count, event);
}
public boolean onKeyDown(int keyCode, KeyEvent event)
{
    return mUnityPlayer.onKeyDown(keyCode, event);
}
public boolean onKeyUp(int keyCode, KeyEvent event)
{
    return mUnityPlayer.onKeyUp(keyCode, event);
}

   只要有按键被按下,这三个方法都能执行,包括音量键等。但是只能监听到按键事件,却无法识别是否按下的是返回键,还是菜单键。加上KeyCode.Escape或者KeyCode.Back都无效,用onBackPressed()方法也仍然无效。网上很多一样的问题,却没有有效的答案。


参考资料:http://stackoverflow.com/questions/7754373/integrating-unity-with-eclipse-back-button-click

http://forum.unity3d.com/threads/75360-Is-there-any-way-to-close-Activity

http://forum.unity3d.com/threads/61851-How-to-Use-hardware(H-W)-MENU-KEY



================继承UnityPlayerActivity获取按键事件==================================

    找不到确切的解决办法,决定改变思路再尝试下。原先的UnityPlayerActivity保持不变,参数传入的接收和处理仍然在这个类里进行,自己再创建一个类来继承UnityPlayerActivity。测试后发现终于可以识别到按键了,同时正常加载UnityPlayerActivity这个视图。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class ExtendActivity extends UnityPlayerActivity
{
                                                                                                                                                                                                                                              
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
    }
                                                                                                                                                                                                                                              
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        if(keyCode == KeyEvent.KEYCODE_BACK)
        {
            finish();
            Log.e("key", "key");
        }
        // TODO Auto-generated method stub
        return super.onKeyDown(keyCode, event);
    }
}

       既然可以识别到返回键,那么接下来的问题应该就好办了。按照上面的处理后,进入ExtendActivity就等于加载了UnityPlayerActivity,但是按下back键后又出现了原先的问题,三维图退出了,紧接着其他activity也退出了,就跟jni脚本文件里执行Application.Quit()方法的效果一样。(这个还没整明白具体原因)。



=======================通过mUnityPlayer.quit()退出并返回上一个activity==================

   于是接着继续测试修改。为UnityPlayerActivity注册了广播接收者,在按下ExtendActivity的back键时发送广播通知UnityPlayerActivity执行finish()方法。修改后发现问题一样,还是无法返回到上一个activity。

   正整得头大的时候,又看了遍UnityPlayerActivity类,发现了mUnityPlayer.quit()方法。于是尝试把finish()方法换成mUnityPlayer.quit(),通过退出unityplayer来结束UnityPlayerActivity,没想最后终于成功了。喜大普奔啊


java代码如下:


ExtendActivity类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class ExtendActivity extends UnityPlayerActivity
{
                                                                                                                          
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
    }
                                                                                                                          
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        if(keyCode == KeyEvent.KEYCODE_BACK)
        {
            sendBroadcast(new Intent("finish"));
//            finish();
            Log.e("key", "key");
        }
        // TODO Auto-generated method stub
        return super.onKeyDown(keyCode, event);
    }
}



UnityPlayerActivity类里添加的方法:

1
2
3
4
5
6
7
8
//注册广播接受者
private void registBroadcast()
{
    BroadcastReceiver receiver = new FinishUnityBroadcast();
    IntentFilter filter = new IntentFilter();
    filter.addAction("finish");
    registerReceiver(receiver, filter );
}


1
2
3
4
5
6
7
8
9
//关闭三维图的广播
class FinishUnityBroadcast extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        mUnityPlayer.quit();
    }
}

Unity3D与Android项目交互中无法监听back键返回的解决办法

这两天为解决unity3d与android项目整合中出现的无法监听真机back实体键的问题找了很多资料,网上也有很多人遇到了这个问题,但是似乎都没找到有效的解决方法。  原文地址:http://...
  • fanglrui
  • fanglrui
  • 2015年05月06日 00:47
  • 2063

Android 重写onBackPressed()函数 失效问题

@Override public void onBackPressed() { // TODO Auto-generated method stub super.onBackPressed();...
  • Bill_Ming
  • Bill_Ming
  • 2013年04月17日 01:21
  • 20755

Unity3D与Android项目交互中无法监听back键返回的解决办法

这两天为解决unity3d与android项目整合中出现的无法监听真机back实体键的问题找了很多资料,网上也有很多人遇到了这个问题,但是似乎都没找到有效的解决方法。      实现的效果...
  • dream_sky213
  • dream_sky213
  • 2014年11月19日 14:43
  • 1101

Unity3D与Android项目交互中无法监听back键返回的解决办法

这两天为解决unity3d与android项目整合中出现的无法监听真机back实体键的问题找了很多资料,网上也有很多人遇到了这个问题,但是似乎都没找到有效的解决方法。  原文地址:http://...
  • fanglrui
  • fanglrui
  • 2015年05月06日 00:47
  • 2063

关于Fragment中返回键(onBackPressed)的处理

关于Fragment中返回键(onBackPressed)的处理 我们在Android开发中怎么处理返回键的?常见的两种方法:在Activity中实现如下代码,来监听“返回键” @Override...
  • mxh1988123
  • mxh1988123
  • 2015年05月16日 23:57
  • 6976

优雅的让Fragment监听返回键

Fragment是不能得到物理返回键的监听的,
  • guxiao1201
  • guxiao1201
  • 2014年10月27日 14:40
  • 76883

Android软键盘(七)键盘显示的状态下,onKeyDown方法无法监听到back事件

Android键盘显示的状态下,onKeyDown方法无法监听到back事件,android弹出键盘的系统下,监听不到返回值的解决方案。...
  • sinat_31311947
  • sinat_31311947
  • 2016年12月29日 21:59
  • 1260

Android设备Home、Menu和Back返回键的监听

在APP的操作中,有时需要监听系统按键,今天我就分享下自己的学习所得。 Menu键和Back键通过KeyDown事件就可以监听到,但Home键触发是系统事件,不能通过KeyDown简单的监控,但可以通...
  • nalw2012
  • nalw2012
  • 2015年11月06日 14:28
  • 3842

Android之back键拦截处理

Back键是手机上的后退键,在Android上有两种方法来获取该按钮的事件。 **一:如何捕获Back按键事件**1.直接获取按钮按下事件,直接重写Activity的onKeyDown方法即可,代码...
  • lyjIT
  • lyjIT
  • 2016年06月06日 17:46
  • 3752

Fragment详解之六——如何监听fragment中的回退事件与怎样保存fragment状态

前言:计划总是赶不上变化,无论结局怎样,只要一直跟随自己的内心,不放弃,总有一天,你会成为那个人,加油。经过前几篇,大家应该对Fragment认识的已经足够多了,有关Fragment的基础知识在前几篇...
  • harvic880925
  • harvic880925
  • 2015年04月12日 20:36
  • 33927
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android笔记:Unity3D与android项目交互中无法监听back键返回的解决办法
举报原因:
原因补充:

(最多只允许输入30个字)