title: How do launcher apps uninstall apps in the background?
body: <h2>Background</h2>
  
  <p>I have a spare time app that one of its main features is to easily uninstall apps.</p>
  
  <h2>The problem</h2>
  
  <p>I'm using a very basic API for uninstalling apps, which for the user seems like 2 steps: confirm uninstalling, and seeing some dialog showing the uninstall-process.</p>
  
  <p>I've noticed that on some launcher apps (such as Nova launcher and Pixel Launcher), upon uninstall, they show only one step, of confirmation of uninstalling the chosen app.</p>
  
  <p>Here's how it looks via my app and from the normal, built in screen of app-info. First you see this:</p>
  
  <p><a href="https://i.stack.imgur.com/QXcJb.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/QXcJb.png" alt="enter image description here"></a></p>
  
  <p>and then this:</p>
  
  <p><a href="https://i.stack.imgur.com/GWk0F.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/GWk0F.png" alt="enter image description here"></a></p>
  
  <p>However, on the launcher, you see just this:</p>
  
  <p><a href="https://i.stack.imgur.com/N0snb.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/N0snb.png" alt="enter image description here"></a></p>
  
  <p>And shortly after, the app is gone without you seeing anything in between.</p>
  
  <h2>What I've found</h2>
  
  <p>Only way I know of uninstalling an app in the background, is by using root, but that's not what those apps do.</p>
  
  <p>Here's what I use for the normal uninstall procedure:</p>
  
  <pre><code>public static Intent prepareUninstallAppIntent(@NonNull final Context context, @NonNull final String packageName) {
      final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, Uri.fromParts("package", packageName, null));
      intent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
      intent.putExtra("android.intent.extra.UNINSTALL_ALL_USERS", true);
      return null;
  }
  </code></pre>
  
  <h2>The questions</h2>
  
  <ol>
  <li><p>How do the launcher apps only show the confirmation dialog alone, and perform the uninstall in the background?</p></li>
  <li><p>Is it a new API? If so, from which version? And where can I read about it?</p></li>
  </ol>
  
  <p>EDIT: this doesn't matter anymore. Got to see how it works.</p>
  
  <hr>
  
  <p>I've now found, by looking at <a href="https://github.com/LawnchairLauncher/Lawnchair" rel="nofollow noreferrer"><strong>Lawnchair</strong></a> launcher app code, that it's a bit similar to what I did:</p>
  
  <pre><code>public static boolean startUninstallActivity(
          final Launcher launcher, ItemInfo info, DropTargetResultCallback callback) {
      Pair&lt;ComponentName, Integer&gt; componentInfo = getAppInfoFlags(info);
      ComponentName cn = componentInfo.first;
  
      final boolean isUninstallable;
      if ((componentInfo.second &amp; AppInfo.DOWNLOADED_FLAG) == 0) {
          // System applications cannot be installed. For now, show a toast explaining that.
          // We may give them the option of disabling apps this way.
          Toast.makeText(launcher, R.string.uninstall_system_app_text, Toast.LENGTH_SHORT).show();
          isUninstallable = false;
      } else {
          Intent intent = new Intent(Intent.ACTION_DELETE,
                  Uri.fromParts("package", cn.getPackageName(), cn.getClassName()))
                  .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                          | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
          intent.putExtra(Intent.EXTRA_USER, info.user);
          launcher.startActivity(intent);
          isUninstallable = true;
      }
      if (callback != null) {
          sendUninstallResult(
                  launcher, isUninstallable, componentInfo.first, info.user, callback);
      }
      return isUninstallable;
  }
  </code></pre>
  
  <p>It works there the same as on other launchers, so, to me it seemed they added the part of uninstalling for current user (got it using <code>android.os.Process.myUserHandle();</code> ) .</p>
  
  <p>But I tried it anyway. Seems to work, so what I tried then is to remove more and more code till I got something that works without weird things.</p>
  
  <p>Here's the minimal code:</p>
  
  <pre><code>    final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, Uri.fromParts("package", packageName, null));
  </code></pre>
  
  <p>and you just use startActivity, instead of startActivityForResult.</p>
  
  <p>Yes. It's that short, and I wonder how long I've missed using this...</p>
  
  <p>But now I got other questions:</p>
  
  <ol>
  <li><p>What is the <code>cn.getClassName()</code> and the <code>Intent.EXTRA_USER</code> used for? </p></li>
  <li><p>From which version of Android will this code uninstall the app in the background?</p></li>
  <li><p>Is there any difference between ACTION_UNINSTALL_PACKAGE and ACTION_DELETE here?</p></li>
  <li><p>I removed all flags and it still seem to do the same exact job, without a task that's in the history. Are they really needed?</p></li>
  <li><p>Are there more ways to uninstall apps? Maybe in a batch?</p></li>
  </ol>