It doesn't seem to matter what I id I put in as parameter 2 to this constructor.
I keep getting this compile error: "resource type layout expected"
Code:
m_BTArrayAdapter = new ArrayAdapter<>(this, id.layout_controls);
This web page is no help what so ever: http://developer.android.com/refere...ml#ArrayAdapter(android.content.Context, int)
There are no examples and no proper explanation of the parameters
So what is it exactly that you are supposed to pass into this constructor as the second parameter?
Related
I'm a newbee to xposed module development. I searched sometimes in this forum and viewed some open-source mudules on github, but I still don't know how to reload prefs in my module.
I try to change the setting repeatedly, but logcat always displays that prefs returned a false. My code is here below:
This is the main class loaded by xposed:
Code:
public class Main implements IXposedHookLoadPackage, IXposedHookZygoteInit, IXposedHookInitPackageResources{
private static XSharedPreferences prefs = new XSharedPreferences(Main.class.getPackage().getName());
....
SOME HACKS
....
private BroadcastReceiver xReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
context = mContext;
if (intent.getAction().equals("xxx.xxx.SETTING_CHANGED")){
prefs.makeWorldReadable(); // Wether this line is added or not, the result is same.
prefs.reload();
Log.d(TAG, String.valueOf(prefs.getBoolean("key", false)));
}
}
};
}
This is the setting screen class:
Code:
public class Setting extends PreferenceActivity implements OnSharedPreferenceChangeListener{
ListPreference lp;
ListPreference _lp;
EditTextPreference etp;
CheckBoxPreference cbp;
@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.setting);
getPreferenceManager().setSharedPreferencesMode(MODE_WORLD_READABLE);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(this);
}
@SuppressWarnings("deprecation")
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Intent intent = new Intent();
intent.setAction("xxx.xxx.SETTING_CHANGED");
Setting.this,sendBroadcast(intent);
}
From memory, I believe the XSharedPreferences constructor takes the preferences' file name, which is usually something like "com.mypackage_preferences" and not only "com.mypackage".
Note that you don't need to use makeWorldReadable in your module since you're doing that in your preferences activity.
GermainZ said:
From memory, I believe the XSharedPreferences constructor takes the preferences' file name, which is usually something like "com.mypackage_preferences" and not only "com.mypackage".
Note that you don't need to use makeWorldReadable in your module since you're doing that in your preferences activity.
Click to expand...
Click to collapse
Thanks for your reply. But I can't understand clearly and I'm even more confused.
Code:
XSharedPreferences prefs = new XSharedPreferences(Main.class.getPackage().getName());
This works well. Read preferences correctly.
In the source code of XSharedPreference class. The function "XSharedPreferences(String packageName)" will call "XSharedPreferences(String packageName, String prefFileName)" and complete the default preferences file name. I don't think I need to use full path and file name?
I still don't know how to reload settings correctly. Could you give me a copy of detailed code to work perfectly?
Awating your reply.
neverweep said:
Thanks for your reply. But I can't understand clearly and I'm even more confused.
Code:
XSharedPreferences prefs = new XSharedPreferences(Main.class.getPackage().getName());
This works well. Read preferences correctly.
In the source code of XSharedPreference class. The function "XSharedPreferences(String packageName)" will call "XSharedPreferences(String packageName, String prefFileName)" and complete the default preferences file name. I don't think I need to use full path and file name?
I still don't know how to reload settings correctly. Could you give me a copy of detailed code to work perfectly?
Awating your reply.
Click to expand...
Click to collapse
If I'm not mistaken, this:
Code:
XSharedPreferences prefs = new XSharedPreferences(Main.class.getPackage().getName());
… will load an "empty" preferences file (because it won't exist) so everything will have the default value. Try something like this instead:
Code:
XSharedPreferences prefs = new XSharedPreferences(Main.class.getPackage().getName() + "_preferences");
As for reloading preferences, you seem to be doing it correctly (XSharedPreferences.reload method), it's just that it's not working as intended for the reason explained above.
No, neverweep's code:
Code:
XSharedPreferences prefs = new XSharedPreferences(Main.class.getPackage().getName());
is good. I also use such code in my modules and everything works.
Rovo89 has code to add "_preferences" automatically (link: https://github.com/rovo89/XposedBri...bv/android/xposed/XSharedPreferences.java#L37)
I also had some trouble figuring out how to reload prefs in realtime, but thank's to this thread and to some attempts, I could finally figure it out.
Here's the code if this can help someone (plus the preference management is very simple so it should be a very easy example to follow):
on github (cannot post links yet):
Code:
lrq3000/XposedJitteryGyroFix/blob/14d7e93949bbfd5cfc31ce30482eff9860c35a49/GyroscopeNoiseFilter/src/net/kajos/gyronoisefilter/GyroscopeNoiseFilter.java#L50
hi all.
i created an xposed module but, inside my app, i also have what a standard android app has, like res/strings.xml.
now, even if the entry point is IXposedHookLoadPackage.handleLoadPackage() and then i don't have an android app context, i sometimes need to access my app package name and to my app strings but context.getPackageName() and context.getResources() don't return what i want.
what's the proper way to do it?
thanks a lot.
Do you already have a context? If not, you can use AndroidAppHelper.currentApplication().
To create a context for your application from an existing context, use Context.createPackageContext.
GermainZ said:
Do you already have a context? If not, you can use AndroidAppHelper.currentApplication().
To create a context for your application from an existing context, use Context.createPackageContext.
Click to expand...
Click to collapse
hi and thanks for your reply.
i tried this code but it returns "android" as the package name:
Code:
Context context = AndroidAppHelper.currentApplication();
String packageName = context.getPackageName();
am i missing something?
This is my way of accessing my app context:
Java:
XposedBridge.hookAllConstructors(<the class you want to hook>, new XC_MethodHook() {
[user=439709]@override[/user]
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
log("initializing");
//The context that you mod (usually android)
//It happens that the constructor of the constructor to be hooked has the context as the first argument
//I think AndroidAppHelper.currentApplication() is a more general way to do it
Context modContext = (Context) param.args[0];
//Context of your app
Context appContext = modContext.createPackageContext(
PACKAGE_NAME, Context.CONTEXT_IGNORE_SECURITY);
Resources modRes = modContext.getResources();
Resources appRes = appContext.getResources();
...
}
});
where PACKAGE_NAME is a static field like this
Java:
public static final String PACKAGE_NAME = <Your class>.class.getPackage().getName();
Not sure if there are other alternatives. This is just my way to doing it in my modules
This helped a lot! Thanks!
Hiya,
So I have the hook I need, but I need to get a context. The object I'm in doesn't have a Context member, but it does have an ActivityManager object, and ActivityManager has a context.
The problem is that ActivityManager is an internal class, so I can't do this:
Code:
ActivityManager am = (ActivityManager) XposedHelpers.getObjectField(param.thisObject, "mAm");
Context context = (Context) XposedHelpers.getObjectField(am, "mContext");
I tried this, on a hunch:
Code:
Context context = (Context) XposedHelpers.getObjectField(param.thisObject, "mAm$mContext");
but that didn't work either.
Is there a way to get a field from a nested, internal object?
Thanks!
Ryan
Nevermind. Dumb question. Obviously, you do this:
Code:
Object am = (Object)XposedHelpers.getObjectField(param.thisObject, "mAm");
Context context = (Context) XposedHelpers.getObjectField(am, "mContext");
Code:
public void random(View view){
int min = 0;
int max = 5;
int ran = Random.nextInt((max - min) + 1) + min;
TextView t = (TextView) findViewById(R.id.msg);
t.setText(ran);
}
screwing up on the random line giving error => Error25, 31) error: non-static method nextInt(int) cannot be referenced from a static context
====================================
Edit
====================================
redid it
Code:
public void random(View view){
Random rand = new Random();
int number = rand.nextInt(10)+1;
TextView t = (TextView) findViewById(R.id.msg);
t.setText(""+number);
}
Random is not based on the cpu clock, but the seed used can be based on the current time for example.
How it works
As anything that happens in a computer, the result of a calculation is deterministic and cannot be really random. Basically, the random function remembers the latest returned value, and calculates the new one starting from the old one, for example:
X(i) = (a*X(i-1) + b)mod where a, b and n are constants
so a (pseudo)random function actually returns a predictable sequence of numbers based on the first value. In C you can specify the first value (seed) with srand():
srand(time(NULL));
For example in this way you initialize the seed to the current number of seconds. But if you know the starting value, again the sequence is predictable.
Problems
This is not good for numerous reasons, mainly related to security: for example, if you have a web session identified by a random number given from the server to the user at login, and an attacker is able to predict it, this can be used to impersonate the real user.
Usually is the same with the other programming languages. The only way to get better random numbers, is to rely also on inputs given by the user, such as mouse movements, key press and so on. This gives more unpredictability to the generated value, and this is how OS number generators such as /dev/random work.
Please delete if this is wrong forum for asking about module development. I come into this problem, look at this method :
private void x(ArrayList<y> arrayList) {
arrayList.add("key1","value1");
arrayList.add("key2","value2");
}
This method does not have any return value, it does nothing else, only modifies the input parameter arrayList (adds something to the array). It is like a reference to object, and i want to make changes to the object . Is it even possible to change the input parameter (it is like a reference)? Even if i do
param.args[0] = null;
in afterHookedMethod, it does not influence the arrayList outside of method x();
If you want the function to use modified parameters you need to set them in beforeHookedMethod.