gpt4 book ai didi

Is it possible to update Android Manifest programmatically at runtime?(是否可以在运行时以编程方式更新Android Manifest?)

转载 作者:bug小助手 更新时间:2023-10-25 19:21:08 30 4
gpt4 key购买 nike



What I want to achieve:



I am creating an application which changes the app icon and app name programmatically.


What I have achieved:



I've already achieved this because there are only 5 names and icons by declaring activity-alias in android manifest.


Problem I'm facing:



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.


Below is my code:

以下是我的代码:


AndroidManifest.xml

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>

In MainActivity.java

在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);
}

更多回答

Assuming your question is the one in title Is it possible to update Android Manifest programmatically? the answer is no, it is not possible to do that programmatically.

假设您的问题是标题中的问题,是否有可能以编程方式更新Android Manifest?答案是否定的,不可能通过编程实现这一点。

@azizbekian Not even a single way to achieve that??

@azizbekian甚至没有一种方法可以做到这一点??

You can enable/disable components that are declared in your manifest, but you cannot add or remove something from there, because, as the name says, it's a manifest file, which system "reads" when it installs your app. So you are declaring your app's interface in that manifest, later on you cannot change that (unless you reinstall the app with another manifest).

您可以启用/禁用清单中声明的组件,但不能在其中添加或删除某些内容,因为顾名思义,它是一个清单文件,系统在安装您的应用程序时会“读取”该文件。所以你在清单中声明了你的应用程序的界面,以后你不能改变它(除非你用另一个清单重新安装了应用程序)。

I'll post those comments as an answer.

我会把这些评论贴出来作为回答。

"unless you reinstall the app with another manifest" is it really possible??

“除非你用另一个清单重新安装应用程序”,这真的可能吗?

优秀答案推荐

Assuming your question is the one in title:

假设您的问题是标题中的问题:




Is it possible to update Android Manifest programmatically?




The answer is no, it is not possible to do that programmatically.

答案是否定的,不可能通过编程实现这一点。



You can enable/disable components that are declared in your manifest, but you cannot add or remove something from there, because, as the name says, it's a manifest file, which system "reads" when it installs your app. So you are declaring your app's interface in that manifest, later on you cannot change that, unless you reinstall the app with another manifest.

您可以启用/禁用清单中声明的组件,但不能在其中添加或删除某些内容,因为顾名思义,它是一个清单文件,系统在安装您的应用程序时会“读取”该文件。所以你在清单中声明了你的应用程序的界面,以后你不能改变它,除非你用另一个清单重新安装应用程序。



Assume system provided you ability to do that. Then you'd add some permission to your manifest dynamically, whereas user hasn't approved that while he was downloading your app from Play Store.

假设系统为你提供了这样做的能力。然后你可以动态地向你的清单添加一些权限,而用户在从Play Store下载你的应用程序时并没有批准这一点。



You can change the manifest meta value for Admob or any string by using this code:

您可以使用以下代码更改Admob的manifest Meta值或任何字符串:


package com.asdf.loanapp;

import android.os.Build;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ModifyManifest {

static String readFileString;

public static void main(String[] args) {
// Specify the path to the
AndroidManifest.xml file
String manifestFilePath = "/path/to/AndroidManifest.xml";

// Specify the name of the metadata element you want to modify
String metadataName = "your_metadata_name";

// Specify the new metadata value
String newMetadataValue = "place_your_admob_string_here";

try {
// Read the contents of the AndroidManifest.xml file
String manifestContent = readFile(manifestFilePath);

// Modify the metadata value
manifestContent = modifyMetadata(manifestContent, metadataName, newMetadataValue);

// Save the modified content back to the file
saveFile(manifestContent, manifestFilePath);

System.out.println("Metadata in AndroidManifest.xml modified successfully.");
} catch (IOException e) {
e.printStackTrace();
}
}

// Read the contents of a file

private static String readFile(String filePath) throws IOException {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
readFileString = new String(Files.readAllBytes(Paths.get(filePath)));
}
return readFileString;
}

// Modify the metadata value in the AndroidManifest.xml
private static String modifyMetadata(String manifestContent, String metadataName, String newMetadataValue) {
// Find and replace the metadata value
String oldMetadataTag = "<meta-data android:name=\"" + metadataName + "\"";
int startIndex = manifestContent.indexOf(oldMetadataTag);
if (startIndex != -1) {
int endIndex = manifestContent.indexOf(">", startIndex);
if (endIndex != -1) {
// Extract the existing value
String existingMetadataTag = manifestContent.substring(startIndex, endIndex);
String existingValue = extractMetadataValue(existingMetadataTag);


// Create the new metadata tag with the modified value
String newMetadataTag = "<meta-data android:name=\"" + metadataName + "\" android:value=\"" + newMetadataValue + "\" />";

// Replace the old metadata tag with the new one
manifestContent = manifestContent.replace(existingMetadataTag, newMetadataTag);
}
}
return manifestContent;
}

// Extract the value attribute from a metadata tag
private static String extractMetadataValue(String metadataTag) {
Pattern pattern = Pattern.compile("android:value=\"([^\"]*)\"");
Matcher matcher = pattern.matcher(metadataTag);
if (matcher.find()) {
return matcher.group(1);
}
return null;
}

// Save modified content back to the file
private static void saveFile(String content, String filePath) throws IOException {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Files.write(Paths.get(filePath), content.getBytes());
}
}
}

更多回答

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com