是否可以在运行时以编程方式更新 Android Manifest?
Is it possible to update Android Manifest programmatically at runtime?
我想达到的目标:
I am creating an application which changes the app icon and app name programmatically.
我取得的成绩:
I've already achieved this because there are only 5 names and icons by declaring activity-alias in android manifest.
我面临的问题:
If you have only 5 names then it's easy to declare it in manifest. But what if you don't know the no. of names and you have to update the manifest programmatically.
下面是我的代码:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.drawerstack">
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity-alias android:label="@string/app_name1"
android:icon="@drawable/ic_launcher"
android:name=".MainActivity-Red"
android:enabled="false"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias android:label="@string/app_name2"
android:icon="@drawable/ic_launcher_1"
android:name=".MainActivity-Pink"
android:enabled="false"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias android:label="@string/app_name3"
android:icon="@drawable/ic_launcher_2"
android:name=".MainActivity-Blue"
android:enabled="false"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias android:label="@string/app_name4"
android:icon="@drawable/ic_launcher_3"
android:name=".MainActivity-Grey"
android:enabled="false"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
</application>
</manifest>
在MainActivity.java
img.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (view.getTag().equals(0)) {
changeIcon("com.drawerstack.MainActivity-Red");
removeIcon("com.drawerstack.MainActivity");
removeIcon("com.drawerstack.MainActivity-Pink");
removeIcon("com.drawerstack.MainActivity-Blue");
removeIcon("com.drawerstack.MainActivity-Grey");
} else if (view.getTag().equals(1)) {
changeIcon("com.drawerstack.MainActivity-Pink");
removeIcon("com.drawerstack.MainActivity-Blue");
removeIcon("com.drawerstack.MainActivity-Grey");
removeIcon("com.drawerstack.MainActivity-Red");
removeIcon("com.drawerstack.MainActivity");
} else if (view.getTag().equals(2)) {
changeIcon("com.drawerstack.MainActivity-Blue");
removeIcon("com.drawerstack.MainActivity-Pink");
removeIcon("com.drawerstack.MainActivity-Grey");
removeIcon("com.drawerstack.MainActivity-Red");
removeIcon("com.drawerstack.MainActivity");
} else if (view.getTag().equals(3)) {
changeIcon("com.drawerstack.MainActivity-Grey");
removeIcon("com.drawerstack.MainActivity-Pink");
removeIcon("com.drawerstack.MainActivity-Red");
removeIcon("com.drawerstack.MainActivity-Blue");
removeIcon("com.drawerstack.MainActivity");
}
}
});
private void changeIcon(final String pkgName) {
doAsynchronousTask = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
Date now = new Date();
if(now.after(afterDate)){
timer.cancel();
Common.dismissProgressDialog(MainActivity.this);
finish();
}
}
};
timer.schedule(doAsynchronousTask, 0, 50000);
Common.loadProgressDialog(MainActivity.this,false);
getPackageManager().setComponentEnabledSetting(
new ComponentName("com.drawerstack", pkgName),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}
private void removeIcon(String removePkg) {
getPackageManager().setComponentEnabledSetting(
new ComponentName("com.drawerstack", removePkg),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}
假设您的问题是标题中的问题:
Is it possible to update Android Manifest programmatically?
答案是否,不可能以编程方式做到这一点。
您可以 enable/disable 在您的清单中声明的组件,但您不能从那里添加或删除某些内容,因为正如其名称所示,它是一个清单文件,系统 "reads" 当它会安装您的应用程序。因此,您在该清单中声明了应用程序的界面,以后您无法更改它,除非您使用另一个清单重新安装该应用程序。
假设系统为您提供了这样做的能力。然后你会动态地向你的清单添加一些权限,而用户在从 Play 商店下载你的应用程序时还没有批准。
我想达到的目标:
I am creating an application which changes the app icon and app name programmatically.
我取得的成绩:
I've already achieved this because there are only 5 names and icons by declaring activity-alias in android manifest.
我面临的问题:
If you have only 5 names then it's easy to declare it in manifest. But what if you don't know the no. of names and you have to update the manifest programmatically.
下面是我的代码:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.drawerstack">
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity-alias android:label="@string/app_name1"
android:icon="@drawable/ic_launcher"
android:name=".MainActivity-Red"
android:enabled="false"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias android:label="@string/app_name2"
android:icon="@drawable/ic_launcher_1"
android:name=".MainActivity-Pink"
android:enabled="false"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias android:label="@string/app_name3"
android:icon="@drawable/ic_launcher_2"
android:name=".MainActivity-Blue"
android:enabled="false"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias android:label="@string/app_name4"
android:icon="@drawable/ic_launcher_3"
android:name=".MainActivity-Grey"
android:enabled="false"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
</application>
</manifest>
在MainActivity.java
img.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (view.getTag().equals(0)) {
changeIcon("com.drawerstack.MainActivity-Red");
removeIcon("com.drawerstack.MainActivity");
removeIcon("com.drawerstack.MainActivity-Pink");
removeIcon("com.drawerstack.MainActivity-Blue");
removeIcon("com.drawerstack.MainActivity-Grey");
} else if (view.getTag().equals(1)) {
changeIcon("com.drawerstack.MainActivity-Pink");
removeIcon("com.drawerstack.MainActivity-Blue");
removeIcon("com.drawerstack.MainActivity-Grey");
removeIcon("com.drawerstack.MainActivity-Red");
removeIcon("com.drawerstack.MainActivity");
} else if (view.getTag().equals(2)) {
changeIcon("com.drawerstack.MainActivity-Blue");
removeIcon("com.drawerstack.MainActivity-Pink");
removeIcon("com.drawerstack.MainActivity-Grey");
removeIcon("com.drawerstack.MainActivity-Red");
removeIcon("com.drawerstack.MainActivity");
} else if (view.getTag().equals(3)) {
changeIcon("com.drawerstack.MainActivity-Grey");
removeIcon("com.drawerstack.MainActivity-Pink");
removeIcon("com.drawerstack.MainActivity-Red");
removeIcon("com.drawerstack.MainActivity-Blue");
removeIcon("com.drawerstack.MainActivity");
}
}
});
private void changeIcon(final String pkgName) {
doAsynchronousTask = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
Date now = new Date();
if(now.after(afterDate)){
timer.cancel();
Common.dismissProgressDialog(MainActivity.this);
finish();
}
}
};
timer.schedule(doAsynchronousTask, 0, 50000);
Common.loadProgressDialog(MainActivity.this,false);
getPackageManager().setComponentEnabledSetting(
new ComponentName("com.drawerstack", pkgName),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}
private void removeIcon(String removePkg) {
getPackageManager().setComponentEnabledSetting(
new ComponentName("com.drawerstack", removePkg),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}
假设您的问题是标题中的问题:
Is it possible to update Android Manifest programmatically?
答案是否,不可能以编程方式做到这一点。
您可以 enable/disable 在您的清单中声明的组件,但您不能从那里添加或删除某些内容,因为正如其名称所示,它是一个清单文件,系统 "reads" 当它会安装您的应用程序。因此,您在该清单中声明了应用程序的界面,以后您无法更改它,除非您使用另一个清单重新安装该应用程序。
假设系统为您提供了这样做的能力。然后你会动态地向你的清单添加一些权限,而用户在从 Play 商店下载你的应用程序时还没有批准。