GVKun编程网logo

android – PackageManager.getInstalledPackages()返回空列表(android gettext返回类型)

22

想了解android–PackageManager.getInstalledPackages()返回空列表的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于androidgettext返回类型

想了解android – PackageManager.getInstalledPackages()返回空列表的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于android gettext返回类型的相关问题,此外,我们还将为您介绍关于Android APK应用安装原理解析之AndroidManifest使用PackageParser.parserPackage原理分析、Android Framework 分析 ---3PackageManager 分析、Android O PackageInstaller 解析、Android PackageManager 查询、安装、读取 meta 等用法的新知识。

本文目录一览:

android – PackageManager.getInstalledPackages()返回空列表(android gettext返回类型)

android – PackageManager.getInstalledPackages()返回空列表(android gettext返回类型)

使用PackageManager.getInstalledPackages()方法时,我遇到了一个非常奇怪的情况.我第一次启动活动时,会获得所有已安装软件包的有效列表.但是第二次启动我的活动时,我得到一个空列表……可能是什么导致了这个?

我使用此代码获取列表:
列出pkgList = getPackageManager().getInstalledPackages(PackageManager.GET_ACTIVITIES);

我正在构建1.6 SDK,兼容1.5

提前感谢任何建议/帮助…我对原因感到困惑,不能想到我做错了什么.

解决方法:

由于某种原因,可能需要在主应用程序线程上调用PackageManager.我没有尝试过使用AsyncTask.

更新2018-03-26:PackageManager通常可以在后台线程上调用,特别是getInstalledPackages().

Android APK应用安装原理解析之AndroidManifest使用PackageParser.parserPackage原理分析

Android APK应用安装原理解析之AndroidManifest使用PackageParser.parserPackage原理分析

本文实例讲述了Android APK应用安装之AndroidManifest使用PackageParser.parserPackage原理。分享给大家供大家参考,具体如下:

Android 安装一个APK的时候首先会解析APK,这里要做很多事情,其中一个事情就是解析Manifest.xml文件,并将所有APK的Manifest封装到各种对象中并保存在内存当中

解析Manifest的类是非常重要的,该类就是frameworks\base\core\java\android\content\pm\PackageParser

PackageManagerService会调用PackageParser.parserPackage方法来解析APK清单,下面开始分析PackageParser的实现:

PackageParser是使用的XMLPullParser工具来对XML进行解析的,然后分别通过android.content.pm下各种xxxInfo类来进行封装:

public Package parsePackage(File sourceFile,String destCodePath,displayMetrics metrics,int flags) {
//最后要跑出的解析错误信息
mParseError = PackageManager.INSTALL_SUCCEEDED;
//获得要解析的文件的路径
marchiveSourcePath = sourceFile.getPath();
//如果要解析的不是文件类型就跳过并且返回该方法
if (!sourceFile.isFile()) {
  Log.w(TAG,"Skipping dir: " + marchiveSourcePath);
  //更新错误信息
  mParseError = PackageManager.INSTALL_PARSE_Failed_NOT_APK;
  return null;
}
//如果文件不是以.apk结尾并且flag没有确定一定是APK,那么也返回
if (!isPackageFilename(sourceFile.getName())
    && (flags&PARSE_MUST_BE_APK) != 0) {
  if ((flags&PARSE_IS_SYstem) == 0) {
    // We expect to have non-.apk files in the system dir,// so don't warn about them.
    Log.w(TAG,"Skipping non-package file: " + marchiveSourcePath);
  }
  //更新错误信息
  mParseError = PackageManager.INSTALL_PARSE_Failed_NOT_APK;
  return null;
}
if ((flags&PARSE_CHATTY) != 0 && Config.LOGD) Log.d(
  TAG,"Scanning package: " + marchiveSourcePath);
XmlResourceParser parser = null;
AssetManager assmgr = null;
boolean assetError = true;
try {
  assmgr = new AssetManager();
  //将一个文件添加到AssetManager中并返回一个唯一标识
  int cookie = assmgr.addAssetPath(marchiveSourcePath);
  if(cookie != 0) {
    //通过标识去AssetManager中找到标识对应资源中的Manifest清单文件,并返回一个XML的解析器
    parser = assmgr.openXmlResourceParser(cookie,"AndroidManifest.xml");
    //走到这里证明一切顺利
    assetError = false;
  } else {
    Log.w(TAG,"Failed adding asset path:"+marchiveSourcePath);
  }
} catch (Exception e) {
  Log.w(TAG,"Unable to read AndroidManifest.xml of "
      + marchiveSourcePath,e);
}
if(assetError) {
  if (assmgr != null) assmgr.close();
  mParseError = PackageManager.INSTALL_PARSE_Failed_BAD_MANIFEST;
  return null;
}
String[] errorText = new String[1];
Package pkg = null;
Exception errorException = null;
try {
  // XXXX todo: need to figure out correct configuration.
  Resources res = new Resources(assmgr,metrics,null);
  //这个是真正在解析的package的方法,是private method
  pkg = parsePackage(res,parser,flags,errorText);
} catch (Exception e) {
  errorException = e;
  mParseError = PackageManager.INSTALL_PARSE_Failed_UNEXPECTED_EXCEPTION;
}
if (pkg == null) {
  if (errorException != null) {
    Log.w(TAG,marchiveSourcePath,errorException);
  } else {
    Log.w(TAG,marchiveSourcePath + " (at "
        + parser.getPositionDescription()
        + "): " + errorText[0]);
  }
  parser.close();
  assmgr.close();
  if (mParseError == PackageManager.INSTALL_SUCCEEDED) {
    mParseError = PackageManager.INSTALL_PARSE_Failed_MANIFEST_MALFORMED;
  }
  return null;
}

parserPackage调用了重载的另外一个parserPackage

private Package parsePackage(
    Resources res,XmlResourceParser parser,int flags,String[] outError)
    throws XmlPullParserException,IOException {
    AttributeSet attrs = parser;
    //每次调用这个方法时候清空这些变量
    mParseInstrumentationArgs = null;
    mParseActivityArgs = null;
    mParseServiceArgs = null;
    mParseProviderArgs = null;
    //这里调用这个方法获得包名
    String pkgName = parsePackageName(parser,attrs,outError);
    if (pkgName == null) {
      mParseError = PackageManager.INSTALL_PARSE_Failed_BAD_PACKAGE_NAME;
      return null;
    }
    int type;
    final Package pkg = new Package(pkgName);
    boolean foundApp = false;
    //从资源里获得AndroidManifest的数组
    TypedArray sa = res.obtainAttributes(attrs,com.android.internal.R.styleable.AndroidManifest);
    //继续挖掘出版本号
    pkg.mVersionCode = sa.getInteger(
        com.android.internal.R.styleable.AndroidManifest_versionCode,0);
    //获取版本名
    pkg.mVersionName = sa.getNonConfigurationString(
        com.android.internal.R.styleable.AndroidManifest_versionName,0);
    if (pkg.mVersionName != null) {
      pkg.mVersionName = pkg.mVersionName.intern();
    }
    //获得sharedUserId
    String str = sa.getNonConfigurationString(
        com.android.internal.R.styleable.AndroidManifest_sharedUserId,0);
    if (str != null && str.length() > 0) {
      //验证包名是否符合规则
      String nameError = validateName(str,true);
      if (nameError != null && !"android".equals(pkgName)) {
        outError[0] = "<manifest> specifies bad sharedUserId name \""
          + str + "\": " + nameError;
        mParseError = PackageManager.INSTALL_PARSE_Failed_BAD_SHARED_USER_ID;
        return null;
      }
      pkg.mSharedUserId = str.intern();
      pkg.mSharedUserLabel = sa.getResourceId(
          com.android.internal.R.styleable.AndroidManifest_sharedUserLabel,0);
    }
    sa.recycle();
    //安装的位置
    pkg.installLocation = sa.getInteger(
        com.android.internal.R.styleable.AndroidManifest_installLocation,PARSE_DEFAULT_INSTALL_LOCATION);
    // Resource boolean are -1,so 1 means we don't kNow the value.
    int supportsSmallScreens = 1;
    int supportsnormalScreens = 1;
    int supportsLargeScreens = 1;
    int resizeable = 1;
    int anyDensity = 1;
    int outerDepth = parser.getDepth();
    //关键时刻到了,真正的开始解析了
    while ((type=parser.next()) != parser.END_DOCUMENT
        && (type != parser.END_TAG || parser.getDepth() > outerDepth)) {
      if (type == parser.END_TAG || type == parser.TEXT) {
        continue;
      }
      String tagName = parser.getName();
      if (tagName.equals("application")) {
        if (foundApp) {
          if (RIGID_PARSER) {
            outError[0] = "<manifest> has more than one <application>";
            mParseError = PackageManager.INSTALL_PARSE_Failed_MANIFEST_MALFORMED;
            return null;
          } else {
            Log.w(TAG,"<manifest> has more than one <application>");
            XmlUtils.skipCurrentTag(parser);
            continue;
          }
        }
        foundApp = true;
        if (!parseApplication(pkg,res,outError)) {
          return null;
        }
      } else if (tagName.equals("permission-group")) {
        if (parsePermissionGroup(pkg,outError) == null) {
          return null;
        }
      } else if (tagName.equals("permission")) {
        if (parsePermission(pkg,outError) == null) {
          return null;
        }
      } else if (tagName.equals("permission-tree")) {
        if (parsePermissionTree(pkg,outError) == null) {
          return null;
        }
      } else if (tagName.equals("uses-permission")) {
        sa = res.obtainAttributes(attrs,com.android.internal.R.styleable.AndroidManifestUsesPermission);
        // Note: don't allow this value to be a reference to a resource
        // that may change.
        String name = sa.getNonResourceString(
            com.android.internal.R.styleable.AndroidManifestUsesPermission_name);
        sa.recycle();
       ...................................................
       ...................................................
       ...................................................篇幅有限

这里分别把每种不同的element用不同的小方法去解析,他们的调用顺序是:

这些小方法里其实还是有很多小技巧的,有兴趣的话可以细细品位

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android开发入门与进阶教程》、《Android调试技巧与常见问题解决方法汇总》、《Android基本组件用法总结》、《Android视图View技巧总结》、《Android布局layout技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。

Android Framework 分析 ---3PackageManager 分析

Android Framework 分析 ---3PackageManager 分析

在 windowphone,ios 和 android 中到目前为止,还是 android 的市场份额最大。个人认为除了 google 开源外,广大开发者早就了 android 的霸主地位。各位兄弟姐妹开发出各种各样的 apk,才组成 android 的广阔天下。本篇主要分析一下 android 系统是针对处理这些 apk 的,主要涉及到 pm 这块的代码。分析这种底层服务,最好从 android 的开启启动流程中开始分析。因为这样才能更清楚的了解服务的启动流程。

1. 在 SystemServer.java 中启动 PM

  android 开机启动后加载的第一个 java 的程序就是 SystemServer, 在包含 android 系统的最主要的一些底层服务。在 4.4kk 之前都是建一个 Thread 线程来启动。4.4KK 的启动机制就变了,具体后续的文章会讲解。

Installer installer = null;   
Slog.i(TAG, "Waiting for installd to be ready.");
            installer = new Installer();
            installer.ping();

 pm = PackageManagerService.main(context, installer,
                    factoryTest != SystemServer.FACTORY_TEST_OFF,
                    onlyCore);
            boolean firstBoot = false;
            try {
                firstBoot = pm.isFirstBoot();
            } catch (RemoteException e) {
            }
 public static final IPackageManager main(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        PackageManagerService m = new PackageManagerService(context, installer,
                factoryTest, onlyCore);
        ServiceManager.addService("package", m);
        return m;
    }
在 systemServer 中初始化了 Installer,并将它传入 PackageManagerService.main () 中。在 main 函数中将 pm 添加到 ServiceManager 中,供开发者调用。

2.PackageManagerService 启动安装分析

启动 PackageManagerService 后,主要完成以下几个步骤

2.1. 初始化 PackageSetting,设置 sharedUserID

 

mSettings = new Settings(context);
        mSettings.addSharedUserLPw("android.uid.system",
                Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);
        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, ApplicationInfo.FLAG_SYSTEM);
2.2. 获取屏幕参数:

WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
        Display d = wm.getDefaultDisplay();
        d.getMetrics(mMetrics);
2.3. 使用 HandlerThread 开启 packagemanager 工作线程和初始化 app 目录

mHandlerThread.start();
            mHandler = new PackageHandler(mHandlerThread.getLooper());

            File dataDir = Environment.getDataDirectory();
            mAppDataDir = new File(dataDir, "data");
            mAppInstallDir = new File(dataDir, "app");
            mAppLibInstallDir = new File(dataDir, "app-lib");
            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
            mUserAppDataDir = new File(dataDir, "user");
            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2.4. 加载 Framework 的主要 jar 和 BOOTCLASSPATH

mFrameworkDir = new File(Environment.getRootDirectory(), "framework");
            mDalvikCacheDir = new File(dataDir, "dalvik-cache");

            boolean didDexOpt = false;

            /**
             * Out of paranoia, ensure that everything in the boot class
             * path has been dexed.
             */
            String bootClassPath = System.getProperty("java.boot.class.path");
2.5. 安装 system/app,vendor/app 和 data/app 目录下 apk

// Collect all system packages.
            mSystemAppDir = new File(Environment.getRootDirectory(), "app");
            mSystemInstallObserver = new AppDirObserver(
                mSystemAppDir.getPath(), OBSERVER_EVENTS, true);
            mSystemInstallObserver.startWatching();
            scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);

            // Collect all vendor packages.
            mVendorAppDir = new File("/vendor/app");
            mVendorInstallObserver = new AppDirObserver(
                mVendorAppDir.getPath(), OBSERVER_EVENTS, true);
            mVendorInstallObserver.startWatching();
            scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);

......
 mAppInstallObserver = new AppDirObserver(
                    mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
                mAppInstallObserver.startWatching();
                scanDirLI(mAppInstallDir, 0, scanMode, 0);

其中具体如果安装代码在 scanDirLI()函数,最终调用 scanPackageLI()进行安装。在安装过程中会搜集 ApplicationInfo 和 ActivityInfo 信息,比较签名,匹配本地 so 的目录。

具体细节参看 PackageManagerService.java 中的

private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
            int parseFlags, int scanMode, long currentTime, UserHandle user) {

函数。

3. 在 Activity 使用 PackageManger 的分析

   我们在应用经常通过

   PackageManager pm = this.getPackageManager () 来获取 pm。这部分主要从它的来源来深入分析。

  由于我们在 Activity 中使用 this 来获取 pm,很容易想到到 context 类里去寻找实现。

 

/** Return PackageManager instance to find global package information. */
    public abstract PackageManager getPackageManager();
但是 context 是虚函数,因此要找到它的实现,由于 context 的实现采用 设计模式里面的 " 桥接模式 '' 因此很容易想到从 contextImpl.java 中寻找实现。

果然找到。

public PackageManager getPackageManager() {
        if (mPackageManager != null) {
            return mPackageManager;
        }

        IPackageManager pm = ActivityThread.getPackageManager();
        if (pm != null) {
            // Doesn''t matter if we make more than one instance.
            return (mPackageManager = new ApplicationPackageManager(this, pm));
        }

        return null;
    }

从代码上看获取 IPackageManager,还是需要从 ActivityThread 中获取。我在 Activity 里面获取吗出现在 ActivityThread 也不意外。

那我们就看看他是怎么实现的

public static IPackageManager getPackageManager() {
        if (sPackageManager != null) {
            //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
            return sPackageManager;
        }
        IBinder b = ServiceManager.getService("package");
        //Slog.v("PackageManager", "default service binder = " + b);
        sPackageManager = IPackageManager.Stub.asInterface(b);
        //Slog.v("PackageManager", "default service = " + sPackageManager);
        return sPackageManager;
    }
原来是通过 ServiceManager.getService ("package"). 从上你们的代码知道,这句其实就是获取 PackageManagerService 并赋给 IBinder ,成为一个 binder 对象。

通过 asInterface()函数,通过 binder 对象获取接口类 IPackageManager 的实例。并返回回去。

if (pm != null) {
            // Doesn''t matter if we make more than one instance.
            return (mPackageManager = new ApplicationPackageManager(this, pm));
        }


在接着同 ApplicationPackageManager 创建 PackageManager 对象。到此我们在 Activity 中就可以使用 pm 这个对象操作系统中的各种包。


4.Android 系统中 PackageManager 的关键类和 UML 的类图。

 在 pm 中主要涉及的类和路径如下:

 frameworks\base\services\java\com\android\server\pm\PackageManagerService.java 和 其他文件

frameworks\base\core\java\android\content\pm\IPackageManager.aidl

frameworks\base\core\java\android\app\ActivityThread.java ,context.java ,contextimpl.java

frameworks\base\core\java\android\content\pm\PackageManager.java





 






 



版权声明:本文为博主原创文章,未经博主允许不得转载。

Android O PackageInstaller 解析

Android O PackageInstaller 解析

Android O 8.0

 

1.src\com\android\packageinstaller\permission\mode\PermissionGroups.java

        @Override
        public List<PermissionGroup> loadInBackground() {
            ArraySet<String> launcherPkgs = Utils.getLauncherPackages(getContext());
            PermissionApps.PmCache pmCache = new PermissionApps.PmCache(
                    getContext().getPackageManager());

            List<PermissionGroup> groups = new ArrayList<>();
            Set<String> seenPermissions = new ArraySet<>();

            PackageManager packageManager = getContext().getPackageManager();
            List<PermissionGroupInfo> groupInfos = packageManager.getAllPermissionGroups(0);

            for (PermissionGroupInfo groupInfo : groupInfos) {
                // Mare sure we respond to cancellation.
                if (isLoadInBackgroundCanceled()) {
                    return Collections.emptyList();
                }

                // 得到权限组里的所有权限
                // Get the permissions in this group.
                final List<PermissionInfo> groupPermissions;
                try {
                    groupPermissions = packageManager.queryPermissionsByGroup(groupInfo.name, 0);
                } catch (PackageManager.NameNotFoundException e) {
                    continue;
                }

                boolean hasRuntimePermissions = false;

                // 查看某个权限组是否含有运行时权限
                // Cache seen permissions and see if group has runtime permissions.
                for (PermissionInfo groupPermission : groupPermissions) {
                    seenPermissions.add(groupPermission.name);
                    if ((groupPermission.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
                            == PermissionInfo.PROTECTION_DANGEROUS
                            && (groupPermission.flags & PermissionInfo.FLAG_INSTALLED) != 0
                            && (groupPermission.flags & PermissionInfo.FLAG_REMOVED) == 0) {
                        hasRuntimePermissions = true;
                    }
                }

                // 权限组里没有运行时权限,我们不感兴趣,继续循环查询
                // No runtime permissions - not interesting for us.
                if (!hasRuntimePermissions) {
                    continue;
                }

                // 如果权限组里含有运行时权限,则继续往下执行

                // 获取权限组的label
                CharSequence label = loadItemInfoLabel(groupInfo);
                Drawable icon = loadItemInfoIcon(groupInfo);

                // 根据权限组 新建 PermissionApps 对象
                PermissionApps permApps = new PermissionApps(getContext(), groupInfo.name, null,
                        pmCache);
                permApps.refreshSync();

                // 创建 PermissionGroup 对象
                // Create the group and add to the list.
                PermissionGroup group = new PermissionGroup(groupInfo.name,
                        groupInfo.packageName, label, icon, permApps.getTotalCount(launcherPkgs),
                        permApps.getGrantedCount(launcherPkgs));
                groups.add(group);
            }


            // 获取所有的安装包权限
            // Make sure we add groups for lone runtime permissions.
            List<PackageInfo> installedPackages = getContext().getPackageManager()
                    .getInstalledPackages(PackageManager.GET_PERMISSIONS);


            // We will filter out permissions that no package requests.
            Set<String> requestedPermissions = new ArraySet<>();
            for (PackageInfo installedPackage : installedPackages) {
                if (installedPackage.requestedPermissions == null) {
                    continue;
                }
                // 将安装包请求的权限加入到 列表中
                for (String requestedPermission : installedPackage.requestedPermissions) {
                    requestedPermissions.add(requestedPermission);
                }
            }

            for (PackageInfo installedPackage : installedPackages) {
                if (installedPackage.permissions == null) {
                    continue;
                }

                // 自定义的权限
                for (PermissionInfo permissionInfo : installedPackage.permissions) {
                    // If we have handled this permission, no more work to do.
                    if (!seenPermissions.add(permissionInfo.name)) {
                        continue;
                    }

                    // 关心的是 运行时权限
                    // We care only about installed runtime permissions.
                    if ((permissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
                            != PermissionInfo.PROTECTION_DANGEROUS
                            || (permissionInfo.flags & PermissionInfo.FLAG_INSTALLED) == 0) {
                        continue;
                    }

                    // 没有app使用那个自定义的权限
                    // If no app uses this permission,
                    if (!requestedPermissions.contains(permissionInfo.name)) {
                        continue;
                    }

                    CharSequence label = loadItemInfoLabel(permissionInfo);
                    Drawable icon = loadItemInfoIcon(permissionInfo);

                    PermissionApps permApps = new PermissionApps(getContext(), permissionInfo.name,
                            null, pmCache);
                    permApps.refreshSync();

                    // Create the group and add to the list.
                    PermissionGroup group = new PermissionGroup(permissionInfo.name,
                            permissionInfo.packageName, label, icon,
                            permApps.getTotalCount(launcherPkgs),
                            permApps.getGrantedCount(launcherPkgs));
                    groups.add(group);
                }
            }

            Collections.sort(groups);
            return groups;
        }

 

2.PermissionApps.java

/**
     * Refresh the state and do not return until it finishes. Should not be called while an {@link
     * #refresh async referesh} is in progress.
     */
    public void refreshSync() {
        mSkipUi = true;
        createMap(loadPermissionApps());
    }

 

3.

src\com\android\packageinstaller\permission\utils\EventLogger.java

/**
 * For each permission there are four events. The events are in the order of
 * #ALL_DANGEROUS_PERMISSIONS. The four events per permission are (in that order): "requested",
 * "granted", "denied", and "revoked".
 */
public class EventLogger {
    private static final String LOG_TAG = EventLogger.class.getSimpleName();

    /** All dangerous permission names in the same order as the events in MetricsEvent */
    private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
            Manifest.permission.READ_CALENDAR,
            Manifest.permission.WRITE_CALENDAR,
            Manifest.permission.CAMERA,
            Manifest.permission.READ_CONTACTS,
            Manifest.permission.WRITE_CONTACTS,
            Manifest.permission.GET_ACCOUNTS,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.CALL_PHONE,
            Manifest.permission.READ_CALL_LOG,
            Manifest.permission.WRITE_CALL_LOG,
            Manifest.permission.ADD_VOICEMAIL,
            Manifest.permission.USE_SIP,
            Manifest.permission.PROCESS_OUTGOING_CALLS,
            Manifest.permission.READ_CELL_BROADCASTS,
            Manifest.permission.BODY_SENSORS,
            Manifest.permission.SEND_SMS,
            Manifest.permission.RECEIVE_SMS,
            Manifest.permission.READ_SMS,
            Manifest.permission.RECEIVE_WAP_PUSH,
            Manifest.permission.RECEIVE_MMS,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_PHONE_NUMBERS,
            Manifest.permission.ANSWER_PHONE_CALLS,
            Manifest.permission.ACCEPT_HANDOVER);

    private static final List<String> ALL_APPOP_PERMISSIONS = Arrays.asList(
            Manifest.permission.ACCESS_NOTIFICATIONS,
            Manifest.permission.SYSTEM_ALERT_WINDOW,
            Manifest.permission.WRITE_SETTINGS,
            Manifest.permission.REQUEST_INSTALL_PACKAGES);

......

}

 

4.

src\com\android\packageinstaller\permission\utils\Utils.java

public static final String OS_PKG = "android";

    public static final String[] MODERN_PERMISSION_GROUPS = {  // 目前平台支持的权限组
            Manifest.permission_group.CALENDAR,
            Manifest.permission_group.CAMERA,
            Manifest.permission_group.CONTACTS,
            Manifest.permission_group.LOCATION,
            Manifest.permission_group.SENSORS,
            Manifest.permission_group.SMS,
            Manifest.permission_group.PHONE,
            Manifest.permission_group.MICROPHONE,
            Manifest.permission_group.STORAGE
    };

    private static final Intent LAUNCHER_INTENT = new Intent(Intent.ACTION_MAIN, null)
                            .addCategory(Intent.CATEGORY_LAUNCHER);

 

5.

DeviceUtils.java
public class DeviceUtils {
    public static boolean isTelevision(Context context) { // 电视
        int uiMode = context.getResources().getConfiguration().uiMode;
        return (uiMode & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION;
    }

    public static boolean isWear(final Context context) {// 穿戴设备
        return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
    }

    public static boolean isAuto(Context context) {// 汽车、自动设备
        return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
    }
}

 

 

 

 

 

Android PackageManager 查询、安装、读取 meta 等用法

Android PackageManager 查询、安装、读取 meta 等用法

一、查询手机上的所有 app

首先建立一个 Model

class ApplicationInfo {

    CharSequence title;

    Intent intent;

    Drawable icon;

    boolean filtered;

  //启动app初始化设置方式一
    final void setActivity(ComponentName className, int launchFlags) { 
        intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.setComponent(className);
        intent.setFlags(launchFlags);
    }

     //直接获得启动器,启动初始化方式二
   final void setActivity(Context cxt,String packageName, int launchFlags) {
    	 intent = cxt.getPackageManager().getLaunchIntentForPackage(packageName);
         intent.setFlags(launchFlags);
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof ApplicationInfo)) {
            return false;
        }

        ApplicationInfo that = (ApplicationInfo) o;
        return title.equals(that.title) &&
                intent.getComponent().getClassName().equals(
                        that.intent.getComponent().getClassName());
    }

    @Override
    public int hashCode() {
        int result;
        result = (title != null ? title.hashCode() : 0);
        final String name = intent.getComponent().getClassName();
        result = 31 * result + (name != null ? name.hashCode() : 0);
        return result;
    }
}

  第一种方式:

找到的代码只能查询到系统的 app,不能查询到全部 app,代码如下:

private void loadAppVerion1() {
    
        PackageManager manager = getPackageManager();

        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); //可能出现误差,因为Action任何Activity都可以相同
        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);

        final List<ResolveInfo> apps = manager.queryIntentActivities(mainIntent, 0);
        Collections.sort(apps, new ResolveInfo.DisplayNameComparator(manager));
        
        if (apps != null) {
            final int count = apps.size();

            if (mApplications == null) {
                mApplications = new ArrayList<ApplicationInfo>(count);
            }
            mApplications.clear();

            for (int i = 0; i < count; i++) {
                ApplicationInfo application = new ApplicationInfo();
                ResolveInfo info = apps.get(i);

                application.title = info.loadLabel(manager);
                application.setActivity(new ComponentName(
                        info.activityInfo.applicationInfo.packageName,
                        info.activityInfo.name),
                        Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
                application.icon = info.activityInfo.loadIcon(manager);

                mApplications.add(application);
            }
        }
}

第二种方式可获得所有的 app(推荐):

private void loadAppVerion2()
{
PackageManager packageManager = this.getPackageManager();
List<PackageInfo> packageInfoList = packageManager.getInstalledPackages(PackageManager.GET_ACTIVITIES);
     
if(packageInfoList!=null)
{
     if (mApplications == null)
     {
         mApplications = new ArrayList<ApplicationInfo>();
     }
     mApplications.clear();
             
     for (PackageInfo packageInfo : packageInfoList)
      {
        	ApplicationInfo application = new ApplicationInfo();
        	if(android.os.Build.VERSION.SDK_INT>=9)
        	{
        		application.icon  = packageInfo.applicationInfo.loadLogo(packageManager);
        	 }else{
        	    application.icon = packageInfo.applicationInfo.loadIcon(packageManager);
        	}
        	    application.title = packageInfo.applicationInfo.loadLabel(packageManager);
        	    String packageName = packageInfo.packageName;
        	    application.setActivity(this, packageName,Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
        	    mApplications.add(application);
		}
        }
 }

 

 

二、下面是关于 app 的安装

// 安装APK程序代码
private void openArcInStall(File file) {//传入app的下载路径构造的File文件即可

    Intent intent = new Intent();
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setAction(android.content.Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");
    startActivity(intent);
}

 

1. 查找可以分享文本的 app

/**
* 查询手机内所有支持分享的应用
* @param context
* @return
*/
public static List<ResolveInfo> getShareApps(Context context){
	    List<ResolveInfo> mApps = new ArrayList<ResolveInfo>();  
	    Intent intent=new Intent(Intent.ACTION_SEND,null);  
	    intent.addCategory(Intent.CATEGORY_DEFAULT);  
	    intent.setType("text/plain");  
	    PackageManager pManager = context.getPackageManager();
	    mApps = pManager.queryIntentActivities(intent,PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);  
	    
	    return mApps;  
	}

2. 查询最近打开过的应用(任务栈)

   private void searchRecents()
    {
        final PackageManager manager = getPackageManager();
        final ActivityManager tasksManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        final List<ActivityManager.RecentTaskInfo> recentTasks = tasksManager.getRecentTasks(40);

        final int count = recentTasks.size();
        final ArrayList<ApplicationInfo> recents = new ArrayList<ApplicationInfo>();
    }

三、读取 Meta 信息

1> application
<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <meta-data
            android:name="application_meta_data"
            android:value="application_meta_data_value" />  <!--可以关联资源ID, 支持多种数据类型 -->

ApplicationInfo info = null;
        
     try {
         info = getPackageManager()
                   .getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
     } catch (NameNotFoundException e) {
         e.printStackTrace();
     }
Log.v(TAG, "application meta data value:" + info.metaData.getString("application_meta_data"));
2> Activity 

<activity
        android:name="fyc.app.testandroid.MainActivity" >
        <meta-data
            android:name="activity_meta_data"
            android:value="activity_meta_data_value" />
</activity>

ActivityInfo info = null;
        
    try {
        info = getPackageManager()
                 .getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
    } catch (NameNotFoundException e) {
        e.printStackTrace();
    }
Log.v(TAG, "activity meta data value:" + info.metaData.getString("activity_meta_data"));
3> Service

<service android:name="fyc.app.testandroid.MyService" >
            <meta-data
                android:name="service_meta_data"
                android:value="service_meta_data_value" />
</service>

ServiceInfo info = null;
        
    try {
        info = getPackageManager()
                .getServiceInfo(new ComponentName(this, MyService.class), PackageManager.GET_META_DATA); 
    } catch (NameNotFoundException e) {
            e.printStackTrace();
    }
Log.v(TAG, "service meta data value:" + info.metaData.getString("service_meta_data"));
4> BroadcastReceiver

<receiver android:name="fyc.app.testandroid.MyReceiver" >
        <meta-data
                android:name="receiver_meta_data"
                android:value="receiver_meta_data_value" />
</receiver>

ActivityInfo info = null;
        
    try {
        info = getPackageManager()
                .getReceiverInfo(new ComponentName(this, MyReceiver.class), PackageManager.GET_META_DATA);
    } catch (NameNotFoundException e) {
        e.printStackTrace();
    }
Log.v(TAG, "receiver meta data value:" + info.metaData.getString("receiver_meta_data"));

 

关于android – PackageManager.getInstalledPackages()返回空列表android gettext返回类型的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于Android APK应用安装原理解析之AndroidManifest使用PackageParser.parserPackage原理分析、Android Framework 分析 ---3PackageManager 分析、Android O PackageInstaller 解析、Android PackageManager 查询、安装、读取 meta 等用法等相关内容,可以在本站寻找。

本文标签: