【问题标题】:Custom Settings to Fire off Shell Script自定义设置以触发 Shell 脚本
【发布时间】:2015-07-27 17:55:55
【问题描述】:

所以,我正在为我的 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" />

.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

【问题讨论】:

    标签: android xml shell smali


    【解决方案1】:

    您的类需要实现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
    

    【讨论】:

    • 我如何根据点击的内容找到mListPreference = (ListPreference) findPreference("dp_cleaner");
    • 我不明白您的问题。您引用的行只是保存 ListPreference 以便您可以确保您的 onPreferenceChanged 回调告诉您有关正确首选项的更新。新值在onPreferenceChanged 调用中作为第二个参数传递给您。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-13
    • 1970-01-01
    • 2020-02-25
    相关资源
    最近更新 更多