I am going to write a project that can hide another apps. I do research and find some useful code and it work well to hide my app. You can see my code below:
PackageManager pm = getPackageManager();
pm.setComponentEnabledSetting(getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
And the problem is that, I don't know how can I hide another apps. I have tried to do lot of research but I still cannot find any solution. So you can look at my code below (but it is not working to hide another apps, but to hide my own is working well):
PackageManager p = getPackageManager();
ComponentName com = new ComponentName("com.example.pro", "com.example.pro.classname");
p.setComponentEnabledSetting(com, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
I know that the first parameter for ComponentName is a package name of the app, and second parameter is a main activity name of the app that I want to hide. But it always force close every time i changed both of this parameters to another value. But if I change the first parameter to package name of my app and second parameter to the main activity name of my app, it work well like the first code I show above.
And I have some log that i got when my app force close below:
04-01 22:56:32.884 13339-13339/com.example.pro D/AndroidRuntime: Shutting down VM 04-01 22:56:32.884 13339-13339/com.example.pro E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.pro, PID: 13339
java.lang.SecurityException: Permission Denial: attempt to change component state from pid=13339, uid=10613, package uid=10464
at android.os.Parcel.readException(Parcel.java:1540)
at android.os.Parcel.readException(Parcel.java:1493)
at android.content.pm.IPackageManager$Stub$Proxy.setComponentEnabledSetting(IPackageManager.java:4073)
at android.app.ApplicationPackageManager.setComponentEnabledSetting(ApplicationPackageManager.java:1839)
at com.example.pro.MainActivity$1.onClick(MainActivity.java:142)
at android.view.View.performClick(View.java:5191)
at android.view.View$PerformClick.run(View.java:20931)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5944)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
So the problem is that, how can I hide another apps ? Any other code/method/suggest/example is fine. And i'd appreciate your help. Thanks.
I don't know how can I hide another apps
Fortunately, you cannot do that from an ordinary SDK app, for obvious security reasons. Ransomware authors would love the ability to do what you are proposing.
There are some hooks for doing what amounts to "hide another apps" in the device owner APIs IIRC, but they require the app be a device owner app, and that requires special work at the time the phone or tablet is first powered on after being purchased.
You may be able to accomplish what you want on a rooted device, and you certainly can do it with your own custom ROM. You could also create a home screen that "hides" apps by simply not showing them in its own launcher.
Related
I have an Android alarm clock app. I have the usual(?) alarm Intent -> receiver -> activity chain, whose last step creates a full-screen window and sounds the alarm.
All this works fine on pre-Oreo (API 26) versions of Android. But on Oreo, when the alarm fires, the System UI crashes and I get this exception in the emulator (slightly reformatted here):
12-12 01:15:02.864 9570-9570/com.android.systemui E/AndroidRuntime:
FATAL EXCEPTION: main
Process: com.android.systemui, PID: 9570
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.android.systemui.statusbar.phone.NavigationBarFragment.onKeyguardOccludedChanged(boolean)' on a null object reference
at com.android.systemui.statusbar.phone.StatusBar.onKeyguardOccludedChanged(StatusBar.java:3843)
at com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager.setOccluded(StatusBarKeyguardViewManager.java:277)
at com.android.systemui.keyguard.KeyguardViewMediator.handleSetOccluded(KeyguardViewMediator.java:1176)
at com.android.systemui.keyguard.KeyguardViewMediator.-wrap14(Unknown Source:0)
at com.android.systemui.keyguard.KeyguardViewMediator$4.handleMessage(KeyguardViewMediator.java:1531)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
As a possible clue, I've found that when I remove WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED from win.addFlags(), it doesn't crash -- but of course, it also doesn't show the alarm when the phone is locked.
I don't remember everything I've tried, but here are some of the things:
Locating Android's StatusBar.java source code to try to figure out exactly what thing is null that's not supposed to be. My Google-fu has failed me here, apparently.
Explicitly dismissing the keyguard with something like getSystemService(KeyguardManager.class).requestDismissKeyguard(this, null);.
Dismissing the keyguard by using WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD.
Both explicitly showing and explicitly hiding the status bar.
I think I tried some other method of showing the window when locked -- like, calling setShowWhenLocked(true) or something like that. But it didn't help, and anyway that method was added only in API 27, so it wouldn't solve the problem for API 26 even if it had worked.
Um ... other things I no longer remember.
None of these has had any effect.
Clearly this can work, because other alarm clock apps work under Oreo. What am I doing wrong?
Known bug that has been fixed it seems. Especially on the emulator.
So update the image used in the emulator.
It was present in the original Oreo release it seems according to the history if I interpret it correctly. Fixed in 8.0.0_r21 and later, present in 8.0.0_r17 and earlier and can't see any between those).
What exact versions of Oreo, have you tried 8.1 and/or various patch levels?
Because it's was fixed Sep 20 according to this commit, maybe another commit as well:
https://android.googlesource.com/platform/frameworks/base/+/8078996f4a8b1718a2ca56ff52fd1f4d522e7720%5E1..8078996f4a8b1718a2ca56ff52fd1f4d522e7720/
Possibly:
https://android.googlesource.com/platform/frameworks/base/+/9c4faa85f1bc4ffc2aa949da7b5d8439f4c638a2
Or their related source commit (noticed it was merge commits).
I quote one of them:
Fix random systemui crashes during boot
When trying to boot android in emulator, systemui may crash due to an
uninitialized value of mNavigationBar probably because of some race
condition during initialization caused by emulation performance issues
I was wondering if it's possible for third-party apps to dynamically add permission to the system or not. According to this book, it is possible through the use of the public addPermission() API; however, I am getting a SecurityException that says "java.lang.SecurityException: You either need MANAGE_USERS or CREATE_USERS permission to: query users". I just wanted to make sure it is really because the system doesn't allow it and not because I messed up something in my code. If it is the case, dynamic addition of permissions is not allowed to third-party apps not signed with the system certificate, it would be great if somebody could explain the reasoning behind this choice.
Here is how I add the permission programmatically:
public void addDynamicPermission() {
PermissionInfo pi = new PermissionInfo();
pi.name = "com.somedomain.permission.MY_PERMISSION";
pi.labelRes = R.string.permission_label;
pi.protectionLevel = PermissionInfo.PROTECTION_DANGEROUS;
final PackageManager packageManager = getApplicationContext().getPackageManager();
packageManager.addPermission(pi);
}
This is what I have in my manifest file:
<permission-tree android:name="com.somedomain.permission" />
and this is the full java stack for the exception:
FATAL EXCEPTION: main
Process: com.example.myapp, PID: 11824
java.lang.SecurityException: You either need MANAGE_USERS or CREATE_USERS permission to: query users
at android.os.Parcel.readException(Parcel.java:1684)
at android.os.Parcel.readException(Parcel.java:1637)
at android.content.pm.IPackageManager$Stub$Proxy.addPermission(IPackageManager.java:2870)
at android.app.ApplicationPackageManager.addPermission(ApplicationPackageManager.java:535)
at com.example.myapp.MainActivity.addDynamicPermission(MainActivity.java:183)
at com.example.myapp.MainActivity$6.onClick(MainActivity.java:64)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Thanks a lot!
TL;DR: The book is outdated and versions of Android newer than Lollipop do indeed require MANAGE_USERS or CREATE_USERS, both of which have a protectionLevel of 3 (signatureOrSystem).
Longer answer:
A while back, in the KitKat era, I wrote some test code similar to yours and I recall it working fine. That was a few years ago. I just fired up that old app in my current Nougat (7.0) environment and ended up with the exact same exception that you are seeing. Curious, I reinstalled KitKat (4.4.4), Lollipop (5.1), and Marshmallow (6.0) instances and tried the app on each.
For 4.4.4 and 5.1, everything works fine. I verified this by running the code and then checking for the existence of the custom permission as follows:
% adb shell dumpsys package packagename | grep -i com.example
...
Permission [com.example.permission.TEST_PERMISSION] (79c4d6d):
sourcePackage=com.example.myapplication
perm=Permission{2c725da2 com.example.permission.TEST_PERMISSION}
...
However, on 6.0 and 7.0, I'm getting the security exception. A quick check of androidxref.com indicates that the exception is coming from either the getPrimaryUser or getUsers method in UserManagerService.
getPrimaryUsers doesn't exist in 4.4.4 or 5.1, and getUsers has always been protected with checkManageOrCreateUsersPermission. Therefore, I think its reasonable to assume that the addPermission chain was modified starting in 6.0 to get a list of users for some reason. So addPermission does not require MANAGE_USERS or CREATE_USERS, but a method it now calls does.
Whether or not this additional access control check is intended and the reasoning behind why, are questions I cannot answer.
Getting an exception while launching Calendar on android device.
Logcat:
`
FATAL EXCEPTION: main
Process: com.google.android.calendar, PID: 7209
java.lang.IllegalArgumentException: the name must not be empty: null
at android.accounts.Account.<init>(Account.java:48)
at com.android.calendar.calendarlist.CalendarListUtils.processCursor(CalendarListUtils.java:155)
at com.android.calendar.calendarlist.SelectCalendarsAdapter.swapCursor(SelectCalendarsAdapter.java:160)
at com.android.calendar.calendarlist.DrawerFragment.onLoadFinished(DrawerFragment.java:244)
at com.android.calendar.calendarlist.DrawerFragment.onLoadFinished(DrawerFragment.java:55)
at android.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:483)
at android.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:451)
at android.content.Loader.deliverResult(Loader.java:144)
at android.content.CursorLoader.deliverResult(CursorLoader.java:109)
at android.content.CursorLoader.deliverResult(CursorLoader.java:97)
at android.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:265)
at android.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:92)
at android.os.AsyncTask.finish(AsyncTask.java:651)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Force finishing activity com.google.android.calendar/com.android.calendar.AllInOneCalendarActivity
`
Did anyone get this issue? Any help would be appreciated.
#Krishna,
Problem could be solved by setting --> App and clearing cache and data from the calendar app and do a force stop of the calendar app.
Also, there is one more app which is running for calendar called "Calendar storage", which could be found in Setting --> App and on the top menu click on Show System.
On this screen all system Apps will be visible. Click on Calendar storage and follow all the steps for clearing cache and data and force stop the app.
Now start the Calendar App, It will start without any issue.
This is an off-topic question. StackOverflow is intended for programming questions.
Anyway, just for the sake of answering, I think your Calendar app hasn't been granted permissions sufficient permissions.
Head over to Settings --> Apps --> Calendar.
Click on Permissions and enable all in it.
Now reboot the phone and try. It should work by now.
If it still doesn't work, try clearing it's data & cache and try again.
Background
We have a very large and very popular app with quite a few permissions.
The problem
It seems that on Motorola devices only (XT1254,XT1585,XT1565), with Android 5.1 and 5.1.1, we get crashes of this kind:
Fatal Exception: java.lang.SecurityException: Permission Denial: not allowed to send
broadcast com.motorola.intent.SYSTEM_DIALOG_POPUP from pid=15407, uid=10164
at android.os.Parcel.readException(Parcel.java:1546)
at android.os.Parcel.readException(Parcel.java:1499)
at android.app.ActivityManagerProxy.broadcastIntent(ActivityManagerNative.java:2864)
at android.app.ContextImpl.sendBroadcast(ContextImpl.java:1510)
at android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:382)
at android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:382)
at android.app.Dialog$2.run(Dialog.java:316)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
The above statistics were collected using Crashlytics.
Not sure if it is because of this, but one of the app's permission is "SYSTEM_ALERT_WINDOW", to be able to show content on top of other apps.
Thing is, this error seems to be because of Motorola's code itself, and I can't find anything about it over the Internet.
What I've tried
Apart from searching the Internet about this exception, I've also tried to find how to contact Motorola itself, including finding a developer forum, but I've failed in doing so.
I've also tried posting about this on Android's group:
https://code.google.com/p/android/issues/detail?id=201631
The question
What can be done in this case?
Why does it occur? Is it because of the permission? Is there a workaround ?
Hi actually me and my team mates faced the exact same problem when we were building an application which shows notes on top of other applications.
After researching for great lengths we found out that "SYSTEM_ALERT_WINDOW" permissions was made a signature permission and was causing problems by not letting the pop up appear from Lollipop 5.1
As a work around to it we need to explicitly ask the user to grant overlay permission for your app by doing this.
public void checkOverlayPermission(){
if(!Settings.canDrawOverlays(this)){
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:"+getPackageName()));
startActivityForResult(intent, ApplicationConstants.OVERLAY_PERMISSION);
}
}
Hope this helps
In my very simple app (based on the default Hello World app but with a button added) I try to open one of my phone's (a SE X10 Mini) preinstalled activities, like this:
Intent calendarIntent = new Intent();
calendarIntent.setClassName("com.sonyericsson.calendar","com.sonyericsson.calendar.dayview.DayActivity");
startActivity(calendarIntent);
However, it does not work, I get the following error in the log:
E/AndroidRuntime( 2215): java.lang.SecurityException: Permission Denial: starting Intent { cmp=com.sonyericsson.calendar/.dayview.DayActivity } from ProcessRecord{302cf238 2215:com.klibb.quickappointment/10079} (pid=2215, uid=10079) requires null
E/AndroidRuntime( 2215): at android.os.Parcel.readException(Parcel.java:1246)
E/AndroidRuntime( 2215): at android.os.Parcel.readException(Parcel.java:1234)
E/AndroidRuntime( 2215): at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:1157)
E/AndroidRuntime( 2215): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1449)
E/AndroidRuntime( 2215): at android.app.Activity.startActivityForResult(Activity.java:2661)
E/AndroidRuntime( 2215): at android.app.Activity.startActivity(Activity.java:2705)
E/AndroidRuntime( 2215): at com.klibb.quickappointment.QuickAppointmentActivity$1.onClick(QuickAppointmentActivity.java:25)
Is there anything I can do about this or is this type of code a no-no? When searching the web I see people changing the intent filters in what I assume is their own app, but I obviously cannot change anything in a preinstalled app.
Any ideas are welcome!
PS. What I am trying to achieve is to create a small program that directly launches the "New Apppointment" activity of my phone, to avoid going through two extra activities (start the default calendar, click a day, click an hour).
Mathias,
What you are trying to do is actually very simple. However, the information you need may be hard to get. You need to find three pieces of information (none of which require rewriting the pre-installed app)
1)Determine if the activity can be started by external components. This is done by using the Package Manager to provide you a list of all installed packages and their related data. You could also get a free package analyzer from the Android Market.
2)Get the permission required to start the app and add it to your manifest. Permissions are registered with Android OS, but getting required permissions for an external app is not done through the package manager, as far as I know.
3)Get the Intent Extras (data) required to start the activity if it is a "sub activity".
Your best bet for #2 & 3 are to contact Sony Ericsson or search on their website. Many Android phone manufacturers do provide open information about their products. If you are lucky, it may be a simple as including a file that they provide you via AIDL.
FuzzicalLogic
You have to have android.permission.READ_CALENDAR permission listed in the manifest. Some others may be required as well.