2

I am creating a module for Xposed, it does what I want but I would like to provide users with a simple preferences screen to input two integer values.

I mainly used the tutorial that can be found here on XDA.

The tutorial explains that one has to create an Activity to show and manage the preferences screen, ok. But after that, there's no explanation at all on how to link that to Xposed so that the user can click the module's name in the module's list and access the preferences screen, instead I just get a message "the module does not provide a user interface".

I did not find any documentation on how to do this. Can someone enlighten me about this please?

gaborous
  • 15,832
  • 10
  • 83
  • 102

1 Answers1

4

I think I have found the culprit (at least this fixed the issue for me). It seems Xposed automatically detects if the app has launchable activity, and just starts it. There's no API. Source: Xposed sourcecode:

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    String packageName = (String) v.getTag();
    if (packageName == null)
        return;

    if (packageName.equals(NOT_ACTIVE_NOTE_TAG)) {
        Intent intent = new Intent(getActivity(), XposedInstallerActivity.class);
        intent.putExtra(XposedInstallerActivity.EXTRA_SECTION, XposedDropdownNavActivity.TAB_INSTALL);
        startActivity(intent);
        return;
    }

    Intent launchIntent = getSettingsIntent(packageName);
    if (launchIntent != null)
        startActivity(launchIntent);
    else
        Toast.makeText(getActivity(), getActivity().getString(R.string.module_no_ui), Toast.LENGTH_LONG).show();
}

Thus, you just need to create an activity, but I think that's not enough: you also have to make it a "Launcher Activity" in Eclipse, or you can do that manually by adding the CATEGORY_LAUNCHER intent filter.

If it works, when you push the app from eclipse to your testing phone, the app will open automatically (just like any other app). If this happens, normally the app should also open inside Xposed.

Here's for example what I have put inside my class:

package xxx.xxx.xxx;

import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;

public class MainSettingsActivity extends PreferenceActivity {

    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       // Setup a non-default and world readable shared preferences, so that 1- we know the name (necessary for XSharedPreferences()), 2- the preferences are accessible from inside the hook.
       PreferenceManager prefMgr = getPreferenceManager();
       prefMgr.setSharedPreferencesName("pref_mine");
       prefMgr.setSharedPreferencesMode(MODE_WORLD_READABLE);
       addPreferencesFromResource(R.xml.pref_settings);
    }

}

Then to use the prefs inside your hook in your main class:

public class Main implements IXposedHookLoadPackage {
    public XSharedPreferences pref;

    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        XSharedPreferences pref = new XSharedPreferences(Main.class.getPackage().getName(), "pref_mine"); // load the preferences using Xposed (necessary to be accessible from inside the hook, SharedPreferences() won't work)
        pref.makeWorldReadable();
        pref.reload();
        pref.getString("some_var", "default_value");
        ...
gaborous
  • 15,832
  • 10
  • 83
  • 102