I have been through with many Google solutions but not any solution is able to resolve my problem. What I am trying to do is firing a window for user to enter pin/password while he is trying to uninstall my application.
I saw this link, but I am facing 2 issues with this solution these are as follow:
I registered broadcast receiver in My Application, when I open "My Application" in settings, it does not seems working but working fine with other apps. My Code below:
public void onReceive(Context context, Intent intent) {
/// fetching package names from extras
String[] packageNames = intent.getStringArrayExtra("android.intent.extra.PACKAGES");
if(packageNames!=null){
for(String packageName: packageNames){
if(packageName!=null && packageName.equals("com.android.systemapplication")){
// User has selected our application under the Manage Apps settings
// now initiating background thread to watch for activity
new ListenActivities(context).start();
}
}
}
}
When I replaced package name with some different package name that settings screen can detect in broadcast receiver then in run(thread) it is not detecting uninstaller activity, Please see my ListenActivities as below:
public void run(){
Looper.prepare();
while(!exit){
// get the info from the currently running task
List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(MAX_PRIORITY);
String activityName = taskInfo.get(0).topActivity.getClassName();
Log.d("topActivity", "CURRENT Activity ::"
+ activityName);
// here "activityName" is "com.android.launcher" if I select
// package name it is "com.android.launcher2.launcher".
if (activityName.equals("com.android.packageinstaller.UninstallerActivity")) {
// User has clicked on the Uninstall button under the Manage Apps settings
//do whatever pre-uninstallation task you want to perform here
exit = true;
Toast.makeText(context, "Done with preuninstallation tasks... Exiting Now", Toast.LENGTH_SHORT).show();
} else if(activityName.equals("com.android.settings.ManageApplications")) {
// back button was pressed and the user has been taken back to Manage Applications window
// we should close the activity monitoring now
exit=true;
}
}
Looper.loop();
}
I saw many solutions but no success. if it is deprecated then please show some Android documentation because I can see antivirus can do same as what I am asking for. Code would be more helpful. ? Any help would be helpful.
Related
I have created demo app for One Signal Push notification. It's work fine on emulator but when testing on real device. There is one problem when application closed did not receive push notification.
implementation code is like as following:
TestDemo.java file
public class TestDemo extends Application {
#Override
public void onCreate() {
super.onCreate();
OneSignal.setLogLevel(OneSignal.LOG_LEVEL.DEBUG, OneSignal.LOG_LEVEL.WARN);
OneSignal.startInit(this)
.setNotificationOpenedHandler(new ExampleNotificationOpenedHandler())
.autoPromptLocation(true)
.init();
}
private class ExampleNotificationOpenedHandler implements OneSignal.NotificationOpenedHandler {
#Override
public void notificationOpened(OSNotificationOpenResult result) {
OSNotificationAction.ActionType actionType = result.action.type;
JSONObject data = result.notification.payload.additionalData;
String customKey;
if (data != null) {
customKey = data.optString("customkey", null);
if (customKey != null)
Log.i("OneSignalExample", "customkey set with value: " + customKey);
}
if (actionType == OSNotificationAction.ActionType.ActionTaken)
Log.i("OneSignalExample", "Button pressed with id: " + result.action.actionID);
}
}
}
MainActivity.java file
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
OneSignal.idsAvailable(new OneSignal.IdsAvailableHandler() {
#Override
public void idsAvailable(String userId, String registrationId) {
Log.d("UserId : ", userId);
Log.d("Reg Id : ", registrationId);
}
});
}
and also given permission as suggestion on documentation
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Please help if any solution for that...
Thanks...
The following are reasons why notifications may show as delivered on the OneSignal dashboard or API, but are not visible on your device or website:
The app is currently In Focus
By default, notifications will not be displayed on the device if your app is currently "in focus" (open and visible). However, you can call inFocusDisplaying with InAppAlert to show notifications as alert boxes in your app, or Notification to display the notification.
The app is Force Stopped
When an app is in a "Force Stopped" state most events including GCM/FCM messages for push notifications will not be received. An app can be placed in this state in the following ways.
From Settings > Apps, "Force Stop" is pressed.
Long pressing the back button on some devices.
Using a 3rd party task killer like Greenify.
App is closed on some Huawei, Xiaomi, or Sony devices due their custom Android tweaks. The following device settings can be changed to prevent this.
* Huawei - Go to Settings > "Protected apps", check your app.
* Xiaomi - Make sure "Auto-start" property enabled for your app in the settings.
* Sony - Tap on the battery icon. Go to Power Management > STAMINA mode > Apps active in standby > Add your app.
To confirm your app state is the issue send a few notifications and check for the following GCM logcat entry.
W/GCM-DMM: broadcast intent callback: result=CANCELLED forIntent { act=com.google.android.c2dm.intent.RECEIVE pkg=com.onesignal.example (has extras) }
Some device manufactures will white list apps from going into the force closed state. Example such as Gmail and Whatsapp.
You have network issues
The network / WiFi you're connected to may have closed your connection to Google servers'. Try disabling and re-enabling your internet connection. See this post for more details.
I have problem in App Uninstallation. My Application Need is When user want to do application uninstall then open a login screen. when user press your right Password then show a Uninstall App System Alert. And That Alert Have two condition (1) OK
(2) cancel. when user click "OK" then app uninstall correctly. When App Uninstalled Correctly them get a BroadcastReciver Like "android.intent.action.PACKAGE_REMOVED" . if User click a Cancel Button "How we get Any BroadcastReciver Or Notification in an android".
public class CustomBroadcastReceiver extends BroadcastReceiver {
/**
* This method captures the event when a package has been removed
*/
#SuppressWarnings("static-access")
#Override
public void onReceive(Context context, Intent intent)
{
System.out.println("Hello from CustomBroadcastReceiver");
if (intent != null) {
String action = intent.getAction();
System.out.println("L1123 : "+action);
if (intent.getAction().equals("android.intent.action.PACKAGE_REMOVED"))
{
SMContants.Removed_Apps=true;
//Log the event capture in the log file ...
SMContants.App_uninstalled=false; /// Important Line
System.out.println("The package has been removed");
}
else
{
SMContants.App_uninstalled=false;
}
}
}
}
when I am Write a Important Line
I want when user click on Cancel Button then value of Variable
SMContants.App_uninstalled=false;
How we Get the App Uninstallation Cancel Button Event
I have a service that turn on my app sometimes, the main activity prompt Dialog message to user sometimes,
after the user answer YES\NO I call to finish() to close the app.
my problem is when the message is shown, user answers it and app was call to finish() and when you look in the recent history you played before (in samsung for example you press long on home button) you will see my app along with other apps user started.
when you push it to open it again the Dialog show again..
How to show the activity when launched from recent app without showing the Dialog
public void dialog_1(){
myDialogViewN = new MyDialogViewNegativeTime(MainActivity.this);
// Setting vibrator
vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
long[] pattern= {100, 1000};
vibrator.vibrate( pattern,0 );
// Setting 2 Dialog Listeners
myDialogViewN.setOnDialogListener(new DialogListener() {
#Override
public void onNegativeClick()
{
// Stopping Vibraror
if (vibrator.hasVibrator()){
vibrator.cancel();
vibrator = null;
}
initialize_DialogToUser(); /// ??
SendDataToService(3); //doesn't want reminder
myDialogViewN.dismissDialog();
waitForDialogAnswer=false;
finish();
}
#Override
public void onPositiveClick()
{
// Stopping Vibrator
if (vibrator.hasVibrator()){
vibrator.cancel();
vibrator = null;
}
initialize_DialogToUser();
SendDataToService(1); //remind!
myDialogViewN.dismissDialog();
squre.setImageResource(R.drawable.triangle_red2);
waitForDialogAnswer=false;
finish();
} });
myDialogViewN.show();
}
#Override
public void onDestroy()
{
super.onDestroy();
// close/stop running application on background
int id= android.os.Process.myPid();
android.os.Process.killProcess(id);
}
finally i find solution,
the problem was when you open the app from history - the last intent that comes from service to your activity stay there and not goes, in contrary for openning the app by click it's own icon. (different openning ways).
my solution:
send 2 intent's from service to activity,
the first - with what you really need.
the second - after you receive your answer in the service. in the second you will not put any data! it is a mere intent that comes to change the "stuck" intent in history-app open way.
maby it is stupid, but it's the only solution i found :)
I'm working on an MDM (Mobile Device Management) app for android, but I have a huge problem and it's that the user can disable my app from within settings>security>device administrators. The only thing I can do about it, is display a warning message by overriding the onDisableRequested(...) method in my DeviceAdminReceiver sub-class, but I really want to prevent the user from disabling my admin app altogether.
I've tried to override the onReceive(...) method, so that nothing happens when the actions ACTION_DEVICE_ADMIN_DISABLE_REQUESTED and ACTION_DEVICE_ADMIN_DISABLED are broadcasted by the system, but so far it has not worked. Apparently some other component is processing those actions before they arrive to my onReceive(...) method and I dont know why. I would like to be able to show my own custom dialog indicating that the user can´t disable the administrator app from this section, and maybe even ask the user to set an admin password to do it.
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_PASSWORD_CHANGED.equals(action)) {
onPasswordChanged(context, intent);
} else if (ACTION_PASSWORD_FAILED.equals(action)) {
onPasswordFailed(context, intent);
} else if (ACTION_PASSWORD_SUCCEEDED.equals(action)) {
onPasswordSucceeded(context, intent);
} else if (ACTION_DEVICE_ADMIN_ENABLED.equals(action)) {
onEnabled(context, intent);
} else if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) {
} else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) {
} else if (ACTION_PASSWORD_EXPIRING.equals(action)) {
onPasswordExpiring(context, intent);
}
}
I need help to solve this issue.
Thanks,
You can do this from Android 5 Lollipop with the new device-owner mode. Then the Device-Administrator option in greyed-out and the user cannot disable it, thus not uninstall the device-admin App.
However note that installing a device-owner App is not easy, it has to be done at provision-time with NFC, or from a computer with adb (handy for testing but not for deployment), or with a MDM what is your case...
There is no way to prevent user from disabling, and it's his right.
But to get sure that the user himself is actually removing the admin privilege, lock the device in onDisableRequested with his password and return something like "Someone tried to disable this app administrator feature. was it you and are you sure?".
Now if someone other than the real user try to disable it, he has to enter password before proceeding.
I agree with FoamyGuy, you are not allowed to prevent disabling admin. Otherwise, your application can't be uninstalled at all.
Generally speaking a user grants to some application device admin rights and can remove these rights at any moment.
Any broadcasts are just notifications, you can't handle it and prevent some actions from happening. The system just says to listening apps that something is going on.
Also, read this:
How to wipe Android device when device admin is deactivated?
There is a workaround to prevent disabling the device administrator.
When the user initiates deactivation and we recieve ACTION_DEVICE_ADMIN_DISABLE_REQUESTED callback, we re-launch the settings activity intent.
A message is allowed by the OS to be displayed asking for confirmation from the user. According to Android OS rules, for about 5 seconds, no app is allowed to launch on top of this confirmation dialog. So basically the settings activity we tried to open will only launch after 5 seconds.
To pass these 5 seconds without allowing the user to confirm deactivation, the phone is locked by the device administrator repeatedly in a background thread. After 5 seconds when the user unlocks the device, 'Settings' activity will have been restarted.
The following code for Device Admin Broadcast Receiver Class illustrates the above method.
DevAdminReceiver.java
public class DevAdminReceiver extends DeviceAdminReceiver {
DevicePolicyManager dpm;
long current_time;
Timer myThread;
#Override
public void onEnabled(#NonNull Context context, #NonNull Intent intent) {
super.onEnabled(context, intent);
Log.d("Root", "Device Owner Enabled");
}
#Nullable
#Override
public CharSequence onDisableRequested(#NonNull Context context, #NonNull Intent intent) {
Log.d("Device Admin","Disable Requested");
Intent startMain = new Intent(android.provider.Settings.ACTION_SETTINGS);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(startMain);
dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
myThread = new Timer();
current_time = System.currentTimeMillis();
myThread.schedule(lock_task,0,1000);
return "Warning";
}
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) {
CharSequence res = onDisableRequested(context, intent);
if (res != null) {
dpm.lockNow();
Bundle extras = getResultExtras(true);
extras.putCharSequence(EXTRA_DISABLE_WARNING, res);
}
}else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) {
Log.d("Device Admin","Disabled");
}
}
// Repeatedly lock the phone every second for 5 seconds
TimerTask lock_task = new TimerTask() {
#Override
public void run() {
long diff = System.currentTimeMillis() - current_time;
if (diff<5000) {
Log.d("Timer","1 second");
dpm.lockNow();
}
else{
myThread.cancel();
}
}
};
}
Ensure force lock policy is set for the device admin in the resource file.
This is a purely a workaround and not an intended solution from the side of the developers. Apps which abuse device admin permissions are always promptly taken down from the Play Store when exposed.
Complete sample code is present in the following repo
https://github.com/abinpaul1/Android-Snippets/tree/master/PermanentDeviceAdministrator
Not a nice way to do this, but here an idea:
When you receive the callback ACTION_DEVICE_ADMIN_DISABLE_REQUESTED, kill the settings app.
(Search for task-killers to see how)
And make sure you don't kill the settings-app after the user entered the password.
If the settings app is gone, the user can't click the disable button.
I want to uninstall my application on button click. For this I am using following code.
Uri packageURI = Uri.parse("package:"+packageName);
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
startActivity(uninstallIntent);
It gives me result, but I want to delete directly without click on "Ok" button of dialog with message "This application will be Uninstalled".
I just want uninstalling application directly.
Uninstalling without user confirmation is not allowed to 3rd party applications.
As xDragonZ points out, a root process can crudely do this by literally removing the directory and leaving the package manager to deal with the loss, but that's not a very widely deployable solution, since AFAIK no devices ship with that capability for apps to run their own root helper process - that's a risky aftermarket modification.
Yes it is possible to uninstall a package in Android. Moreover you can also skip asking user to press OK button on uninstall screen. You can do it by using Accessibility service in Android.
public class MyAccessibilityService extends AccessibilityService {
private static final String TAG = MyAccessibilityService.class
.getSimpleName();
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.i(TAG, "ACC::onAccessibilityEvent: " + event.getEventType());
//TYPE_WINDOW_STATE_CHANGED == 32
if (AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED == event
.getEventType()) {
AccessibilityNodeInfo nodeInfo = event.getSource();
Log.i(TAG, "ACC::onAccessibilityEvent: nodeInfo=" + nodeInfo);
if (nodeInfo == null) {
return;
}
List<AccessibilityNodeInfo> list = nodeInfo
.findAccessibilityNodeInfosByViewId("com.android.settings:id/left_button");
for (AccessibilityNodeInfo node : list) {
Log.i(TAG, "ACC::onAccessibilityEvent: left_button " + node);
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
list = nodeInfo
.findAccessibilityNodeInfosByViewId("android:id/button1");
for (AccessibilityNodeInfo node : list) {
Log.i(TAG, "ACC::onAccessibilityEvent: button1 " + node);
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}
#Override
public void onServiceConnected() {
Log.i(TAG, "ACC::onServiceConnected: ");
}
#Override
public void onInterrupt() {
// TODO Auto-generated method stub
}
}
You should first look into the Android native PackageInstaller. I would recommendating you to update all the code you use.
Next step is to inspect PackageInstaller which is an normal class. You will find that uninstall function there. The bad news is that this needs Manifest.permission.DELETE_PACKAGES permission and its only granted to system apps. This means that this is not available directly to other developers. But we can access it using device owner permission.
This requires:
Android 6.0 or newer
Device owner permission to uninstall the package
Generally the DELETE_PACKAGES permission says:
Allows an application to delete packages.
Not for use by third-party applications.
Once your app gets the device owner permission, you can uninstall an package like this:
String appPackage = "com.your.app.package";
Intent intent = new Intent(getApplicationContext(),
getApplicationContext().getClass()); //getActivity() is undefined!
PendingIntent sender = PendingIntent.getActivity(getActivity(), 0, intent, 0);
PackageInstaller mPackageInstaller =
getActivity().getPackageManager().getPackageInstaller();
mPackageInstaller.uninstall(appPackage, sender.getIntentSender());
The code used available here:
PackageInstaller "Silent install and uninstall of apps by Device Owner” - Android M Preview