I have developed apps for screen mirroring one is for server and other is receiving server's screens.
Now, i am working on adding Touch events in receiver app and send touch event to server app. As both apps are on different devices so i am making connection using DLNA protocol for the communication.
But i am not able to inject touch event from receiver to server app and not able to achieve the functionality. I want to inject touch events without rooting my devices.
Following is the code that i am using:
m_Instrumentation = new Instrumentation();
AsyncTask.execute(new Runnable() {
#Override
public void run() {
//TODO your background code
m_Instrumentation.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),MotionEvent.ACTION_DOWN,x, y,0));
m_Instrumentation.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),MotionEvent.ACTION_UP,x, y,0));
}
});
The above code giving error that is Request Permission to inject event
As inject_event permission is a system permission so i have to make app as system app. For making system app i have to sign app with system certificates. So i followed the link How to compile Android Application with system permissions And if i am able to generate app as system app then i have to install it as /system/app
but when i am searching for adding app as system app then is asking for root device to get read/write access from OS. But i don't want to root the device.
Any helps would be appreciated deeply.
Related
Is it somehow possible to detect if the Wear mini app inside an Android app is already installed in the watch?
I have an app which cannot be used on the phone until the Wear part is installed in the watch, so I want to block all interaction until then.
What about app updates, is it possible to detect if the Wear part was already updated?
EDIT:
It looks like the Data API and even Message API calls are buffered and delivered after the app is installed. This however does not solve the issue with app updates. That is solvable with the accepted answer.
One Solution is to use CapabilityClient(https://developers.google.com/android/reference/com/google/android/gms/wearable/CapabilityClient). First you can detect whether the Wearable and phone are connected or not using NodeClient(https://developers.google.com/android/reference/com/google/android/gms/wearable/NodeClient). Below I have mentioned the code to detect whether the watch is connected to phone or not in android.
Task<List<Node>> nodesTask = Wearable.getNodeClient(MainMobileActivity.this)
.getConnectedNodes();
nodesTask.addOnSuccessListener(new OnSuccessListener<List<Node>>() {
#Override
public void onSuccess(List<Node> nodes) {
nodeSize = nodes.size();
for (Node node : nodes) {
Wearable.getMessageClient(MainMobileActivity.this)
.sendMessage(node.getId(), MESSAGE_PATH, "Hello from AndroidWear".getBytes());
}
Log.d("Hello" , "Message sent to Cordova");
}
});
So, nodeSize tells how many nodes/watches are connected.
Wearable.getMessageClient(MainMobileActivity.this)
.sendMessage(node.getId(), MESSAGE_PATH, "Hello from AndroidWear".getBytes());
This piece of code helps to send the message from phone to watch. Now coming to detect whether the watch has the application or not. Below is the mentioned code for it.
Task<CapabilityInfo> capabilityTask = Wearable.getCapabilityClient(this)
.getCapability(CAPABILITY_WEAR_APP, CapabilityClient.FILTER_REACHABLE);
capabilityTask.addOnSuccessListener(new OnSuccessListener<CapabilityInfo>() {
#Override
public void onSuccess(CapabilityInfo capabilityInfo) {
mWearNodesWithApp = capabilityInfo.getNodes();
}
});
So, if mWearNodesWithApp comes as 0 it shows that app is not installed and if it shows 1 it means application is installed.
CAPABILITY_WEAR_APP should be of String type and should have the value which you mentioned in wear.xml of wear application and not of phone. Do remember to mention the same applicationId for both Phone and Wear application.
AFAIK, there is no out-of-the-box solution to do it.
If your Wear app does not have activities (and therefore no means to be started by user), what you can do is send something like IS_INSTALLED message to Wear periodically while handheld app is in foreground until Wear won't put it version number into data layer. On application update you can check for version number in data layer and if it's lower than current version - repeat the procedure.
This approach will as well solve problem with Wear device not being connected (or out-of-range which is essentially the same).
I am working on android multi-user. So I have to convert my existing project in to multi user supporting project.
My app will be running in owner. If I switch to user, any related UI actions should be shown on owner or user,
I am using Context.startActivityAsUser(intent, UserHandle.Current);
so the activity will be launched on corresponding user or owner.
the same way to launching broadcast events.
In my app, I am using notification as part of service as below
startForeground (int id, Notification notification);
as the service is running is owner, the notification is showing on owner only even though I switched to user.
When end user switched to other profile, the notification should be shown on current profile.
as per my knowledge, there is no startForeground(...) as user (i mean as startForegroundAsUser()) so I have converted notification stuff to
NotificationManager.notifyAsUser(null, appID, notification, UserHandle.CURRENT);
....
When I switch from owner to user, my app is getting crashed and logs also not clear for find the issue. Logcat just says as
I/ActivityManager(421): Process com.example.test (pid 5833) has died
W/ActivityManager(421): Scheduling restart of crashed service com.example.test/com.example.test.testservice in 1000ms
.....
.....
.....
but the service is not started as top profile is CURRENT.
Let me know the other approach to achieve this.
The short answer is you cannot do this. Each app package is installed on the device with a separate data area and process for each human user. They are purposely kept isolated in memory and filesystem space via Linux UID/GID and permissions. In Android 5.0 this is further enforced using SE Linux for Android. So when you are switching (human) users, your apps are being started as separate instances for that person.
I'm developping two apps (on Android 4.2.2), app A that contains a "private" area and app B that can open the private area with an Intent.
I have used a custom Permission with protectionLevel="signature" to be sure the broadcast will be receive only if A and B are built with the same keystore, and it works well.
After this, I have made some tests, and finally find a way to "bypass" the Permission by using:
su -c am broadcast ... from an app that did not define the custom permission
So it means that if someone install the application A on a rooted device, he could send a broadcast message to my app and access the "private" area...
From my point of view, I'm not sure if it's a security breach or the expected behaviour.
I have found no documentation about this...
Do I really need to add a password in extras or something like that to be sure this access is protected?
Thanks
I understand that when you install an android app you need to accept the permissions requested by the app. When you run the app, when it comes to the point that app really about to use that permission and perform a task, the android system has to check again "whether this app is allowed to perform this task?". I need to perform some task (log the event) at this moment. How can I do this?
There is a catch. I want to identify these instances (moments) for other running apps (not for my app)
(Ex: I want to know when DropBox app is about to access the internet.)
I need to perform some task (log the event) at this moment. How can I do this?
You can download the Android source code, modify it to incorporate your desired security flaw, compile the results into a ROM mod, and install that ROM mod on your own device.
This is not possible via the Android SDK.
There is a catch. I want to identify these instances (moments) for other running apps (not for my app) (Ex: I want to know when DropBox app is about to access the internet.)
You are welcome to install and use a firewall package on your rooted Android device and perhaps hook something up that way, for this specific scenario. In general, what you seek is not possible, for blindingly obvious privacy and security reasons.
This question already has answers here:
Is it possible to detect Android app uninstall?
(8 answers)
Perform a task on uninstall in android [duplicate]
(4 answers)
Closed 7 years ago.
I though it was not possible but I noticed that NQ Mobile Security is able to show a message after I click on Uninstall and before the PackageUninstaller is called.
I would like to replicate this behavior in my App.
I tried with an Activity listening to "android.intent.action.DELETE" Intent, as suggested here:
How to know my app is uninstalled from the device...?
But as I'm about to uninstall my app, the chooser pops up asking to pick my application or the package uninstaller. How can I avoid this?
Is there a different way to intercept your application UNINSTALL event? (before answering that it is not possible, please try to uninstall NQ Mobile Security and see what happens. On my Android 2.3.4 it shows a nice screen saying that is not safe to go without a security app).
I noticed that NQ Mobile Security is able to show a message after I click on Uninstall and before the PackageUninstaller is called
They must be exploiting some security flaw in Android. I will research it and see if I can get it fixed. Apps are not supposed to get control at uninstall time.
Thanks for pointing this out!
Is there a different way to intercept your application UNINSTALL event?
I sure hope not.
Opera Max is an app that does something similar - after being uninstalled opens a webpage.
How do they do this?
By using libevent, from native code, they watch /data/data/com.opera.max directory to be removed and then post good old action.VIEW broadcast when it happens.
Install their app, run it, and on rooted device from adb shell remove /data/data/com.opera.max directory
UPDATE: I created a sample app that shows how it works. BTW it doesn't work with recent (KitKat+ I think) Android versions: https://github.com/pelotasplus/ActionAfterUninstall
I'm pretty sure that they are monitoring the LogCat to intercept when the Activity Manager calls the PackageUninstaller. I think they kill the task and start their own Activity.
It's pretty clever but it's definitely exploiting a security hole in Android.
They are likely asking for a very critical permission that the user is granting them unknowingly. Look at the "Permissions" tab for this app (as of 6/15/2012): https://play.google.com/store/apps/details?id=com.nqmobile.antivirus20&hl=en.
The list of permissions this app gets is downright chilling. Among other things:
SYSTEM TOOLS RETRIEVE RUNNING APPS Allows the app to retrieve
information about currently and recently running tasks. Malicious apps
may discover private information about other apps.
CHANGE/INTERCEPT NETWORK SETTINGS AND TRAFFIC Allows the app to change network settings
and to intercept and inspect all network traffic, for example to
change the proxy and port of any APN. Malicious apps may monitor,
redirect, or modify network packets without your knowledge.
PREVENT TABLET FROM SLEEPING PREVENT PHONE FROM SLEEPING Allows the app to
prevent the tablet from going to sleep. Allows the app to prevent the
phone from going to sleep.
CHANGE YOUR UI SETTINGS Allows the app to
change the current configuration, such as the locale or overall font
size.
MODIFY GLOBAL SYSTEM SETTINGS Allows the app to modify the
system's settings data. Malicious apps may corrupt your system's
configuration.
DISPLAY SYSTEM-LEVEL ALERTS Allows the app to show
system alert windows. Malicious apps may take over the entire screen.
MOUNT AND UNMOUNT FILESYSTEMS Allows the app to mount and unmount
filesystems for removable storage.
CHANGE NETWORK CONNECTIVITY Allows
the app to change the state of network connectivity.
CHANGE WI-FI STATE Allows the app to connect to and disconnect from Wi-Fi access
points, and to make changes to configured Wi-Fi networks.
-- Update --
I also found that the Android Package Manager pretty much just deletes a package if it is asked to do so. The only check it performs prior to doing so is whether the package being deleted is currently registered as having an active device admin:
try {
if (dpm != null && dpm.packageHasActiveAdmins(packageName)) {
Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
}
} catch (RemoteException e) {
}
See line 6900 in PackageManagerService in the AOSP source here.
For this, the application must be explicitly registered as a device admin by the user. See notes on device administration here: http://developer.android.com/training/enterprise/device-management-policy.html.
As per https://stackoverflow.com/a/26829978/1317564, here is some example code that does it: https://github.com/zzljob/android-uninstall-feedback/blob/master/library/jni/feedback-uninstall.c. This won't actually stop the uninstall from taking place, but does provide a way to catch it and take some action. I'm honestly surprised that this works in Android and the team may have plugged the gap in recent releases.