Get the application (Package) Size in Android -- Use of packagemanager (2)

Source: Internet
Author: User

Reprinted please indicate the source:Http://blog.csdn.net/qinjuning

 

 

Pass the first part<Obtain Application (Package) Information in Android ----- use of packagemanager (1)>For packagemanager and

The node Information Class xxxinfo defined in androidmanife. XML has some knowledge.

This section describes how to obtain the size of the installation package, including the cache size (cachesize), data size (datasize), and application size (codesize ).

Knowledge points in this section involve the aidl and Java reflection mechanisms. It is not difficult to understand.

The size information of the installation package is encapsulated in the packagestats class, which is very simple and has only a few fields:

Packagestats class:

Common fields:

Public long cachesize cache size

Public long codesize application size

Public long datasize data size

Public String packagename package name

 

PS: total application size = cachesize + codesize + datasize

That is to say, you only need to obtain the packagestats object corresponding to the installation package. However, the method provided is not displayed in the androidsdk.

Is it annoying to get this object? However, we can use the radiation mechanism to call the hidden functions (@ hide) in the system to obtain the information of each installation package.

The specific method is as follows:

Step 1The prototype of calling the getpackagesizeinfo () method through the radiation mechanism is:

/* @ Param packagename application package name * @ Param observer when the query package size operation is complete, the ongetstatscompleted () method in the ipackagestatsobserver class is called back ,*, the required packagestats object is also encapsulated in its parameters. * @ hide // hide the function flag */public abstract void getpackagesizeinfo (string packagename, ipackagestatsobserver observer );{//}

The internal call process is as follows. This knowledge point is more complex,

The getpackagesizeinfo method calls the getpackagesizeinfoli (packagename, pstats) method internally to obtain the package status.

The getpackagesizeinfoli method internally calls Installer. getsizeinfo (string pkgname, string apkpath, string fwdlockapkpath, packagestats

Pstats), and then return the package status information to the pstats parameter. The getsizeinfo method is internally used to connect to the server through a local socket,

Then, send a text string command to the server in the format of getsize apkpath fwdlockapkpath to the server. The server returns the result and resolves it to pstats.

. You can master this call knowledge chain.

 

 

Step 2To obtain a system-level service or class, we must add the aidl file formed by the Android system. There are two in total:

Ipackagestatsobserver. aidl and packagestats. aidl files. And place it in the path of the android. PM. content package.

Ipackagestatsobserver. aidl File

 

package android.content.pm;import android.content.pm.PackageStats;/** * API for package data change related callbacks from the Package Manager. * Some usage scenarios include deletion of cache directory, generate * statistics related to code, data, cache usage(TODO) * {@hide} */oneway interface IPackageStatsObserver {        void onGetStatsCompleted(in PackageStats pStats, boolean succeeded);}

Packagestats. aidl File

package android.content.pm;parcelable PackageStats;

Step 3Create a class to inherit from ipackagestatsobserver. Stub (pile,) it essentially implements the Binder Mechanism. When we call an instance of this class through getpackagesizeinfo (), and the function then starts the intermediate process to obtain the information size of the relevant package. After the scan is complete, finally, the query information is called back to the ongetstatscompleted (in packagestats pstats, Boolean succeeded) method of the class. The information size is encapsulated on this instance. For example:

// Bindler Mechanism Formed by aidl file service class public class pkgsizeobserver extends ipackagestatsobserver. stub {/*** callback function, * @ Param pstatus. The returned data is encapsulated in the packagestats object. * @ Param succeeded indicates that the callback is successful */@ overridepublic void ongetstatscompleted (packagestats pstats, boolean succeeded) throws RemoteException {// todo auto-generated method stub cachesize = pstats. cachesize; // cache size datasize = pstats. codesize; // data size codesize = pstats. codesize; // application size }}

Step 4Finally, we can obtain the pstats attributes and Their attribute values, and convert them by calling the system function formatter. formatefilesize (long size ).

Is a string measured in KB/MB.

Important: to obtain the application size through reflection, you must add the following permissions. Otherwise, a warning is reported and the actual value is not obtained.

  <uses-permission android:name="android.permission.GET_PACKAGE_SIZE"></uses-permission>

 

The flowchart is as follows:

Demo description:

Based on the first application, we added a new function. After clicking on any application, a dialog box showing the package size of the application is displayed.

As follows:

Engineering Drawing: Program:

1. dialg_app_size.xml File

<? XML version = "1.0" encoding = "UTF-8"?> <Linearlayout xmlns: Android = "http://schemas.android.com/apk/res/android" Android: Orientation = "vertical" Android: layout_width = "wrap_content" Android: layout_height = "wrap_content"> <linearlayout Android: layout_width = "wrap_content" Android: layout_height = "wrap_content" Android: Orientation = "horizontal"> <textview Android: layout_width = "100dip" Android: layout_height = "wrap_content" Android: TEXT = "cache size:"> </textview> <textview Android: layout_width = "100dip" Android: Id = "@ + ID/tvcachesize" Android: layout_height = "wrap_content"> </textview> </linearlayout> <linearlayout Android: layout_width = "wrap_content" Android: layout_height = "wrap_content" Android: orientation = "horizontal"> <textview Android: layout_width = "100dip" Android: layout_height = "wrap_content" Android: text = "data size:" ></textview> <textview Android: layout_width = "100dip" Android: Id = "@ + ID/tvdatasize" Android: layout_height = "wrap_content"> </textview> </linearlayout> <linearlayout Android: layout_width = "wrap_content" Android: layout_height = "wrap_content" Android: Orientation = "horizontal"> <textview Android: layout_width = "100dip" Android: layout_height = "wrap_content" Android: TEXT = "application size:"> </textview> <textview Android: layout_width = "100dip" Android: Id = "@ + ID/tvcodesize" Android: layout_height = "wrap_content"> </textview> </linearlayout> <linearlayout Android: layout_width = "wrap_content" Android: layout_height = "wrap_content" Android: orientation = "horizontal"> <textview Android: layout_width = "100dip" Android: layout_height = "wrap_content" Android: text = "total size:" ></textview> <textview Android: layout_width = "100dip" Android: Id = "@ + ID/tvtotalsize" Android: layout_height = "wrap_content"> </textview> </linearlayout>

2. The first part of the resource file or custom adapter is reused.

3. Add the aidl file, as shown above.

4. The main file mainactivity. Java is as follows:

Package COM. qin. appsize; import Java. lang. reflect. method; import Java. util. arraylist; import Java. util. collections; import Java. util. list; import COM. qin. appsize. appinfo; import android. app. activity; import android. app. alertdialog; import android. content. componentname; import android. content. context; import android. content. dialoginterface; import android. content. intent; import android. content. PM. ipackagestatso Bserver; import android. content. PM. packagemanager; import android. content. PM. packagestats; import android. content. PM. resolveinfo; import android. graphics. drawable. drawable; import android. OS. bundle; import android. OS. remoteException; import android. text. format. formatter; import android. util. log; import android. view. layoutinflater; import android. view. view; import android. widget. adapterview; import android. WID Get. listview; import android. widget. textview; import android. widget. adapterview. onitemclicklistener; public class mainactivity extends activity implements onitemclicklistener {Private Static string tag = "app_size"; private listview = NULL; private list <appinfo> mlistappinfo = NULL; layoutinflater infater = NULL; // global variable, save the information of the current query package private long cachesize; // cache size private long datasize; // data size PR Ivate long codesize; // application size private long totalsize; // total size @ override public void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); setcontentview (R. layout. browse_app_list); listview = (listview) findviewbyid (R. id. listviewapp); mlistappinfo = new arraylist <appinfo> (); queryappinfo (); // query all application information browseapplicationinfoadapter browseappadapter = new browseapplicationinfoadapte R (this, mlistappinfo); listview. setadapter (browseappadapter); listview. setonitemclicklistener (this);} // click the displayed dialog box to display the public void onitemclick (adapterview <?> Arg0, view, int position, long arg3) {// update the current package size information querypacakgesize (mlistappinfo. get (position ). getpkgname (); infater = (layoutinflater) mainactivity. this. getsystemservice (context. layout_inflater_service); view dialog = infater. inflate (R. layout. dialog_app_size, null); textview tvcachesize = (textview) dialog. findviewbyid (R. id. tvcachesize); // cache size textview tvdatasize = (textview) dialog. findvie Wbyid (R. id. tvdatasize); // data size textview tvcodesize = (textview) dialog. findviewbyid (R. id. tvcodesize); // application size textview tvtotalsize = (textview) dialog. findviewbyid (R. id. tvtotalsize); // total size // type conversion and value tvcachesize. settext (formatefilesize (cachesize); tvdatasize. settext (formatefilesize (datasize); tvcodesize. settext (formatefilesize (codesize); tvtotalsize. settext (formatefilesize (totalsize); // display custom Dialog Box alertdialog. builder = new alertdialog. builder (mainactivity. this); builder. setview (DIALOG); builder. settitle (mlistappinfo. get (position ). the size of getapplabel () + "is:"); builder. setpositivebutton ("OK", new dialoginterface. onclicklistener () {@ overridepublic void onclick (dialoginterface dialog, int which) {// todo auto-generated method stubdialog. cancel (); // cancel the display dialog box}); builder. create (). show ();} Pu BLIC void querypacakgesize (string pkgname) throws exception {If (pkgname! = NULL) {// use the radiation mechanism to obtain the hidden function of the packagemanager class. getpackagesizeinfo packagemanager PM = getpackagemanager (); // obtain the PM object try {// obtain the hidden function method getpackagesizeinfo = PM through the reflection mechanism. getclass (). getdeclaredmethod ("getpackagesizeinfo", String. class, ipackagestatsobserver. class); // call the function and assign parameters to it. After the call process is complete, the function getpackagesizeinfo of the pkgsizeobserver class will be called back. invoke (PM, pkgname, new pkgsizeobserver ();} catch (exception ex) {log. E (TAG, "No Suchmethodexception "); Ex. printstacktrace (); throw ex; // throw an exception} // bindler Mechanism Formed by aidl file service class public class pkgsizeobserver extends ipackagestatsobserver. stub {/*** callback function, * @ Param pstatus. The returned data is encapsulated in the packagestats object. * @ Param succeeded indicates that the callback is successful */@ overridepublic void ongetstatscompleted (packagestats pstats, boolean succeeded) throws RemoteException {// todo auto-generated method stub cachesize = pstats. Cachesize; // cache size datasize = pstats. datasize; // data size codesize = pstats. codesize; // application size totalsize = cachesize + datasize + codesize; log. I (TAG, "cachesize --->" + cachesize + "datasize ---->" + datasize + "codesize ---->" + codesize) ;}// system function, string Conversion long-string (Kb) Private string formatefilesize (Long SIZE) {return formatter. formatfilesize (mainactivity. this, size) ;}// obtain information about all started activities, similar to the launch interface. Public void queryappinfo () {packagemanager PM = This. getpackagemanager (); // get the packagemanager object intent mainintent = new intent (intent. action_main, null); mainintent. addcategory (intent. category_launcher); // obtain all resolveinfo objects by querying. list <resolveinfo> resolveinfos = PM. queryintentactivities (mainintent, 0); // sort by name by calling the system. // This sorting is very important. Otherwise, only system applications can be displayed, rather than third-party applications collections can be listed. sort (resolveinfos, new resolveinfo. d Isplaynamecomparator (PM); If (mlistappinfo! = NULL) {mlistappinfo. clear (); For (resolveinfo reinfo: resolveinfos) {string activityname = reinfo. activityinfo. name; // obtain the namestring pkgname = reinfo of the activity started by the application. activityinfo. packagename; // obtain the package name of the application string applabel = (string) reinfo. loadlabel (PM); // obtain the labeldrawable icon = reinfo of the application. loadicon (PM); // get the app icon // prepare intentintent launchintent = new intent (); launchintent for the app startup activity. setcomponent (New componentname (pkgname, activityname); // create an appinfo object and assign the value appinfo = new appinfo (); appinfo. setapplabel (applabel); appinfo. setpkgname (pkgname); appinfo. setappicon (icon); appinfo. setintent (launchintent); mlistappinfo. add (appinfo); // Add to list }}}}

This is the size of application information. The entire process is relatively simple. It is hard to understand the use of aidl files and the processing of callback functions.

After careful research, I can understand it.

 

Source code for use of packagemanager has been uploaded,: http://download.csdn.net/detail/qinjuning/3775856

 

 

 

 

 

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.