首页 \ 问答 \ 自定义设置以触发Shell脚本(Custom Settings to Fire off Shell Script)

自定义设置以触发Shell脚本(Custom Settings to Fire off Shell Script)

所以,我正在为我的Android手机开发一个“自定义设置”应用程序,我需要一点帮助....

这就是我想要做的...我希望能够在/res/xml/file.xml中设置一个Preference ,根据xml中的某个值触发shell脚本

所以,说我的Preference是:

<ListPreference android:key="dp_cleaner" android:title="My Cleaner" android:entries="@array/dp_cleaner_entries" android:entryValues="@array/dp_cleaner_entries_values" />

用于触发shell脚本的.smali方法是

.method public static execRootCmdSilent(Ljava/lang/String;)I
# Contains all my code to fire it off...
.end method

用法

:try_start_0
const-string v2, "THE_COMMAND"
invoke-static {v2}, Lcom/android/settings/ExecSH;->execRootCmdSilent(Ljava/lang/String;)I
:try_end_0
.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0

我怎么能从列表中的tapped值填充我的const-string ? 我假设我需要通过key以某种方式找到参考,但我不知道如何将tapped值传递给方法....

可能是一件简单的事情:

.class public Lcom/android/settings/ExecSH;
.super Lcom/android/settings/SettingsPreferenceFragment;
.source "ExecSH.java"

.implements Landroid/preference/Preference$OnPreferenceChangeListener;
.implements Landroid/preference/Preference$OnPreferenceClickListener;


# direct methods
.method public onPreferenceTreeClick(Landroid/preference/PreferenceScreen;Landroid/preference/Preference;)Z

    :try_start_0
    const-string v2, Landroid/preference/Preference;->findPreference(Ljava/lang/CharSequence;)Landroid/preference/Preference;

    invoke-static {v2}, Lcom/android/settings/ExecSH;->execRootCmdSilent(Ljava/lang/String;)I
    :try_end_0
    .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0

.end method

.method public static execRootCmdSilent(Ljava/lang/String;)I
#MY CODE
.end method

So, I am working on a "custom settings" app for my android phone, and I am in need of a little help here....

Here's what I'd like to do... I'd like to be able to set a Preference in the /res/xml/file.xml that on tap fires off a shell script based on some value in the xml

So, say my Preference is:

<ListPreference android:key="dp_cleaner" android:title="My Cleaner" android:entries="@array/dp_cleaner_entries" android:entryValues="@array/dp_cleaner_entries_values" />

And the .smali method to fire off the shell scripts is

.method public static execRootCmdSilent(Ljava/lang/String;)I
# Contains all my code to fire it off...
.end method

Usage

:try_start_0
const-string v2, "THE_COMMAND"
invoke-static {v2}, Lcom/android/settings/ExecSH;->execRootCmdSilent(Ljava/lang/String;)I
:try_end_0
.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0

How could I populate my const-string from the tapped value in the list? I'm assuming that I would need to findPreference somehow via the key, but I don't know how I can pass the tapped value to the method....

Could it be something as simple as:

.class public Lcom/android/settings/ExecSH;
.super Lcom/android/settings/SettingsPreferenceFragment;
.source "ExecSH.java"

.implements Landroid/preference/Preference$OnPreferenceChangeListener;
.implements Landroid/preference/Preference$OnPreferenceClickListener;


# direct methods
.method public onPreferenceTreeClick(Landroid/preference/PreferenceScreen;Landroid/preference/Preference;)Z

    :try_start_0
    const-string v2, Landroid/preference/Preference;->findPreference(Ljava/lang/CharSequence;)Landroid/preference/Preference;

    invoke-static {v2}, Lcom/android/settings/ExecSH;->execRootCmdSilent(Ljava/lang/String;)I
    :try_end_0
    .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0

.end method

.method public static execRootCmdSilent(Ljava/lang/String;)I
#MY CODE
.end method

原文:https://stackoverflow.com/questions/31659997
更新时间:2022-05-11 21:05

最满意答案

您的类需要实现Preference.OnPreferenceChangedListener接口并设置为ListPreference的更改侦听器。 您的侦听器方法将作为参数传递新值,此时您可以将其传递给execRootCmdSilent方法。

关键的smali部分位于以下文件的底部:

.method public onPreferenceChange(Landroid/preference/Preference;Ljava/lang/Object;)Z

    move-object v2, p2

    // there are some more moves here and a test, which is why we're shuffling registers

    move-object v3, v2

    invoke-virtual {v3}, Ljava/lang/Object;->toString()Ljava/lang/String;

    move-result-object v3

    invoke-static {v3}, Lsarbs/com/tinker/SettingsActivity;->execRootCmdSilent(Ljava/lang/String;)I

基本上, p2值是传递给onPreferenceChange方法( newValue )的第二个参数。 我们将其移动到本地寄存器中,然后在其上invoke-virtual toString方法。 将该调用的结果移动到v3寄存器中,然后可以使用该v3寄存器作为参数invoke-static execRootCmdSilent方法。

我用来实现这个的Java代码:

package sarbs.com.tinker;

import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;

public class SettingsActivity extends PreferenceActivity implements Preference.OnPreferenceChangeListener {
    ListPreference mListPreference;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.pref_general);

        mListPreference = (ListPreference) findPreference("dp_cleaner");
        mListPreference.setOnPreferenceChangeListener(this);
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        if (preference == mListPreference) {
            execRootCmdSilent(newValue.toString());
        }
        return true;
    }

    public static int execRootCmdSilent(String str) {
        return 0;
    }
}

它产生的smali代码:

.class public Lsarbs/com/tinker/SettingsActivity;
.super Landroid/preference/PreferenceActivity;
.source "SettingsActivity.java"

# interfaces
.implements Landroid/preference/Preference$OnPreferenceChangeListener;


# instance fields
.field mListPreference:Landroid/preference/ListPreference;


# direct methods
.method public constructor <init>()V
    .registers 3

    .prologue
    .line 8
    move-object v0, p0

    .local v0, "this":Lsarbs/com/tinker/SettingsActivity;
    move-object v1, v0

    invoke-direct {v1}, Landroid/preference/PreferenceActivity;-><init>()V

    return-void
.end method

.method public static execRootCmdSilent(Ljava/lang/String;)I
    .registers 3

    .prologue
    .line 30
    move-object v0, p0

    .local v0, "str":Ljava/lang/String;
    const/4 v1, 0x0

    move v0, v1

    .end local v0    # "str":Ljava/lang/String;
    return v0
.end method


# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
    .registers 7

    .prologue
    .line 13
    move-object v0, p0

    .local v0, "this":Lsarbs/com/tinker/SettingsActivity;
    move-object v1, p1

    .local v1, "savedInstanceState":Landroid/os/Bundle;
    move-object v2, v0

    move-object v3, v1

    invoke-super {v2, v3}, Landroid/preference/PreferenceActivity;->onCreate(Landroid/os/Bundle;)V

    .line 15
    move-object v2, v0

    const v3, 0x7f030001

    invoke-virtual {v2, v3}, Lsarbs/com/tinker/SettingsActivity;->addPreferencesFromResource(I)V

    .line 17
    move-object v2, v0

    move-object v3, v0

    const-string v4, "dp_cleaner"

    invoke-virtual {v3, v4}, Lsarbs/com/tinker/SettingsActivity;->findPreference(Ljava/lang/CharSequence;)Landroid/preference/Preference;

    move-result-object v3

    check-cast v3, Landroid/preference/ListPreference;

    iput-object v3, v2, Lsarbs/com/tinker/SettingsActivity;->mListPreference:Landroid/preference/ListPreference;

    .line 18
    move-object v2, v0

    iget-object v2, v2, Lsarbs/com/tinker/SettingsActivity;->mListPreference:Landroid/preference/ListPreference;

    move-object v3, v0

    invoke-virtual {v2, v3}, Landroid/preference/ListPreference;->setOnPreferenceChangeListener(Landroid/preference/Preference$OnPreferenceChangeListener;)V

    .line 19
    return-void
.end method

.method public onPreferenceChange(Landroid/preference/Preference;Ljava/lang/Object;)Z
    .registers 8

    .prologue
    .line 23
    move-object v0, p0

    .local v0, "this":Lsarbs/com/tinker/SettingsActivity;
    move-object v1, p1

    .local v1, "preference":Landroid/preference/Preference;
    move-object v2, p2

    .local v2, "newValue":Ljava/lang/Object;
    move-object v3, v1

    move-object v4, v0

    iget-object v4, v4, Lsarbs/com/tinker/SettingsActivity;->mListPreference:Landroid/preference/ListPreference;

    if-ne v3, v4, :cond_12

    .line 24
    move-object v3, v2

    invoke-virtual {v3}, Ljava/lang/Object;->toString()Ljava/lang/String;

    move-result-object v3

    invoke-static {v3}, Lsarbs/com/tinker/SettingsActivity;->execRootCmdSilent(Ljava/lang/String;)I

    move-result v3

    .line 26
    :cond_12
    const/4 v3, 0x1

    move v0, v3

    .end local v0    # "this":Lsarbs/com/tinker/SettingsActivity;
    return v0
.end method

Your class needs to implement the Preference.OnPreferenceChangedListener interface and be set as your ListPreference's change listener. Your listener method will be passed the new value as a parameter, at which point you can pass that in to your execRootCmdSilent method.

The critical smali section is toward the bottom of the below files:

.method public onPreferenceChange(Landroid/preference/Preference;Ljava/lang/Object;)Z

    move-object v2, p2

    // there are some more moves here and a test, which is why we're shuffling registers

    move-object v3, v2

    invoke-virtual {v3}, Ljava/lang/Object;->toString()Ljava/lang/String;

    move-result-object v3

    invoke-static {v3}, Lsarbs/com/tinker/SettingsActivity;->execRootCmdSilent(Ljava/lang/String;)I

Basically, the p2 value is the second parameter being passed to the onPreferenceChange method (newValue). We move that into a local register, and then invoke-virtual the toString method on it. Move the result of that call into the v3 register, and then you can invoke-static your execRootCmdSilent method using that v3 register as the parameter.

The Java code I used to implement this:

package sarbs.com.tinker;

import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;

public class SettingsActivity extends PreferenceActivity implements Preference.OnPreferenceChangeListener {
    ListPreference mListPreference;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.pref_general);

        mListPreference = (ListPreference) findPreference("dp_cleaner");
        mListPreference.setOnPreferenceChangeListener(this);
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        if (preference == mListPreference) {
            execRootCmdSilent(newValue.toString());
        }
        return true;
    }

    public static int execRootCmdSilent(String str) {
        return 0;
    }
}

And the smali code it produced:

.class public Lsarbs/com/tinker/SettingsActivity;
.super Landroid/preference/PreferenceActivity;
.source "SettingsActivity.java"

# interfaces
.implements Landroid/preference/Preference$OnPreferenceChangeListener;


# instance fields
.field mListPreference:Landroid/preference/ListPreference;


# direct methods
.method public constructor <init>()V
    .registers 3

    .prologue
    .line 8
    move-object v0, p0

    .local v0, "this":Lsarbs/com/tinker/SettingsActivity;
    move-object v1, v0

    invoke-direct {v1}, Landroid/preference/PreferenceActivity;-><init>()V

    return-void
.end method

.method public static execRootCmdSilent(Ljava/lang/String;)I
    .registers 3

    .prologue
    .line 30
    move-object v0, p0

    .local v0, "str":Ljava/lang/String;
    const/4 v1, 0x0

    move v0, v1

    .end local v0    # "str":Ljava/lang/String;
    return v0
.end method


# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
    .registers 7

    .prologue
    .line 13
    move-object v0, p0

    .local v0, "this":Lsarbs/com/tinker/SettingsActivity;
    move-object v1, p1

    .local v1, "savedInstanceState":Landroid/os/Bundle;
    move-object v2, v0

    move-object v3, v1

    invoke-super {v2, v3}, Landroid/preference/PreferenceActivity;->onCreate(Landroid/os/Bundle;)V

    .line 15
    move-object v2, v0

    const v3, 0x7f030001

    invoke-virtual {v2, v3}, Lsarbs/com/tinker/SettingsActivity;->addPreferencesFromResource(I)V

    .line 17
    move-object v2, v0

    move-object v3, v0

    const-string v4, "dp_cleaner"

    invoke-virtual {v3, v4}, Lsarbs/com/tinker/SettingsActivity;->findPreference(Ljava/lang/CharSequence;)Landroid/preference/Preference;

    move-result-object v3

    check-cast v3, Landroid/preference/ListPreference;

    iput-object v3, v2, Lsarbs/com/tinker/SettingsActivity;->mListPreference:Landroid/preference/ListPreference;

    .line 18
    move-object v2, v0

    iget-object v2, v2, Lsarbs/com/tinker/SettingsActivity;->mListPreference:Landroid/preference/ListPreference;

    move-object v3, v0

    invoke-virtual {v2, v3}, Landroid/preference/ListPreference;->setOnPreferenceChangeListener(Landroid/preference/Preference$OnPreferenceChangeListener;)V

    .line 19
    return-void
.end method

.method public onPreferenceChange(Landroid/preference/Preference;Ljava/lang/Object;)Z
    .registers 8

    .prologue
    .line 23
    move-object v0, p0

    .local v0, "this":Lsarbs/com/tinker/SettingsActivity;
    move-object v1, p1

    .local v1, "preference":Landroid/preference/Preference;
    move-object v2, p2

    .local v2, "newValue":Ljava/lang/Object;
    move-object v3, v1

    move-object v4, v0

    iget-object v4, v4, Lsarbs/com/tinker/SettingsActivity;->mListPreference:Landroid/preference/ListPreference;

    if-ne v3, v4, :cond_12

    .line 24
    move-object v3, v2

    invoke-virtual {v3}, Ljava/lang/Object;->toString()Ljava/lang/String;

    move-result-object v3

    invoke-static {v3}, Lsarbs/com/tinker/SettingsActivity;->execRootCmdSilent(Ljava/lang/String;)I

    move-result v3

    .line 26
    :cond_12
    const/4 v3, 0x1

    move v0, v3

    .end local v0    # "this":Lsarbs/com/tinker/SettingsActivity;
    return v0
.end method

相关问答

更多
  • 我找到了我要求的答案,我做错了。 首先让我说网络上显示如何创建iOS Static Library所有教程都缺少了一些东西而且至少在我看到的东西上并不完美,这就是我首先遇到这个问题的原因。 这些是我曾经做过的那些: Xcode 6 iOS创建Cocoa Touch框架 - 架构问题 在iOS教程中创建静态库Ray Wenderlich 这就是我的问题的答案: 我没有创建新的Aggregate Target并在那里插入Custom Shell Script代码,而是将Custom Shell Script代码 ...
  • 按照下面的步骤,我可以完成它,一切工作正常: 1 - 我从Homebrew brew install curl --with-openssl : brew install curl --with-openssl 2 - 将curl PATH指向新安装的: brew link --force curl 3 - 运行这个: curl --remote-name --time-cond cacert.pem https://curl.haxx.se/ca/cacert.pem By following the b ...
  • 您的类需要实现Preference.OnPreferenceChangedListener接口并设置为ListPreference的更改侦听器。 您的侦听器方法将作为参数传递新值,此时您可以将其传递给execRootCmdSilent方法。 关键的smali部分位于以下文件的底部: .method public onPreferenceChange(Landroid/preference/Preference;Ljava/lang/Object;)Z move-object v2, p2 ...
  • 命令'file'可以帮助您识别要检查的'文件'的类型 一些例子: $file lavtc.sh lavtc.sh: POSIX shell script, ASCII text executable, with very long lines 和: $file java /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked ...
  • 你可以传递$ file作为参数 $file="my_wa/fin" if [[ "$file" == *"fin" ]]; then script.pl \"$file\" fi 然后访问数据 my $input_filename = $ARGV[0]; you can pass $file as an argument $file="my_wa/fin" if [[ "$file" == *"fin" ]]; then script.pl \"$ ...
  • 是。 你需要做几件事情:首先,如果你在Xcode服务器运行的机器上,我会打电话给你的Xcode服务器的IP地址XCS_IP,通常是本地主机。 在终端中找到bot的ID:运行curl -k "https://XCS_IP:20343/api/bots" 。 将输出复制到某个编辑器,并为您的机器人找到键_id的值,将类似于6b3de48352a8126ce7e08ecf85093613 。 我们称之为BOT_ID 。 通过运行curl -k -X POST -u "username:password" "htt ...
  • 根据你的说法,我认为问题可能是 该脚本未标记为可执行文件。 在这种情况下,添加Build - > Execute Shell (如果你有linux) sudo chmod 777 path_to_script/jake.sh 该脚本不在基目录中。 请记住,当您执行bash脚本时,当前目录是/path_to_job/workspace 。 因此,您首先要移动到脚本文件夹( cd path_to_script )或在运行它时指定路径: ./path_to_script/jake.sh cd path_to_sc ...
  • 它有超过1200个appleid证书,所以它需要一段时间来签署cocopods。 修理: 打开钥匙串 单击“ Certificates 搜索appleid 选择所有CMD-A 按delete 参考: XCode 7.3.1挂起“复制swift标准库” It had over 1200 appleid certificates, so it was taking a while to sign the cocopods. To fix: Open keychain Click Certificates Sea ...
  • 首先,你需要放置一些无限的东西来继续在后台运行你的容器,就像你可以tail -f application.log或类似的东西,这样即使你从容器bash退出它仍然在后台运行 你不需要做cmd1 & cmd2 &&...cmdn &只需要输入一个命令,如touch 1.txt && tail -f 1.txt作为my-script.sh的最后一步。 它将继续运行您的容器。 你需要更改的一件事是docker run -it docker run -it -d -d将以后台模式启动容器。如果你想进入容器内而不是do ...
  • 首先,如果要将make变量设置为空使用 .SHELLFLAGS = 通过添加引号,您实际上已将变量设置为文字字符串'' (make不是shell,也不执行shell引用剥离)。 其次, .SHELLFLAGS变量是在GNU make 3.82中添加的,所以如果你的版本比那个旧,那么它将无法工作。 如果你有3.82或更新,那么它确实有效(我刚刚尝试过)。 最后,正如Jean-François所指出的,如果你的命令逃脱了空间,你将会遇到问题。 但是,他使用"$@"解决方案不能按原样工作,因为这样整个命令就被视 ...

相关文章

更多

最新问答

更多
  • 如何重新加载下拉列表(How to reload dropdownlist)
  • RStudio:在脚本中保留特殊字符(RStudio: keeping special characters in a script)
  • Powershell的“GetLatest”不会在新的TFS工作区上下载文件(“GetLatest” with Powershell doesn't download files on new TFS workspace)
  • 我如何让JS识别一个由字符组成的数组?(How do I get JS to recognise an array insted of characters?)
  • EF从存储过程中急切加载(EF eager loading from stored procedure)
  • 将输出文件添加到Python扩展(Adding output file to Python extension)
  • 淮北职业技术学院电脑应用专业咋样?
  • 更改默认扩展面板箭头的箭头样式(Change arrow style for default expansion panel arrow)
  • 芜湖计算机(计算机)培训机构(培训班,学校)哪家好
  • 致命错误:使用clang-llvm ASTMatcher时未找到'stddef.h'文件(fatal error: 'stddef.h' file not found when using clang-llvm ASTMatcher)
  • 内容的.NET缓存(Contentful .NET caching)
  • 客户端没有发生WCF回调(WCF callback is not happening in client)
  • 使用friend在全局范围内调用类成员函数会产生27个错误(Calling a Class member function in Global Scope using friend Gives 27 ERRORS)
  • 如何绑定到WPF中的另一个控件属性(How to Bind to Another Control Property in WPF)
  • 南华大学电脑专业,就业好不好
  • 是否存在泄密文件的官方(或常见)文件扩展名或后缀?(Is there an official (or common) file extention or suffix for deflated files?)
  • 在SVM python中只训练一次(Training only once in SVM python)
  • 淘汰自定义绑定光滑js无法正常工作(knockout custom binding for slick js not working)
  • 似乎无法正确地抓住网站“福布斯”(Can't seem to scrape the website “Forbes” properly)
  • 无法使用boto.rds2从describe_instance方法检索有关db实例的信息(Not able to retrieve information about db instances from the describe_instance method using boto.rds2)
  • 转换为英国日期格式问题(Convert to british date format issue)
  • 在表中列出不同的元组(10种方法)(List distinct tuples in a table(SQL query)(10 ways))
  • OrientDB查询比较(OrientDB query compare)
  • 全局变量有什么不好?(What is so bad about global variables? [duplicate])
  • 为什么JavaMail Transport.send()是一个静态方法?(Why is JavaMail Transport.send() a static method?)
  • 获取最近3个Instagram图像张贴在一个地方(Get last 3 instagram images posted in a place)
  • 使用libnfc格式化/读/写NDEF Mifare 1K卡(Format/Read/Write NDEF Mifare 1K Card using libnfc)
  • 阻止谷歌索引特定图像(Block Google from indexing a particular image)
  • 消息模板接收让Dispatcher没有订阅频道(Message Template receive gives Dispatcher has no subscribers for channel)
  • OpenShift:使用自定义节点版本(OpenShift: Use custom node version)