所以,我正在为我的 Android 手机开发一个“自定义设置”应用程序,在这里我需要一点帮助....
这是我想做的...
我希望能够在/res/xml/file.xml 中设置一个 Preference,它会根据 xml 中的某些值触发 shell 脚本
那么,假设我的偏好是:
<ListPreference android:key="dp_cleaner" android:title="My Cleaner" android:entries="@array/dp_cleaner_entries" android:entryValues="@array/dp_cleaner_entries_values" />
.smali 方法来触发 shell 脚本是
.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
如何从列表中的点击值填充我的const-string?我假设我需要通过 key 以某种方式findPreference,但我不知道如何将点击的值传递给方法....
是否可以像这样简单:
.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
最佳答案
你的类需要实现 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 value 是传递给 onPreferenceChange 的第二个参数方法(newValue)。我们将其移至本地寄存器,然后 invoke-virtual toString方法就可以了。将该调用的结果移至 v3注册,然后就可以invoke-static你的execRootCmdSilent使用该方法 v3注册为参数。
我用来实现这个的 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
关于android - 用于触发 Shell 脚本的自定义设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31659997/
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我有一个在Linux服务器上运行的ruby脚本。它不使用rails或任何东西。它基本上是一个命令行ruby脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg