APK in QQ-like acquisition equipment and sharing

Keywords: Mobile

A few days ago, I saw a brilliant user interface application in my colleague. It was a little interesting, so I asked him to send me the APK. I want to decompile and see the code inside. As a result, the brothers searched for a long time in the mobile phone, and finally told me: there is no root in the mobile phone, where can not find the APK file. I asked him to try other machines, and the results were almost the same: otherwise it would be very troublesome to find, or it would be impossible to find them at all. At this time, the test sister said: mobile QQ has this function. I turned on the QQ of my mobile phone and saw it. Sure enough, I didn't notice it at ordinary times.

This function summarizes a little:
- Each item includes: the icon of the application, the name, the size of the installation file, and the last update time.
- Click on item to share its corresponding APK file

See here, the heart itchy, we can do such a similar thing?
Yes! Must be able! Otherwise, how can you raise your head in front of the test girl!?

Let's first get the apps already installed on the phone:

List<PackageInfo> packageInfoList = mPackageManager.getInstalledPackages(0);
  • 1

These applications are already lying here, and we will now step by step find out the relevant information for each application.

(1) Get the name of the application

    /**
     * Get the name of the application
     */
   public String getApplicationName(String packageName,PackageManager packageManager) {
        String applicationName=null;
        try {
            ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, 0);
            applicationName = (String) packageManager.getApplicationLabel(applicationInfo);
        } catch (PackageManager.NameNotFoundException e) {

        }
        return applicationName;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

Well, it's not difficult. A new driver can do it easily.

(2) the icon for obtaining applications

The name of the application is easy to get, so where is its icon?
Since the name of the application is used:

packageManager.getApplicationLabel(applicationInfo);

So is there a similar getApplication Icon method? As soon as we try to knock on the code, the AS prompt does have what we want.

packageManager.getApplicationIcon(ApplicationInfo info)

Well, it's a pleasure. We guessed it right. If you run the code, there's no problem with my Huawei mobile phone. Samsung for another try, right; then run with HTC, and you get a little green man - the default icon of the system! ____________ Then take the millet from the test girl. Same thing, we didn't get the corresponding icon of the application correctly.

Unhappy, drink water, silently open Du Niang to find the answer. See this way:

//.........
        Class pkgParserCls = Class.forName(PATH_PackageParser);
        Class[] typeArgs = new Class[1];
        typeArgs[0] = String.class;
        Constructor pkgParserCt = pkgParserCls.getConstructor(typeArgs);
        Object[] valueArgs = new Object[1];
        valueArgs[0] = apkPath;
        Object pkgParser = pkgParserCt.newInstance(valueArgs);
//.........
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Reflections are used. Complexity is not to say, but also affects efficiency. So don't do it when you have to. It seems that it is not possible to get the Icon of the application through PackageManager. Then try PackageInfo from another angle and see a field:

public ApplicationInfo applicationInfo;

The official document explains: Information collected from the application. That is to say, this field contains a lot of information about App. So, look at what's in Application Info, take a look, and see one thing:

//Retrieve the current graphical icon associated with this item.
 public Drawable loadIcon(PackageManager pm) {
        return pm.loadItemIcon(this, getApplicationInfo());
    }
  • 1
  • 2
  • 3
  • 4

This method can avoid the bug that can't get the application icon on some models. The machine at hand has been tried once, no problem. This little problem was solved and we went on.

(3) Getting the last update time of the application
This is easy, too. PackageInfo has corresponding fields:

public long lastUpdateTime;

Of course, this value is a millisecond value, which needs to be converted into the date format required by the project using SimpleDateFormat.
In some cases, you also need to get the first installation time of the application, and there are corresponding fields in PackageInfo:

public long firstInstallTime;

Similarly, it needs to be formatted.

(4) Get Apk file size
To get the Apk file size, you must first find the Apk file. It's like I want to go shopping with my sister on the weekend if I have to have a sister. (Stop, no more, tears fall on the keyboard.)
But where on earth is it? It's impossible to imagine using PackageManager, which has no method at all similar to getApplication Apk ().
Then what shall I do? Oh, remember the ApplicationInfo field in PackageInfo mentioned earlier? Let's continue to look inside to see if there is any harvest, and find a field in line 501 of the source code:

public String sourceDir;

The official document describes this: Full path to the base APK for this application. Uh huh, bingo! Find it, it represents the full path of the APK file. Document path has been obtained, everything is easy to do (just like knowing where my sister lives, you can... ).

File apkFile = new File(packageInfo.applicationInfo.sourceDir);

We encapsulate the path into a file and then get its size.

apkFile.length() / 1024 / 1024

Here the file size is converted to MB units, such as the pea pod APK file of 6.46MB.

Okay, we've all found what we want. Let's just use a ListView to show the relevant information of each APK as an item. There is a small problem to note: Getting APK information from mobile phones is a time-consuming process, so we need to do this in sub-threads.

Okay, look at the results.

We then click on item to share the Apk file:

 private class ItemClickListenerImpl implements AdapterView.OnItemClickListener{
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            File apkFile = mAppInfoList.get(position).getApkFile();
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_SEND);
            intent.setType("*/*");
            intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(apkFile));
            startActivity(intent);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Here the Apk file is placed in intent and then the system's own sharing function can be invoked.

The interface has been made and the function has been realized. Looking back, it's not very difficult. The difficulty is that we don't know -- we don't know exactly where its icon and Apk files are. It reminds me of a passage from Rumsfeld:

We also know there are known unknowns; that is to say we know there
are some things we do not know. But there are also unknown unknowns –
the ones we don't know we don't know.

Hey hey, we won't, just don't know.

Posted by pdmiller on Thu, 09 May 2019 22:56:38 -0700