自定义设置以触发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 xmlSo, 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 tofindPreference
somehow via thekey
, 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
最满意答案
您的类需要实现
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 yourListPreference
's change listener. Your listener method will be passed the new value as a parameter, at which point you can pass that in to yourexecRootCmdSilent
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 theonPreferenceChange
method (newValue
). We move that into a local register, and theninvoke-virtual
thetoString
method on it. Move the result of that call into thev3
register, and then you caninvoke-static
yourexecRootCmdSilent
method using thatv3
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 bot(Using script to fire Xcode bot)[2021-10-09]
是。 你需要做几件事情:首先,如果你在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 ...
-
在Makefile中自定义SHELL(设置SHELL = my_shell.sh)(Customize SHELL in Makefile (set SHELL=my_shell.sh))[2021-03-11]
首先,如果要将make变量设置为空使用 .SHELLFLAGS = 通过添加引号,您实际上已将变量设置为文字字符串'' (make不是shell,也不执行shell引用剥离)。 其次, .SHELLFLAGS变量是在GNU make 3.82中添加的,所以如果你的版本比那个旧,那么它将无法工作。 如果你有3.82或更新,那么它确实有效(我刚刚尝试过)。 最后,正如Jean-François所指出的,如果你的命令逃脱了空间,你将会遇到问题。 但是,他使用"$@"解决方案不能按原样工作,因为这样整个命令就被视 ...