Oyununuzda oyun kumandalarını destekliyorsanız oyununuzun, farklı Android sürümlerinin yüklü olduğu cihazlarda kumandalara tutarlı bir şekilde yanıt verdiğinden emin olmak sizin sorumluluğunuzdadır. Bu sayede oyununuz daha geniş bir kitleye ulaşır ve oyuncularınız, Android cihazlarını değiştirseler veya yükseltseler bile kumandalarıyla sorunsuz bir oyun deneyimi yaşayabilir.
Bu derste, Android 4.1 ve sonraki sürümlerde bulunan API'lerin geriye dönük uyumlu bir şekilde nasıl kullanılacağı gösterilmektedir. Bu sayede oyununuz, Android 3.1 ve sonraki sürümleri çalıştıran cihazlarda aşağıdaki özellikleri destekleyebilir:
- Oyun, yeni bir oyun kumandası eklenip eklenmediğini, değiştirilip değiştirilmediğini veya kaldırılıp kaldırılmadığını algılayabilir.
- Oyun, oyun kumandasının özelliklerini sorgulayabilir.
- Oyun, oyun kumandasından gelen hareket etkinliklerini tanıyabilir.
Oyun kumandası desteği için API'leri soyutlamaya hazırlanma
Android 3.1 (API seviyesi 12) çalıştıran cihazlarda bir oyun kumandasının bağlantı durumunun değişip değişmediğini belirlemek istediğinizi varsayalım. Ancak API'ler yalnızca Android 4.1 (API düzeyi 16) ve sonraki sürümlerde kullanılabilir. Bu nedenle, Android 4.1 ve sonraki sürümleri destekleyen bir uygulama sağlarken Android 3.1'den Android 4.0'a kadar olan sürümleri destekleyen bir geri dönüş mekanizması da sağlamanız gerekir.
Hangi özelliklerin daha düşük sürümler için yedek mekanizma gerektirdiğini belirlemenize yardımcı olmak amacıyla Tablo 1'de Android 3.1 (API düzeyi 12) ile 4.1 (API düzeyi 16) arasındaki oyun kumandası desteği farklılıkları listelenmiştir.
Tablo 1. Farklı Android sürümlerinde oyun kumandası desteği için API'ler.
| Denetleyici Bilgileri | Controller API | API düzeyi 12 | API düzeyi 16 |
|---|---|---|---|
| Cihaz Tanımlama | getInputDeviceIds() |
• | |
getInputDevice() |
• | ||
getVibrator() |
• | ||
SOURCE_JOYSTICK |
• | • | |
SOURCE_GAMEPAD |
• | • | |
| Bağlantı durumu | onInputDeviceAdded() |
• | |
onInputDeviceChanged() |
• | ||
onInputDeviceRemoved() |
• | ||
| Giriş Etkinliği Tanımlama | D-pad'e basma (
KEYCODE_DPAD_UP,
KEYCODE_DPAD_DOWN,
KEYCODE_DPAD_LEFT,
KEYCODE_DPAD_RIGHT,
KEYCODE_DPAD_CENTER) |
• | • |
Gamepad düğmesine basma (
BUTTON_A,
BUTTON_B,
BUTTON_THUMBL,
BUTTON_THUMBR,
BUTTON_SELECT,
BUTTON_START,
BUTTON_R1,
BUTTON_L1,
BUTTON_R2,
BUTTON_L2) |
• | • | |
Kontrol çubuğu ve şapka anahtarı hareketi (
AXIS_X,
AXIS_Y,
AXIS_Z,
AXIS_RZ,
AXIS_HAT_X,
AXIS_HAT_Y) |
• | • | |
Analog tetikleyiciye basma (
AXIS_LTRIGGER,
AXIS_RTRIGGER) |
• | • |
Platformlar arasında çalışan, sürümden bağımsız oyun kumandası desteği oluşturmak için soyutlamayı kullanabilirsiniz. Bu yaklaşımda aşağıdaki adımlar yer alır:
- Oyununuzun gerektirdiği oyun kumandası özelliklerinin uygulanmasını soyutlayan bir ara Java arayüzü tanımlayın.
- Android 4.1 ve sonraki sürümlerdeki API'leri kullanan arayüzünüzün bir proxy uygulamasını oluşturun.
- Android 3.1 ile Android 4.0 arasında kullanılabilen API'leri kullanan arayüzünüzün özel bir uygulamasını oluşturun.
- Çalışma zamanında bu uygulamalar arasında geçiş yapma mantığını oluşturun ve arayüzü oyununuzda kullanmaya başlayın.
Soyutlamanın, uygulamaların farklı Android sürümlerinde geriye dönük uyumlu şekilde çalışabildiğini doğrulamak için nasıl kullanılabileceğine dair genel bir bakış için Geriye Dönük Uyumlu Kullanıcı Arayüzleri Oluşturma başlıklı makaleyi inceleyin.
Geriye dönük uyumluluk için arayüz ekleme
Geriye dönük uyumluluk sağlamak için özel bir arayüz oluşturabilir ve ardından sürüme özel uygulamalar ekleyebilirsiniz. Bu yaklaşımın avantajlarından biri, Android 4.1'de (API düzeyi 16) oyun kumandalarını destekleyen herkese açık arayüzleri yansıtmanıza olanak tanımasıdır.
Kotlin
// The InputManagerCompat interface is a reference example.
// The full code is provided in the ControllerSample.zip sample.
interface InputManagerCompat {
val inputDeviceIds: IntArray
fun getInputDevice(id: Int): InputDevice
fun registerInputDeviceListener(
listener: InputManager.InputDeviceListener,
handler: Handler?
)
fun unregisterInputDeviceListener(listener:InputManager.InputDeviceListener)
fun onGenericMotionEvent(event: MotionEvent)
fun onPause()
fun onResume()
interface InputDeviceListener {
fun onInputDeviceAdded(deviceId: Int)
fun onInputDeviceChanged(deviceId: Int)
fun onInputDeviceRemoved(deviceId: Int)
}
}
Java
// The InputManagerCompat interface is a reference example.
// The full code is provided in the ControllerSample.zip sample.
public interface InputManagerCompat {
...
public InputDevice getInputDevice(int id);
public int[] getInputDeviceIds();
public void registerInputDeviceListener(
InputManagerCompat.InputDeviceListener listener,
Handler handler);
public void unregisterInputDeviceListener(
InputManagerCompat.InputDeviceListener listener);
public void onGenericMotionEvent(MotionEvent event);
public void onPause();
public void onResume();
public interface InputDeviceListener {
void onInputDeviceAdded(int deviceId);
void onInputDeviceChanged(int deviceId);
void onInputDeviceRemoved(int deviceId);
}
...
}
InputManagerCompat arayüzünde aşağıdaki yöntemler sunulur:
getInputDevice()- Aynalar
getInputDevice(). Oyun kumandasının özelliklerini temsil edenInputDevicenesnesini alır. getInputDeviceIds()- Aynalar
getInputDeviceIds(). Her biri farklı bir giriş cihazının kimliği olan bir tam sayı dizisi döndürür. Bu, birden fazla oyuncuyu destekleyen bir oyun geliştiriyorsanız ve kaç denetleyicinin bağlı olduğunu tespit etmek istiyorsanız kullanışlıdır. registerInputDeviceListener()- Aynalar
registerInputDeviceListener(). Yeni bir cihaz eklendiğinde, değiştirildiğinde veya kaldırıldığında bilgilendirilmek için kaydolmanıza olanak tanır. unregisterInputDeviceListener()- Aynalar
unregisterInputDeviceListener(). Giriş cihazı işleyicisinin kaydını siler. onGenericMotionEvent()- Aynalar
onGenericMotionEvent(). Oyununuzun, joystick hareketleri ve analog tetikleyiciye basma gibi etkinlikleri temsil edenMotionEventnesneleri ve eksen değerlerini yakalamasına ve işlemesine olanak tanır.
onPause()- Ana etkinlik duraklatıldığında veya oyun artık odaklanmadığında oyun kumandası etkinlikleri için yoklama işlemini durdurur.
onResume()- Ana etkinlik devam ettirildiğinde veya oyun başlatılıp ön planda çalıştırıldığında oyun kumandası etkinlikleri için yoklama başlatır.
InputDeviceListener- Arayüzü yansıtır.
InputManager.InputDeviceListenerOyununuza, oyun kumandası eklendiğinde, değiştirildiğinde veya kaldırıldığında bilgi verir.
Ardından, farklı platform sürümlerinde çalışan InputManagerCompat uygulamaları oluşturun. Oyununuz Android 4.1 veya sonraki bir sürümde çalışıyorsa ve bir InputManagerCompat yöntemi çağırıyorsa proxy uygulaması, InputManager içinde eşdeğer yöntemi çağırır.
Ancak oyununuz Android 3.1 ile Android 4.0 arasında bir sürümde çalışıyorsa özel uygulama, InputManagerCompat yöntemlerine yapılan çağrıları yalnızca Android 3.1'den sonra kullanıma sunulmayan API'leri kullanarak işler. Çalışma zamanında hangi sürüme özel uygulamanın kullanıldığına bakılmaksızın, uygulama çağrı sonuçlarını şeffaf bir şekilde oyuna geri iletir.
Android 4.1 ve sonraki sürümlerde arayüzü uygulama
InputManagerCompatV16, yöntem çağrılarını gerçek bir InputManagerCompat arayüzüne ve InputManager ile InputManager.InputDeviceListener'ye yönlendiren bir InputManagerCompat arayüzü uygulamasıdır.
InputManager, Context sisteminden alınır.
Kotlin
// The InputManagerCompatV16 class is a reference implementation.
// The full code is provided in the ControllerSample.zip sample.
public class InputManagerV16(
context: Context,
private val inputManager: InputManager =
context.getSystemService(Context.INPUT_SERVICE) as InputManager,
private val listeners:
MutableMap<InputManager.InputDeviceListener, V16InputDeviceListener> = mutableMapOf()
) : InputManagerCompat {
override val inputDeviceIds: IntArray = inputManager.inputDeviceIds
override fun getInputDevice(id: Int): InputDevice = inputManager.getInputDevice(id)
override fun registerInputDeviceListener(
listener: InputManager.InputDeviceListener,
handler: Handler?
) {
V16InputDeviceListener(listener).also { v16listener ->
inputManager.registerInputDeviceListener(v16listener, handler)
listeners += listener to v16listener
}
}
// Do the same for unregistering an input device listener
...
override fun onGenericMotionEvent(event: MotionEvent) {
// unused in V16
}
override fun onPause() {
// unused in V16
}
override fun onResume() {
// unused in V16
}
}
class V16InputDeviceListener(
private val idl: InputManager.InputDeviceListener
) : InputManager.InputDeviceListener {
override fun onInputDeviceAdded(deviceId: Int) {
idl.onInputDeviceAdded(deviceId)
}
// Do the same for device change and removal
...
}
Java
// The InputManagerCompatV16 class is a reference implementation.
// The full code is provided in the ControllerSample.zip sample.
public class InputManagerV16 implements InputManagerCompat {
private final InputManager inputManager;
private final Map<InputManagerCompat.InputDeviceListener,
V16InputDeviceListener> listeners;
public InputManagerV16(Context context) {
inputManager = (InputManager)
context.getSystemService(Context.INPUT_SERVICE);
listeners = new HashMap<InputManagerCompat.InputDeviceListener,
V16InputDeviceListener>();
}
@Override
public InputDevice getInputDevice(int id) {
return inputManager.getInputDevice(id);
}
@Override
public int[] getInputDeviceIds() {
return inputManager.getInputDeviceIds();
}
static class V16InputDeviceListener implements
InputManager.InputDeviceListener {
final InputManagerCompat.InputDeviceListener mIDL;
public V16InputDeviceListener(InputDeviceListener idl) {
mIDL = idl;
}
@Override
public void onInputDeviceAdded(int deviceId) {
mIDL.onInputDeviceAdded(deviceId);
}
// Do the same for device change and removal
...
}
@Override
public void registerInputDeviceListener(InputDeviceListener listener,
Handler handler) {
V16InputDeviceListener v16Listener = new
V16InputDeviceListener(listener);
inputManager.registerInputDeviceListener(v16Listener, handler);
listeners.put(listener, v16Listener);
}
// Do the same for unregistering an input device listener
...
@Override
public void onGenericMotionEvent(MotionEvent event) {
// unused in V16
}
@Override
public void onPause() {
// unused in V16
}
@Override
public void onResume() {
// unused in V16
}
}
Android 3.1'den Android 4.0'a kadar olan sürümlerde arayüzü uygulama
Android 3.1'den Android 4.0'a kadar olan sürümleri destekleyen bir InputManagerCompat uygulaması oluşturmak için aşağıdaki nesneleri kullanabilirsiniz:
- Cihaza bağlı oyun kumandalarını izlemek için
SparseArraycihaz kimliği. - Cihaz etkinliklerini işlemek için
Handler. Bir uygulama başlatıldığında veya devam ettirildiğindeHandler, oyun kumandası bağlantısının kesilmesi için yoklama başlatma mesajı alır.Handler, bilinen her bağlı oyun kumandasını kontrol etmek ve cihaz kimliğinin döndürülüp döndürülmediğini görmek için bir döngü başlatır.nulldönüş değeri, oyun kumandasının bağlantısının kesildiğini gösterir. Uygulama duraklatıldığındaHandler, yoklama yapmayı durdurur. InputManagerCompat.InputDeviceListenernesnelikMap. İzlenen oyun kumandalarının bağlantı durumunu güncellemek için dinleyicileri kullanırsınız.
Kotlin
// The InputManagerCompatV9 class is a reference implementation.
// The full code is provided in the ControllerSample.zip sample.
class InputManagerV9(
val devices: SparseArray<Array<Long>> = SparseArray(),
private val listeners:
MutableMap<InputManager.InputDeviceListener, Handler> = mutableMapOf()
) : InputManagerCompat {
private val defaultHandler: Handler = PollingMessageHandler(this)
…
}
Java
// The InputManagerCompatV9 class is a reference implementation.
// The full code is provided in the ControllerSample.zip sample.
public class InputManagerV9 implements InputManagerCompat {
private final SparseArray<long[]> devices;
private final Map<InputDeviceListener, Handler> listeners;
private final Handler defaultHandler;
…
public InputManagerV9() {
devices = new SparseArray<long[]>();
listeners = new HashMap<InputDeviceListener, Handler>();
defaultHandler = new PollingMessageHandler(this);
}
}
Handler öğesini genişleten bir PollingMessageHandler nesnesi uygulayın ve handleMessage() yöntemini geçersiz kılın. Bu yöntem, bağlı bir oyun kumandasının bağlantısının kesilip kesilmediğini kontrol eder ve kayıtlı işleyicileri bilgilendirir.
Kotlin
private class PollingMessageHandler(
inputManager: InputManagerV9,
private val mInputManager: WeakReference<InputManagerV9> = WeakReference(inputManager)
) : Handler() {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
when (msg.what) {
MESSAGE_TEST_FOR_DISCONNECT -> {
mInputManager.get()?.also { imv ->
val time = SystemClock.elapsedRealtime()
val size = imv.devices.size()
for (i in 0 until size) {
imv.devices.valueAt(i)?.also { lastContact ->
if (time - lastContact[0] > CHECK_ELAPSED_TIME) {
// check to see if the device has been
// disconnected
val id = imv.devices.keyAt(i)
if (null == InputDevice.getDevice(id)) {
// Notify the registered listeners
// that the game controller is disconnected
imv.devices.remove(id)
} else {
lastContact[0] = time
}
}
}
}
sendEmptyMessageDelayed(MESSAGE_TEST_FOR_DISCONNECT, CHECK_ELAPSED_TIME)
}
}
}
}
}
Java
private static class PollingMessageHandler extends Handler {
private final WeakReference<InputManagerV9> inputManager;
PollingMessageHandler(InputManagerV9 im) {
inputManager = new WeakReference<InputManagerV9>(im);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case MESSAGE_TEST_FOR_DISCONNECT:
InputManagerV9 imv = inputManager.get();
if (null != imv) {
long time = SystemClock.elapsedRealtime();
int size = imv.devices.size();
for (int i = 0; i < size; i++) {
long[] lastContact = imv.devices.valueAt(i);
if (null != lastContact) {
if (time - lastContact[0] > CHECK_ELAPSED_TIME) {
// check to see if the device has been
// disconnected
int id = imv.devices.keyAt(i);
if (null == InputDevice.getDevice(id)) {
// Notify the registered listeners
// that the game controller is disconnected
imv.devices.remove(id);
} else {
lastContact[0] = time;
}
}
}
}
sendEmptyMessageDelayed(MESSAGE_TEST_FOR_DISCONNECT,
CHECK_ELAPSED_TIME);
}
break;
}
}
}
Oyun kumandası bağlantısının kesilmesiyle ilgili yoklamayı başlatmak ve durdurmak için şu yöntemleri geçersiz kılın:
Kotlin
private const val MESSAGE_TEST_FOR_DISCONNECT = 101
private const val CHECK_ELAPSED_TIME = 3000L
class InputManagerV9(
val devices: SparseArray<Array<Long>> = SparseArray(),
private val listeners:
MutableMap<InputManager.InputDeviceListener, Handler> = mutableMapOf()
) : InputManagerCompat {
...
override fun onPause() {
defaultHandler.removeMessages(MESSAGE_TEST_FOR_DISCONNECT)
}
override fun onResume() {
defaultHandler.sendEmptyMessageDelayed(MESSAGE_TEST_FOR_DISCONNECT, CHECK_ELAPSED_TIME)
}
...
}
Java
private static final int MESSAGE_TEST_FOR_DISCONNECT = 101;
private static final long CHECK_ELAPSED_TIME = 3000L;
@Override
public void onPause() {
defaultHandler.removeMessages(MESSAGE_TEST_FOR_DISCONNECT);
}
@Override
public void onResume() {
defaultHandler.sendEmptyMessageDelayed(MESSAGE_TEST_FOR_DISCONNECT,
CHECK_ELAPSED_TIME);
}
Bir giriş cihazının eklendiğini algılamak için onGenericMotionEvent() yöntemini geçersiz kılın. Sistem bir hareket etkinliği bildirdiğinde bu etkinliğin, zaten izlenen bir cihaz kimliğinden mi yoksa yeni bir cihaz kimliğinden mi geldiğini kontrol edin. Cihaz kimliği yeniyse kayıtlı dinleyicileri bilgilendirin.
Kotlin
override fun onGenericMotionEvent(event: MotionEvent) {
// detect new devices
val id = event.deviceId
val timeArray: Array<Long> = mDevices.get(id) ?: run {
// Notify the registered listeners that a game controller is added
...
arrayOf<Long>().also {
mDevices.put(id, it)
}
}
timeArray[0] = SystemClock.elapsedRealtime()
}
Java
@Override
public void onGenericMotionEvent(MotionEvent event) {
// detect new devices
int id = event.getDeviceId();
long[] timeArray = mDevices.get(id);
if (null == timeArray) {
// Notify the registered listeners that a game controller is added
...
timeArray = new long[1];
mDevices.put(id, timeArray);
}
long time = SystemClock.elapsedRealtime();
timeArray[0] = time;
}
Dinleyicilere bildirim göndermek için mesaj kuyruğuna DeviceEvent
Runnable nesnesi göndermek üzere Handler nesnesi kullanılır.
DeviceEvent, bir InputManagerCompat.InputDeviceListener referansı içeriyor. DeviceEvent çalıştırıldığında, oyun kumandasının eklenip eklenmediğini, değiştirilip değiştirilmediğini veya kaldırılıp kaldırılmadığını belirtmek için işleyicinin uygun geri çağırma yöntemi çağrılır.
Kotlin
class InputManagerV9(
val devices: SparseArray<Array<Long>> = SparseArray(),
private val listeners:
MutableMap<InputManager.InputDeviceListener, Handler> = mutableMapOf()
) : InputManagerCompat {
...
override fun registerInputDeviceListener(
listener: InputManager.InputDeviceListener,
handler: Handler?
) {
listeners[listener] = handler ?: defaultHandler
}
override fun unregisterInputDeviceListener(listener: InputManager.InputDeviceListener) {
listeners.remove(listener)
}
private fun notifyListeners(why: Int, deviceId: Int) {
// the state of some device has changed
listeners.forEach { listener, handler ->
DeviceEvent.getDeviceEvent(why, deviceId, listener).also {
handler?.post(it)
}
}
}
...
}
private val sObjectQueue: Queue<DeviceEvent> = ArrayDeque<DeviceEvent>()
private class DeviceEvent(
private var mMessageType: Int,
private var mId: Int,
private var mListener: InputManager.InputDeviceListener
) : Runnable {
companion object {
fun getDeviceEvent(messageType: Int, id: Int, listener: InputManager.InputDeviceListener) =
sObjectQueue.poll()?.apply {
mMessageType = messageType
mId = id
mListener = listener
} ?: DeviceEvent(messageType, id, listener)
}
override fun run() {
when(mMessageType) {
ON_DEVICE_ADDED -> mListener.onInputDeviceAdded(mId)
ON_DEVICE_CHANGED -> mListener.onInputDeviceChanged(mId)
ON_DEVICE_REMOVED -> mListener.onInputDeviceChanged(mId)
else -> {
// Handle unknown message type
}
}
}
}
Java
@Override
public void registerInputDeviceListener(InputDeviceListener listener,
Handler handler) {
listeners.remove(listener);
if (handler == null) {
handler = defaultHandler;
}
listeners.put(listener, handler);
}
@Override
public void unregisterInputDeviceListener(InputDeviceListener listener) {
listeners.remove(listener);
}
private void notifyListeners(int why, int deviceId) {
// the state of some device has changed
if (!listeners.isEmpty()) {
for (InputDeviceListener listener : listeners.keySet()) {
Handler handler = listeners.get(listener);
DeviceEvent odc = DeviceEvent.getDeviceEvent(why, deviceId,
listener);
handler.post(odc);
}
}
}
private static class DeviceEvent implements Runnable {
private int mMessageType;
private int mId;
private InputDeviceListener mListener;
private static Queue<DeviceEvent> sObjectQueue =
new ArrayDeque<DeviceEvent>();
...
static DeviceEvent getDeviceEvent(int messageType, int id,
InputDeviceListener listener) {
DeviceEvent curChanged = sObjectQueue.poll();
if (null == curChanged) {
curChanged = new DeviceEvent();
}
curChanged.mMessageType = messageType;
curChanged.mId = id;
curChanged.mListener = listener;
return curChanged;
}
@Override
public void run() {
switch (mMessageType) {
case ON_DEVICE_ADDED:
mListener.onInputDeviceAdded(mId);
break;
case ON_DEVICE_CHANGED:
mListener.onInputDeviceChanged(mId);
break;
case ON_DEVICE_REMOVED:
mListener.onInputDeviceRemoved(mId);
break;
default:
// Handle unknown message type
...
break;
}
// Put this runnable back in the queue
sObjectQueue.offer(this);
}
}
Artık InputManagerCompat için iki uygulama var: biri Android 4.1 ve sonraki sürümlerin yüklü olduğu cihazlarda, diğeri ise Android 3.1 ile Android 4.0 arasındaki sürümlerin yüklü olduğu cihazlarda çalışır.
Sürüme özgü uygulamayı kullanma
Sürüme özgü geçiş mantığı, fabrika görevi gören bir sınıfta uygulanır.
Kotlin
object Factory {
fun getInputManager(context: Context): InputManagerCompat =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
InputManagerV16(context)
} else {
InputManagerV9()
}
}
Java
public static class Factory {
public static InputManagerCompat getInputManager(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
return new InputManagerV16(context);
} else {
return new InputManagerV9();
}
}
}
Artık bir InputManagerCompat nesnesi oluşturabilir ve ana View'nize bir InputManagerCompat.InputDeviceListener kaydedebilirsiniz. Ayarladığınız sürüm değiştirme mantığı nedeniyle oyununuz, cihazın çalıştığı Android sürümüne uygun uygulamayı otomatik olarak kullanır.
Kotlin
class GameView(context: Context) : View(context), InputManager.InputDeviceListener {
private val inputManager: InputManagerCompat = Factory.getInputManager(context).apply {
registerInputDeviceListener(this@GameView, null)
...
}
...
}
Java
public class GameView extends View implements InputDeviceListener {
private InputManagerCompat inputManager;
...
public GameView(Context context, AttributeSet attrs) {
inputManager =
InputManagerCompat.Factory.getInputManager(this.getContext());
inputManager.registerInputDeviceListener(this, null);
...
}
}
Ardından, onGenericMotionEvent() yöntemini ana görünümünüzde geçersiz kılın (Oyun kumandasından MotionEvent işleme ve sonraki sürümlerde açıklandığı gibi). Oyununuz artık Android 3.1 (API düzeyi) çalıştıran cihazlarda oyun kumandası etkinliklerini tutarlı bir şekilde işleyebilmelidir.
Kotlin
override fun onGenericMotionEvent(event: MotionEvent): Boolean {
inputManager.onGenericMotionEvent(event)
// Handle analog input from the controller as normal
...
return super.onGenericMotionEvent(event)
}
Java
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
inputManager.onGenericMotionEvent(event);
// Handle analog input from the controller as normal
...
return super.onGenericMotionEvent(event);
}
Bu uyumluluk kodunun tam uygulamasını, indirilebilen örnek ControllerSample.zip içinde sağlanan GameView sınıfında bulabilirsiniz.