我正在制作一个 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) 如果我打电话
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版本,如果重要的话
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
我有一个方法将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
我知道怎么检查:
packageManager.getInstallerPackageName(pContext.getPackageName())
Run Code Online (Sandbox Code Playgroud)
我从其他StackOverflow答案和我在野外的应用程序中了解到:
Google Play返回: com.android.vending
亚马逊回归: com.amazon.venezia
如果我用adb安装,我会从中返回null值getInstallerPackageName().任何人都知道如何测试安装是否来自三星App Store?
如果我使用下面的代码禁用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 studio中有一个项目,
我首先将项目从eclipse导出到android studio.之后我改变了它的包名AndroidMenifest.xml,
从Android Studio重命名目录,
更改包名称my class files,
也改变了R.java文件的位置
而gen像旧的文件夹是com.oldpath.path1到com.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
当android设备开机时,是否可以在不启动主屏幕的情况下加载一个特定的应用程序?
如何进行此更改?
在哪里更改代码
将权限设置为boot_completed可以正常工作,但在加载应用程序之前,主屏幕会显示5秒钟.如何禁用Android在我的应用程序之前显示任何主屏幕启动器
android android-package-managers android-framework android-launcher
我刚刚发现一个应用程序,允许禁用没有root的三星应用程序,并在后台:
https://play.google.com/store/apps/details?id=com.hecorat.packagedisabler
还有这个免费的:
https://play.google.com/store/apps/details?id=com.ospolice.packagedisabler
怎么会这样?它甚至没有显示系统类型的alertDialog来询问用户是否可以禁用该应用程序.他们找到了允许这样做的缺陷吗?
它仅适用于某些三星应用程序吗?其他应用程序和其他公司怎么样?那也有可能吗?
是否可以将相同的机制用于其他操作?像启用应用程序?
我目前没有三星设备,所以我甚至无法检查这个应用程序.
由于某些技术原因,我无法使用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