如何以编程方式访问 Android 操作系统的私有字符串?

Posted

技术标签:

【中文标题】如何以编程方式访问 Android 操作系统的私有字符串?【英文标题】:How to access private strings of the Android OS programmatically? 【发布时间】:2013-03-16 03:36:03 【问题描述】:

背景

我想以编程方式获取 android 操作系统的所有字符串(包括所有字符串),包括那些被视为私有的字符串。

例如,我想获取 packageManager 应用程序的那些,如找到 here 。

问题

使用 android.R.string 只返回一小部分字符串。

我尝试过的

我找到了this link,它显示了下一个代码,但我不确定要在参数中输入什么:

private String GetAttributeStringValue(Context context, AttributeSet attrs, String namespace, String name, String defaultValue) 
    
        //Get a reference to the Resources
        Resources res = context.getResources();
        //Obtain a  String from the attribute
        String stringValue = attrs.getAttributeValue(namespace, name);
        //If the String is null 
        if(stringValue == null)
        
            //set the return String to the default value, passed as a parameter
            stringValue = defaultValue;
        
        //The String isn't null, so check if it starts with '@' and contains '@string/'
        else if( stringValue.length() > 1 && 
                 stringValue.charAt(0) == '@' && 
                 stringValue.contains("@string/") ) 
        
            //Get the integer identifier to the String resource
            final int id = res.getIdentifier(context.getPackageName() + ":" + stringValue.substring(1), null, null);
            //Decode the string from the obtained resource ID
            stringValue = res.getString(id);
         
        //Return the string value
        return stringValue;
    

过去我见过一些应用可以列出其他应用的各种资源,包括系统本身的资源(例如here)。

后来我发现了如何从你想要的任何应用程序中获取字符串,但它假设你知道标识符的名称,并且不让你列出它们:

fun getStringFromApp(context: Context, packageName: String, resourceIdStr: String, vararg formatArgs: Any): String? 
    try 
        val resources = context.packageManager.getResourcesForApplication(packageName)
        val stringResId = resources.getIdentifier(resourceIdStr, "string", packageName)
        if (stringResId == 0)
            return null
        return resources.getString(stringResId, *formatArgs)
     catch (e: Exception) 
        return null
    

例如,如果要获取“more”的字符串(key为“more_item_label”),可以使用:

val moreString = getStringFromApp(this,"android", "more_item_label")

问题

这样的事情可能吗?如果没有,是否可以用root来做?

【问题讨论】:

我认为你做不到。私有资源是这样设计的,因为它们不能保证在后一个版本的 android 中存在。 @Quanturium 我知道它们受到保护,你不能假设它们都存在。我只想查询他们。如果我假设存在一个字符串,我会回退到我自己的字符串。 那个***.com/questions/8077795/… 怎么样? @Quanturium 我需要查询当前资源,而不是下载所有特定版本的资源。这个链接所说的方式,每次有新的android版本时,我都需要添加越来越多的资源。更不用说有些 rom 可能会改变资源本身。 “Android 资源”的链接失效。另请查看Resource Viewer。我相当肯定 Android 系统本身就是一个 APK,因此获取任何字符串值似乎都是可行的。您可以使用 APKTool 对 Android APK 进行解码,看看是否可行。我认为 APKTool 的文档描述了在哪里可以找到系统 APK。 (不,实际上是把系统APK拖到Android Studio中查看资源。) 【参考方案1】:

您的链接显示如何从首选项屏幕获取资源并说:

 The goal of this example was to show how to obtain the correct String resource outside the Android XML namespace

链接描述了您可以通过其他方式获取资源,而不仅仅是通过 R.string。

我使用另一个自定义命名空间和自定义按钮标签创建了一个演示项目,但不幸的是我无法将字符串资源从一个项目显示到另一个项目。

【讨论】:

不,您可以从应用的自定义名称空间属性中获取字符串资源 如果您知道如何按照我的要求做,请写下来。

以上是关于如何以编程方式访问 Android 操作系统的私有字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中以编程方式启用位置访问?

如何以编程方式访问 iOS 中其他已安装应用程序的 info.plist?

在android中以编程方式拍摄设备快照

Android:如何以编程方式启用/禁用 Wifi 或 Internet 连接

Android:如何以编程方式启用/禁用 Wifi 或 Internet 连接

如何以编程方式访问 iphone 内存卡 (SDcard)