标签: android-package-managers

为每个 Android 版本安装 APK 的正确方法是什么?

我正在制作一个 APK 安装应用程序,并且经历了很多。特别是版本控制。为此,我查阅了一些帖子和 StackOverFlow。但现在所有的帖子让我更加困惑。那么,什么是正确的方法呢?

首先,请检查我下面关于每个版本安装的代码。让我们谈谈什么是正确的方法。

KitKat(API 19)、棒棒糖(API 21)、MashMellow(API 23)

fun installApkBelowNougat(apkFile: File) {
  val apkUri = Uri.fromFile(apkFile)
  val intent = Intent(Intent.ACTION_VIEW).apply {
    setDataAndType(apkUri, "application/vnd.android.package-archive")
    flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
  }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,所有解决方案都是相同的,我们必须使用Uri.fromFile(file)来获得Uri.

牛轧糖(API 24)

fun installApkInNougat(apkFile: File) {
  val apkUri = FileProvider.getUriForFile(applicationContext, applicationContext.packageName + ".fileProvider", apkFile)
  val intent = Intent(Intent.ACTION_VIEW).apply {
    setDataAndType(apkUri, "application/vnd.android.package-archive")
    flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
    addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
  }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们就不能再使用了Uri.fromFile(file)。因此,我们必须使用FileProvider“Nougat”来代替它。并且我们还必须<proivder/>在AndroidManifest.xml中这样写。

...
<provider
  android:name="androidx.core.content.FileProvider"
  android:authorities="${applicationId}.fileProvider"
  android:exported="false"
  android:grantUriPermissions="true">
     <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS" …
Run Code Online (Sandbox Code Playgroud)

android apk android-package-managers android-fileprovider

6
推荐指数
0
解决办法
1277
查看次数

getPackageManager().getInstalledPackages(PackageManager.GET_ACTIVITIES)返回null

如果我打电话

    PackageManager pm = getPackageManager () ;
    List<PackageInfo> pis = pm.getInstalledPackages (PackageManager.GET_PROVIDERS) ;
Run Code Online (Sandbox Code Playgroud)

我得到一个已安装软件包的列表,包括他们声明的任何提供者(即,pis [i] .providers可能是非null).

但是,如果我在标志中包含PackageManager.GET_ACITIVITIES,如

    PackageManager pm = getPackageManager () ;
    List<PackageInfo> pis = pm.getInstalledPackages (PackageManager.GET_ACTIVITIES | PackageManager.GET_PROVIDERS) ;
Run Code Online (Sandbox Code Playgroud)

我希望得到已安装包的"相同"列表,但pis [i] .activities也是非空的.但我没有,我得到一个空列表.

文档中没有提到的标志中包含PackageManager.GET_ACTIVITES有什么特别之处吗?

我目前的工作是将PackageManager.GET_ACTIVITIES从标志中删除,然后循环返回列表,如下所示:

    for (PackageInfo pi : pis) {
        try {
            PackageInfo tmp = pm.getPackageInfo (pi.packageName, PackageManager.GET_ACTIVITIES) ;
            pi.activities = tmp.activities ;
            }
        catch (NameNotFoundException e) {
            Log.e (TAG, e.getMessage ()) ;
            }
Run Code Online (Sandbox Code Playgroud)

但这似乎是一个真正的kludge.

我唯一能提到的getInstalledPackages(PackageManager.GET_ACTIVITIES)返回一个空列表就在这里,但在这种情况下的问题似乎是关于在主应用程序线程外调用getInstalledPackages()的问题,这不是我的情况.

ps这是姜饼的.602 VZW版本,如果重要的话

android installed-applications android-package-managers

5
推荐指数
1
解决办法
2万
查看次数

由PackageManager.DONT_KILL_APP引起的不可预测的行为

PackageManager.DONT_KILL_APP的API文档说:

设置此项时要小心,因为更改组件状态会使包含应用程序的行为无法预测.

不幸的是,他们没有详细说明不可预测的行为意味着什么.

在我的应用程序中,我正在切换活动的启用状态.首先,服务启用活动并启动它:

getPackageManager().setComponentEnabledSetting(
    new ComponentName(MyService.this.getApplicationContext(),
    MyActivity.class),
    PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
    PackageManager.DONT_KILL_APP);

final Intent launchIntent = new Intent(context, MyActivity.class);
    launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
        | Intent.FLAG_ACTIVITY_CLEAR_TOP
        | Intent.FLAG_ACTIVITY_SINGLE_TOP);

context.startActivity(launchIntent);
Run Code Online (Sandbox Code Playgroud)

如果(单顶)活动再次开始或被破坏,它会将自己设置为再次禁用:

@Override
protected void onDestroy() {
    log.d("ON DESTROY");
    super.onDestroy();
    getPackageManager().setComponentEnabledSetting(getComponentName(),
        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
        PackageManager.DONT_KILL_APP);
}

@Override
protected void onNewIntent(Intent intent) {
    if (someCondition) {
        getPackageManager().setComponentEnabledSetting(getComponentName(),
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);

        Intent i = new Intent();
        i.setAction(Intent.ACTION_MAIN);
        i.addCategory(Intent.CATEGORY_HOME);
        startActivity(i);

        finish();
        return;
    }

    super.onNewIntent(intent);
}
Run Code Online (Sandbox Code Playgroud)

通常情况下一切正常,但有时对象是空的,在onResume()其中创建onCreate()并且不触及任何其他地方.我无法在调试器中重建这个问题,但我得到了许多带有NullPointerExceptions的错误报告,onResume()如果onCreate()之前真的被调用过,那是不可能的.

一个简单的例子是:

private String s;

@Override
public void onCreate(Bundle savedInstanceState) …
Run Code Online (Sandbox Code Playgroud)

android nullpointerexception onresume android-package-managers

5
推荐指数
1
解决办法
1297
查看次数

为什么Activity.getPackageManager()返回null

我有一个方法将Intent解析为ComponentName:

private static ComponentName resolveViewExternalIntent(Context context)
{
    Intent intent = createIntent();
    return intent.resolveActivity(context.getPackageManager());
}
Run Code Online (Sandbox Code Playgroud)

我很少得到以下ACRA崩溃报告:

java.lang.NullPointerException
    at android.content.Intent.resolveActivity(Intent.java:4518)
    at com.mypackage.myclass.resolveViewExternalIntent(SourceFile:271)
    at om.mypackage.myActivity.onResume(SourceFile:517)
Run Code Online (Sandbox Code Playgroud)

Intent类中的那一行获取NPE,因为PackageManager是null.

我很少看到这一点,但经常这足以让我写下这个问题.

有没有人知道,在什么情况下Context/Activity.getPackageManager()会返回null?就我而言,context是Activity对象本身,而不是ApplicationContext.当发生这种情况时,应用程序正在执行Activity.onResume()生命周期方法.

android android-context android-package-managers android-activity

5
推荐指数
1
解决办法
3487
查看次数

如何检查安装是否来自三星应用商店

我知道怎么检查:

 packageManager.getInstallerPackageName(pContext.getPackageName())
Run Code Online (Sandbox Code Playgroud)

我从其他StackOverflow答案和我在野外的应用程序中了解到:

Google Play返回: com.android.vending

亚马逊回归: com.amazon.venezia

如果我用adb安装,我会从中返回null值getInstallerPackageName().任何人都知道如何测试安装是否来自三星App Store?

android android-package-managers

5
推荐指数
1
解决办法
569
查看次数

PackageManager.getComponentEnabledSettings()在冷启动之间是否持久?

如果我使用下面的代码禁用AndroidManifest.xml中定义的静态BroadcastReceiver,重启后会重新启用它吗?它似乎不是,但文档没有说它是否应该.

final ComponentName compName =
        new ComponentName(context,
        MyBroadcastReceiver.class);

context.getPackageManager().setComponentEnabledSetting(
        compName,
        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
        PackageManager.DONT_KILL_APP);
Run Code Online (Sandbox Code Playgroud)

提前致谢...

android android-manifest android-package-managers

5
推荐指数
1
解决办法
1559
查看次数

在android studio中重命名包名称后发生错误,运行时错误

我在android studio中有一个项目,

我首先将项目从eclipse导出到android studio.之后我改变了它的包名AndroidMenifest.xml,

从Android Studio重命名目录,

更改包名称my class files,

也改变了R.java文件的位置

gen像旧的文件夹是com.oldpath.path1com.newpath.path2.

在R.java文件和BuildConfig.java文件中也反映相同.

现在得到错误如下..

    Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.oldpath.path1/com.newpath.path2.main.SplashScreen }
Error type 3
Error: Activity class {com.oldpath.path1/com.newpath.path2.main.SplashScreen} does not exist.
Run Code Online (Sandbox Code Playgroud)

请帮帮我,我被困在我的项目中..

java android android-package-managers r.java-file android-studio

5
推荐指数
2
解决办法
5208
查看次数

如何直接加载应用程序而不启动主屏幕

当android设备开机时,是否可以在不启动主屏幕的情况下加载一个特定的应用程序?

如何进行此更改?

在哪里更改代码

将权限设置为boot_completed可以正常工作,但在加载应用程序之前,主屏幕会显示5秒钟.如何禁用Android在我的应用程序之前显示任何主屏幕启动器

android android-package-managers android-framework android-launcher

5
推荐指数
1
解决办法
910
查看次数

如何以编程方式禁用没有root的应用程序?

我刚刚发现一个应用程序,允许禁用没有root的三星应用程序,并在后台:

https://play.google.com/store/apps/details?id=com.hecorat.packagedisabler

还有这个免费的:

https://play.google.com/store/apps/details?id=com.ospolice.packagedisabler

  1. 怎么会这样?它甚至没有显示系统类型的alertDialog来询问用户是否可以禁用该应用程序.他们找到了允许这样做的缺陷吗?

  2. 它仅适用于某些三星应用程序吗?其他应用程序和其他公司怎么样?那也有可能吗?

  3. 是否可以将相同的机制用于其他操作?像启用应用程序?

我目前没有三星设备,所以我甚至无法检查这个应用程序.

android android-package-managers samsung-mobile

5
推荐指数
1
解决办法
6074
查看次数

查询不同配置文件的意图活动:Android for Work

由于某些技术原因,我无法使用Android File Picker将文件及其内容存入我的应用程序.这就是为什么我想出了一个查询意图并在我自己的UI上处理结果的解决方案.

以下是我获取应用程序列表的方法 Intent.ACTION_GET_CONTENT

/* Create a new Intent to Read a File */
Intent documentIntent = new Intent(Intent.ACTION_GET_CONTENT);
documentIntent.setType((action == ACTION_SELECT_FILE) ? "*/*" : "image/*");

/* Query for Applications to see which are available */
List<ResolveInfo> appList = getActivity().getPackageManager().queryIntentActivities(documentIntent, PackageManager.MATCH_DEFAULT_ONLY);
Run Code Online (Sandbox Code Playgroud)

这很好,并列出了可以处理我的请求的应用程序.

但我工作的Android for Work,当我执行上面的代码,我只得到可用的应用程序列表中的工作资料,预计.

但是从上面的代码返回的结果之一是"切换到个人",其中列出了安装在Android文件选择器中的个人帐户中的应用程序.

所以问题是,我怎样才能获得相同的行为?如何从个人资料中查询意图活动?

android android-intent android-package-managers android-for-work

5
推荐指数
1
解决办法
847
查看次数