Concept:
I have an Android application written in Kotlin that simply launches an Android application on an external display. The display could be a AirServer, Miracast, Microsoft Connect, USB-OTG HDMI, USB-C HDMI, or a Simulated Secondary Display (see screenshot).
Here's the except of the code that does the "heavy lifting":
val intent = packageManager.getLaunchIntentForPackage(info.id)
val dm = recyclerView.context.getSystemService(Service.DISPLAY_SERVICE) as DisplayManager
val displays = dm.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION)
for (display in displays) {
val options = ActivityOptions.makeBasic()
options.launchDisplayId = display.displayId
recyclerView.context.startActivity(intent, options.toBundle())
break
}
The applications start fine. See the screenshot, where I used it to launch Minecraft Pocket Edition to a Simulated Secondary Display (as if an external HDMI monitor was connected). The issue is that I cannot send touch or cursor inputs to the virtual displays.
What Works:
adb shell input -d <display-id> tap <x> <y>
Wireless Controllers
Wireless Keyboards
What Doesn't Work:
Wireless / Wired Mice (cursor hits the edges of the phone screen, never enters the Virtual Display / External Display screen)
Touch (see screenshot)
What I've Tried:
The output of dumpsys display reveals that the Virtual Displays all lack the touch VIRTUAL parameter that the internal display has. I'm not sure if this means that the display itself doesn't support touchscreen input, or if it's simply not enabled.
I tried forcing the application into the foreground, which made the apps detect keyboard and controller inputs, but the cursor was still locked to the internal display window.
It's worth noting that the Android 10 Desktop Mode Developer Setting DOES put the cursor into the external display instead of the internal display. This is what I'm trying to accomplish.
There appears to be a hidden Java API within Androids SDK:
https://github.com/aosp-mirror/platform_frameworks_base/blob/a4ddee215e41ea232340c14ef92d6e9f290e5174/services/core/jni/com_android_server_input_InputManagerService.cpp#L825
I attempted to access this class via reflection and call setFocusedDisplay, but I kept getting ClassNotFound exceptions, even with the private API blacklist secure settings changed.
Any help would be appreciated here. The only other related threat to this one is here, and it was never solved:
Android Q VirtualDisplay touch input events
I've solve my problem. The input directed to the external display is controlled by the Android internal framework. By default, external mice are directed to the internal display. To have them go to the external display, Force Desktop Mode must be enabled in Developer Settings. There is currently no other way to forward the pointer.
Related
I would like to send data from my Windows computer to my Android Mobile.
For this, I need to activate the Accessory mode of the Android device and the USB Host mode on the Windows device.
On my Windows computer, I have a USB Composite device for the Android Mobile. This Composite USB device bundles several interfaces: Enumeration of USB Composite Devices.
Unfortunately, I can't find information how I can access the single devices of a Composite device.
I want to get a device id / path, which I can open with CreateFile to use the created HANDLE for opening a WinUsb handle with WinUsb_Initialize.
But if I try to open a Composite USB device with CreateFile, I get a ERROR_NOT_ENOUGH_MEMORY result.
I'm using this code:
_deviceHandle = CreateFile(
deviceId, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_NONE, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
... with the filename "\?\USB#VID_04E8&PID_6864#RF8NB0NMT0X#{a5dcbf10-6530-11d2-901f-00c04fb951ed}"
It's a GUID_DEVINTERFACE_USB_DEVICE device id for a Samsung Galaxy mobile with enabled USB debugging.
As the driver Windows uses ssudbus2.sys, Version 2.17.16.0 (2021-09-14) from Samsung Electronics Co. Ltd.
The app MyPhoneExplorer can access to my mobile. So it a solution without a special driver must be possible.
How can I get this device id / path of the single USB devices inside a Composite USB device?
The filename you are using represents the overall USB device; it doesn't represent any particular instance. A filename that represents interface will have something like &mi_01 right after the product name, where 1 is the 0-based interface number.
You might be able to just insert the appropriate &mi_xx string into your filename at the appropriate place and get it work. I think you'd also need to modify the GUID at the end of the string, which is the device interface GUID.
The more standard way to find the filename in code is to use the SetupAPI and the configuration manager (CM) API to iterate through all the child devices of your USB device. Look for a child whose device instance ID (retrieved with CM_Get_Device_ID) contains MI_xx where xx is the two-digit interface number you are looking for.
It takes a lot of effort to write up this code in standalone form, and test it, and debug it, so I will not be presenting you with a working code example. Instead, I encourage you to look at the working code in the get_interface_composite function of libusbp which does what you need to do:
https://github.com/pololu/libusbp/blob/759f48d/src/windows/interface_windows.c#L86
There are some more steps to get the path of that device node. And then the code that actually calls CreateFile and WinUsb_Initialize is here:
https://github.com/pololu/libusbp/blob/759f48d/src/windows/generic_handle_windows.c#L56-L77
I've developed an application that streams music (via internet connection) using service and having trubles streaming content without phone going idle.
While i was developing my application each time i tried case mentioned below the music was reproducing fine.
Use case : search song, select song from results, play song, screen off -> auto play next song from result list
I'm developing using real device - Huawei Mate 20 Lite - OS v8.01 so while debugging it gotta use USB cabel.
Like i said following the use case above while hooked on USB the auto play while screen off works good. The case it doesn't work good is when the cable is not connected (only mobile data turned on).
What I've figured out is that phone when connected on USB is probably keeping the device awake and it doesn't go to idle mode while when not connected after around 5mins the device probably shuts down processes that cost energy or it shuts down connection to mobile data i'm not sure and there's where i need you guys.
Also I've tested app using HTC U Play - OS v6.0 and the streaming goes smooth without interrupts while screen off and phone wasn't touched for 10+mins.
Also I've tried to acquire wakelock inside oncreate and without releasing it just to see if it helps and it doesn't.
pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
wl.acquire();
This problem you are facing can be due to the fact that after Andriod 6.0, all apps are getting optimized for optimizing the battery usage.
If you really think, the reason behind the application to go killed is inactivity. Then, probably, its because of battery optimization software itself.
You can enable another permission while installing the app on the device where you can update the list of unoptimized app by adding an entry for your app.
Originally, you will be able to do the manual settings by following below instruction.
. Head for the ‘Settings‘ app and then ‘Battery‘
. On the ‘three dots‘ menu, top right, you’ll find ‘Battery optimisation‘.
. Here you’ll see a list of all applications which shouldn’t be ‘optimised‘ (for which read ‘can be handled by Doze and App Standby’) – by default the list is usually very small, with almost all apps enabled for ‘optimisation’. Which is fine for general users, but if, like me, you want a few applications to live outside of the new battery optimisations, then tap on the ‘Not optimised‘ pick list and choose ‘All apps‘
. As you’d expect, every application on your phone is listed (this may be quite long) – swipe down until you find the application(s) that you particularly want to always keep running. Tap on the application name
. From the two choices, check the box for ‘Don’t optimise‘.
I am working on Acer Chromebook R11. The Android version of Chromebook is 7.1.1. The external monitor is connected via HDMI port on Chromebook. OS is showing both the displays and am able to drag the apps from one window to another window.
I want my app to display on both the screens. While querying for the displays, android display manager is returning only the default display information. The external monitor information is not present with the displaymanager.
import android.hardware.display.DisplayManager;
..
..
DisplayManager displayManager = (DisplayManager) getApplicationContext().getSystemService(Context.DISPLAY_SERVICE);
Display[] var1 = displayManager.getDisplays();
Display[] var2 = displayManager.getDisplays( DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
var1 is always having the default built-in screen information. I am expecting it to have information about the two displays.
var2 is always null.
Is there any issue with this API on Chromebook?
This api is working after I updated the OS on chromebook via beta channel.
In my android native activity, I would like to find all of the game controllers connected to the android device.
In input.h, there is a comment above AInputEvent_getDeviceId() that says
/*
* An input device id of 0 indicates that the event didn't come from a physical device;
* other numbers are arbitrary and you shouldn't depend on the values.
* Use the provided input device query API to obtain information about input devices.
*/
Does anyone know which "provided input device query API" the comment is referring to?
If I can't find all the connected devices, then maybe I can wait until AKEYCODE_BUTTON_START is pressed, and then assign that device as Player1...
Thanks!
I am using a PCB having FTDI UM232H-B in it. I am connecting this board to the Android tablet through USB cable. I have some latches to the UM232H-B to change the inputs and I want to receive the output through USB on the Android tablet which I can't able to.
The resources I am using are :
http://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_UM232H-B.pdf
http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232H.pdf
http://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_147_Java_D2xx_for_Android.pdf
http://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_134_FTDI_Android_D2XX_Driver.pdf
The official android demo application:
http://www.ftdichip.com/Support/SoftwareExamples/Android_JAVA_D2XX_Projects.htm
Finally, I could able to communicate with this IC. I followed these steps :
- Use j2xx library.
- Declare all IO buttons & LEDs.
- Initialize FT_Device object.
- Set in MPSSE Mode.
- Reset Button & LED latches.
- Run a while(true) loop inside a thread (AsyncTask) where, do Enable B/L, Setup B/L, Update B/L operations.
- Whenever a Button is pressed do FT_Device.read() and get the IO_Status and perform your specific action and again call Reset B/L immediately.
- In the meantime, all operations should be done giving some delay (For me 50ms worked just fine)