Hi,
Does anyone know of a thread/post including sample code of an XPosed module, explaining how to hook hardware buttons?
A tutorial would be great, but I guess my search skills are rather poor, I can't seem to find one.
If there isn't anything, then I guess I'll try to understand the source code here :
github.com/agentdr8/GoogleCamX/blob/master/src/com/dr8/xposed/gcx/Mod.java
but if there is anything you can point me to, please help!
Thanks.
binhexcraft said:
Hi,
Does anyone know of a thread/post including sample code of an XPosed module, explaining how to hook hardware buttons?
A tutorial would be great, but I guess my search skills are rather poor, I can't seem to find one.
If there isn't anything, then I guess I'll try to understand the source code here :
github.com/agentdr8/GoogleCamX/blob/master/src/com/dr8/xposed/gcx/Mod.java
but if there is anything you can point me to, please help!
Click to expand...
Click to collapse
That module isn't hooking the buttons directly, but the methods in which the keyCode int is being analyzed. Which button(s) are you after and in which scenario(s)?
agentdr8 said:
That module isn't hooking the buttons directly, but the methods in which the keyCode int is being analyzed. Which button(s) are you after and in which scenario(s)?
Click to expand...
Click to collapse
Any button would be okay, home button, volume up/down, power button, any one of them would suffice.
It would suffice if I could specifically hook one of those buttons and execute my own android code within a certain application context, but if it's not possible, then a global hook for one of the keys for all applications would also be nice.
I read the source code last night and yeah you're right. It hooks certain functions that in turn processes the keyCodes. I'm looking for a more general way to hook the buttons regardless of functions that already exist in the application which analyze the buttons pressed(which the above module uses). What if such function doesn't exist? What would I have to hook in order to intercept hardware key input?
Any suggestions?
binhexcraft said:
What if such function doesn't exist? What would I have to hook in order to intercept hardware key input?
Click to expand...
Click to collapse
Look at the source for framework.jar and android-policy.jar. There's a few places there to grab hardware keys globally.
But if you're only interested in a specific app context, I'd go through that app's code to see if there are any key event methods you can hook into. Might be easier.
agentdr8 said:
Look at the source for framework.jar and android-policy.jar. There's a few places there to grab hardware keys globally.
But if you're only interested in a specific app context, I'd go through that app's code to see if there are any key event methods you can hook into. Might be easier.
Click to expand...
Click to collapse
The application is heavily obfuscated with DexGuard, so it's kind of hard to find the right place to hook into.
By the way, is it even possible to hook into DexGuarded application functions? Cause the package, class, method names are all distorted into weird Unicode characters that don't even display correctly when opened in notepad. I'm not sure if XPosed can properly handle non ascii, wierd unicode symbols... is it possible?
But yeah, I'll look into framework.jar and android-policy.jar. If I were to hook a function in those, then I would have to hook the "android" application right?
Thanks.
binhexcraft said:
The application is heavily obfuscated with DexGuard, so it's kind of hard to find the right place to hook into.
By the way, is it even possible to hook into DexGuarded application functions? Cause the package, class, method names are all distorted into weird Unicode characters that don't even display correctly when opened in notepad. I'm not sure if XPosed can properly handle non ascii, wierd unicode symbols... is it possible?
But yeah, I'll look into framework.jar and android-policy.jar. If I were to hook a function in those, then I would have to hook the "android" application right?
Click to expand...
Click to collapse
You should be able to hook obfuscated methods the same. I'm not sure I've run across a DexGuarded app yet, but those with ProGuard have methods in classes like a.b.c.dd() and they work with Xposed, assuming you can figure out where you need to hook.
I believe "com.android.internal" is where you'd want to look for framework classes/methods.
I found what I am looking for!
http://forum.xda-developers.com/xposed/modules/app-home-volume-button-t2637235
https://github.com/rovo89/XposedMod...xposed/mods/tweakbox/VolumeKeysSkipTrack.java
https://github.com/MohammadAG/Xpose...m/mohammadag/enablecardock/EnableCarDock.java
Thanks for your help.
this how I hooked home button!
findAndHookMethod("android.view.View", lpparam.classLoader, "onKeyDown", int.class, KeyEvent.class, new XC_MethodHook() {
@override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
KeyEvent keyEvent = (KeyEvent) param.args[1];
if (keyEvent.getAction() != KeyEvent.KEYCODE_HOME || keyEvent.getAction() != KeyEvent.KEYCODE_BACK)
....;
}
});
i have the same problem...trying again standby
Forgive the necro but this seems like the most relevant thread for what I'm looking for.
With xposed edge not being updated for a13 and pbmc not working either I'm looking to write my own simple app to intercept volume down key presses so i can make double tap toggle the flashlight.
I've found a few examples of hooks but nothing has worked for a13, I would appreciate some insight into where to hook.
Related
Hi there,
Does anyone out there how to preserve/restore the transient state of a CheckBox and/or Radio button?
So far, I'm using the following code, working for textbox
Code:
Public Sub PreserveState_TextBox(ByVal TB As TextBox)
Dim buffer As String = String.Empty
If True = PhoneApplicationService.Current.State.ContainsKey(TB.Name) Then
buffer = TryCast(PhoneApplicationService.Current.State(TB.Name), String)
If Not String.IsNullOrEmpty(buffer) Then
TB.Text = buffer
End If
End If
End Sub
Public Sub RestoreState_TextBox(ByVal TB As TextBox)
If True = PhoneApplicationService.Current.State.ContainsKey(TB.Name) Then
PhoneApplicationService.Current.State.Remove(TB.Name)
End If
PhoneApplicationService.Current.State.Add(TB.Name, TB.Text)
End Sub
it possible to modify the above code to work for Checkbox and/or Radiobutton?
If not, any ideas?
So far, I've been trying the sample "Tombstoning" sample code from Microsoft without any luck...
Thanks in advance!
Hi,
I'm not a VB developer, but storing the state of a checkbox is not much different from storing any other primitive type. What you could do is have a bool variable "isCbChecked" and store that bool state in your PhoneApplicationService.State.
Code:
PhoneApplicationService.Current.State.Add("isCbChecked", myCheckbox.IsChecked)
Then, when you're restoring your app, simply do
Code:
myCheckbox.IsChecked = (bool)PhoneApplicationService.Current.State.ContainsKey("isCbChecked");
keyboardP said:
Hi,
I'm not a VB developer, but storing the state of a checkbox is not much different from storing any other primitive type. What you could do is have a bool variable "isCbChecked" and store that bool state in your PhoneApplicationService.State.
Code:
PhoneApplicationService.Current.State.Add("isCbChecked", myCheckbox.IsChecked)
Then, when you're restoring your app, simply do
Code:
myCheckbox.IsChecked = (bool)PhoneApplicationService.Current.State.ContainsKey("isCbChecked");
Click to expand...
Click to collapse
Thanks a lot for your fast reply.
Can I ask for additional help on how to make your statements into generic procedures, at least to take them to something similar to what I posted?
Don't care if it's in C#
Thanks in advance!
GFR_2009 said:
Thanks a lot for your fast reply.
Can I ask for additional help on how to make your statements into generic procedures, at least to take them to something similar to what I posted?
Don't care if it's in C#
Thanks in advance!
Click to expand...
Click to collapse
Off the top of my head, something like this should work (C# code).
Code:
public static T RestoreState<T>(string key)
{
if (PhoneApplicationService.Current.State.ContainsKey(key))
{
return (T)PhoneApplicationService.Current.State[key];
}
return null;
}
'T' is the type that will be used. In C# 'T' is a special character denoting the generic type, not something I just used
So in the code above, the return type is 'T' and when using RestoreState, it will be 'RestoreState<Textbox>("TB.Name");'. The value of 'TB.Name' will be searched within the dictionary and, if it's found, it will cast that object as 'T' (Textbox) and return it, otherwise it will return null.
Hi,
So far, I did the following and while no error is raised, nothing happens...
Code:
Public Function Backup(ByVal token As String, ByVal value As Object) As Boolean
If Nothing Is value Then
Return False
End If
Dim store = PhoneApplicationService.Current.State
If store.ContainsKey(token) Then
store(token) = value
Else
store.Add(token, value)
End If
Return True
End Function
Public Function Restore(Of T)(ByVal token As String) As T
Dim store = PhoneApplicationService.Current.State
If Not store.ContainsKey(token) Then
Return Nothing
End If
Return CType(store(token), T)
End Function
I call them as follows
Code:
Backup(Me.CheckBox_1.Name, Me.CheckBox_1)
Restore(Of CheckBox)(Me.CheckBox_1.Name)
Don't where is the error, maybe you could take a look and help me out.
Any help is much appreciated!
Where are you calling the Backup and Restore functions? Since your doing page specific things, you could do it in the OnNavigatedFrom and OnNavigatedTo methods, respectively.
keyboardP said:
Where are you calling the Backup and Restore functions? Since your doing page specific things, you could do it in the OnNavigatedFrom and OnNavigatedTo methods, respectively.
Click to expand...
Click to collapse
Hi,
I'm calling them in the OnNavigatedTo and OnNavigatedFrom methods, as you pointed out
Unfortunately, nothing happens at all!
Thanks!
Hi,
As far as I can tell, there's nothing wrong with your saving/loading code. When you call
"Restore(Of CheckBox)(Me.CheckBox_1.Name)", is that returning a bool? You need to assign that bool to the checkbox:
Code:
myCheckbox.IsChecked = Restore(Of CheckBox)(Me.CheckBox_1.Name);
Also, all variables are reset when the page loads, so make sure you have set "myCheckbox.IsChecked" anywhere else on the page that could be called when the page loads.
Please, check the converted code of the above functions, to C#
Code:
public bool Backup(string token, object value)
{
if (null == value)
{
return false;
}
var store = PhoneApplicationService.Current.State;
if (store.ContainsKey(token))
{
store(token) = value;
}
else
{
store.Add(token, value);
}
return true;
}
public T Restore<T>(string token)
{
var store = PhoneApplicationService.Current.State;
if (! (store.ContainsKey(token)))
{
return default(T);
}
return (T)(store(token));
}
Do you think they are OK?
How should I call them ?
Clearly, the restore does not returns a boolean...
Honestly, I'm lost now!
Hope this helps to find the culprit.
It seems okay to me. You'll have to do some debugging. Set a breakpoint inside the Backup and Restore methods. Step through each line and make sure it's going to the line you expect it to and that the value being set is the correct one.
I haven't seen the tombstoning sample from MSDN, but can you get that to work? If so, is the generic method causing the problem? Or can you not get it to work at all?
Hi,
Sorry for the delay in getting back, but I was trying different codes and at least I found the cause.
Code:
Me.NavigationService.Navigate(New Uri("/PivotPage1.xaml?Name=" & "John", UriKind.Relative))
[B]Me.NavigationService.GoBack[/B]()
Me.NavigationService.Navigate(New Uri("/PivotPage1.xaml", UriKind.Relative))
Everything works fine, and the Checkbox state is saved/restored (in the Pivot Page) if I GO BACK using the GoBack hardware button or Me.NavigationService.GoBack
But, the state's dictionary entry is lost or ignored if I go back with the Navigate service (lines 1 and 3)...
Problem is that I need to get back with the query string...
The query string contains a value taken in the SelectedItem event of PAGE2's ListBox, and automatically once retrieved must go back.
I didn't know until know, that NavigationService.Navigate creates a new page instance or something like that in the backstack...
Any sugestions are welcomed!
Hi,
There are various methods you can use depending on the app's architecture. For example, you could have a 'shared' class that contains a shared field that holds the SelectedItem value. When the user selects the item, set the shared field's value and then when you go back, you can get the value from the shared field.
keyboardP said:
Hi,
There are various methods you can use depending on the app's architecture. For example, you could have a 'shared' class that contains a shared field that holds the SelectedItem value. When the user selects the item, set the shared field's value and then when you go back, you can get the value from the shared field.
Click to expand...
Click to collapse
So, no other way to cope with the navigation service?
It's a strange behaviour for sure...
Will try your ideas.
Thanks a lot for your reply!
GFR_2009 said:
So, no other way to cope with the navigation service?
It's a strange behaviour for sure...
Will try your ideas.
Thanks a lot for your reply!
Click to expand...
Click to collapse
There are other ways. For example, instead of using the PhoneApplicationService to store the tombstoning information, you could put it in a querystring for page 2. Then, in page 2, you could add the information from the previous page to a querystring AND the information of the selected item to the querystring. Navigate to page 1, with the querystring that contains information on what was there before and what the user selected. Tombstoning is there for when the user presses the hardware search button, home button, a phone call arrives etc.. It's not there for the navigation of the app. That's where querystrings, shared variables, binary serialization etc... come into play.
The concept of the navigation service is similar to a website. For example, when you submit something and then go back, it might still be there in the page state. However, if you submit something and then reload the previous page by typing it in the address bar, it becomes a completely new page as no state is stored.
keyboardP said:
There are other ways. For example, instead of using the PhoneApplicationService to store the tombstoning information, you could put it in a querystring for page 2. Then, in page 2, you could add the information from the previous page to a querystring AND the information of the selected item to the querystring. Navigate to page 1, with the querystring that contains information on what was there before and what the user selected. Tombstoning is there for when the user presses the hardware search button, home button, a phone call arrives etc.. It's not there for the navigation of the app. That's where querystrings, shared variables, binary serialization etc... come into play.
The concept of the navigation service is similar to a website. For example, when you submit something and then go back, it might still be there in the page state. However, if you submit something and then reload the previous page by typing it in the address bar, it becomes a completely new page as no state is stored.
Click to expand...
Click to collapse
Hi,
Will try your suggested approach, and thanks a lot for the last explanation on how the darn thing works.
Thanks again!
GFR_2009 said:
Hi,
Will try your suggested approach, and thanks a lot for the last explanation on how the darn thing works.
Thanks again!
Click to expand...
Click to collapse
You're welcome . It's one of those things that take a bit of time to understand, but starts to make sense. You might be interested in a free WP7 development ebook by Charles Petzold.
keyboardP said:
You're welcome . It's one of those things that take a bit of time to understand, but starts to make sense. You might be interested in a free WP7 development ebook by Charles Petzold.
Click to expand...
Click to collapse
I already have the book, but will need a deeper reading
So far, I've been testing your idea of using global classes and works ok.
Thanks a lot for being so cooperative, it's much appreciated!
GFR_2009 said:
I already have the book, but will need a deeper reading
So far, I've been testing your idea of using global classes and works ok.
Thanks a lot for being so cooperative, it's much appreciated!
Click to expand...
Click to collapse
No worries! If programming was super easy everyone would be doing it
keyboardP said:
No worries! If programming was super easy everyone would be doing it
Click to expand...
Click to collapse
Never said better!
this is my first post. I am pretty desperate at the moment.
I would like to dynamically create the UI for the WP7 based on a CSV file in Isolated Storage. right now I would settle for just being able to write the UI in XAML from the code behind in C#.
steps that I would like to execute:
1. user clicks a muscle group button which passes a value to another page-done
2. users data is pulled from CSV file and placed in array for easy storage-done
3. for each data element create a XAML TextBlock with the data which is displayed in the UI <-- need some serious help
best I can do is show the XAML code with the <> tags as a string in the UI.
is what I am asking possible?
Thanks for helping.
Knudmt said:
this is my first post. I am pretty desperate at the moment.
I would like to dynamically create the UI for the WP7 based on a CSV file in Isolated Storage. right now I would settle for just being able to write the UI in XAML from the code behind in C#.
steps that I would like to execute:
1. user clicks a muscle group button which passes a value to another page-done
2. users data is pulled from CSV file and placed in array for easy storage-done
3. for each data element create a XAML TextBlock with the data which is displayed in the UI <-- need some serious help
best I can do is show the XAML code with the <> tags as a string in the UI.
is what I am asking possible?
Thanks for helping.
Click to expand...
Click to collapse
Sounds like what you really want to do is dynamically create controls in the code-behind. I would forget about generating "XAML".
Code:
private void AddTextboxesFromCSV(string[] CSVData) {
foreach(string str in CSVData) {
TextBlock tb = new TextBlock();
tb.Name = "txtUserSelectedValue" + CSVData.IndexOf(str);
tb.Text = str;
<YourObject>.Controls.Add(tb);
}
}
Where <YourObject> is the object you want to place the controls into, some sort of layout Panel.
Thanks for the response
I think that is the direction I will be going. Just out of curiosity do you know if what I wanted to do is even possible?
UN app for WP7 does something like this. Go to http://unitednations.codeplex.com/releases/view/57722 and grab the source. Open the source in Visual Studio and browse to the "Framework" folder and open up "BasePage.cs". At the bottom there's a method called AddNavigatingText() that does what I think you are looking to do.
Here's the method:
Code:
protected Grid AddNavigatingText()
{
var NavigatingText = (Grid) XamlReader.Load(
@" <Grid xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" Height=""30"" VerticalAlignment=""Top"" Background=""#CCFFFFFF"">
<TextBlock HorizontalAlignment=""Left"" TextWrapping=""Wrap"" Text=""Navigating..."" Width=""129"" FontSize=""{StaticResource PhoneFontSizeNormal}"" Margin=""24,0,0,0"" FontFamily=""{StaticResource PhoneFontFamilySemiBold}""/>
<ProgressBar Style=""{StaticResource PerformanceProgressBar}"" RenderTransformOrigin=""0.5,0.5"" Margin=""135,0,0,0"" UseLayoutRounding=""False"" Background=""White"" IsIndeterminate=""True"" LargeChange=""0"" />
</Grid>");
this.Content.As<Grid>().Children.Add(NavigatingText);
return NavigatingText;
}
Thanks for the reply. Looks pretty simple. I downloaded the source and signed up for codeplex. However I can not connect to the tfs.codeplex.com
It's not possible to use dynamically created XAML; code is the way to go and much easier IMHO.
When you open the project just hit cancel at the login screen and it will load.
sulphuricaciduk said:
It's not possible to use dynamically created XAML; code is the way to go and much easier IMHO.
Click to expand...
Click to collapse
Agreed, doing it via code with a very basic XAML based page is likely to be faster, and will actually work. It's also a lot easier to fix things than trying to work out what went wrong in XAML you can't see...
I would agree with the statement that creating the controls dynamically would be faster. And def a great deal easier to read It just bugs me when I know this can be accomplished, yet I cant get it to work
Blade0rz said:
Sounds like what you really want to do is dynamically create controls in the code-behind. I would forget about generating "XAML".
Code:
private void AddTextboxesFromCSV(string[] CSVData) {
foreach(string str in CSVData) {
TextBlock tb = new TextBlock();
tb.Name = "txtUserSelectedValue" + CSVData.IndexOf(str);
tb.Text = str;
<YourObject>.Controls.Add(tb);
}
}
Where <YourObject> is the object you want to place the controls into, some sort of layout Panel.
Click to expand...
Click to collapse
Well that worked very well, thanks! I am having a little formatting issue .. my textblocks show up right on top of each other. any ideas?
Thanks again
Knudmt said:
Well that worked very well, thanks! I am having a little formatting issue .. my textblocks show up right on top of each other. any ideas?
Thanks again
Click to expand...
Click to collapse
I solved this silly issue. just added a listbox control to the xaml front end and added my elements with an ugly cast
listbox1.items.add((TextBlock)myBlock);
Knudmt said:
I solved this silly issue. just added a listbox control to the xaml front end and added my elements with an ugly cast
listbox1.items.add((TextBlock)myBlock);
Click to expand...
Click to collapse
If you had a StackPanel as the parent control, you could have each new textblock stacked...
Hello everyone,
I am trying to develop an app to replace the mode switch and map the swc media keys according to which app is opened.
Until now I managevto change between apps using the modeswich button , the previous playing app stops or get killed like it should do.
What I would like to also add, is the functionality to map the media keys of the swc, so that it controls s]tify when its opened, music app when using music app etc.
I cannot find anywhere the original intents being send when the media buttons are pressed, or which intent/activity skips radio stastion/plays next song in the original mtcapps. Can anyone help here?
I am planning to share the app here when its finished
p_mike83 said:
I cannot find anywhere the original intents being send when the media buttons are pressed, or which intent/activity skips radio stastion/plays next song in the original mtcapps. Can anyone help here?
I am planning to share the app here when its finished
Click to expand...
Click to collapse
Register a broadcast receiver for intents with action com.microntek.irkeyDown, and get the intExtra of keycode. Depending on the keycode, different methods are called in the native MTC apps.
agentdr8 said:
Register a broadcast receiver for intents with action com.microntek.irkeyDown, and get the intExtra of keycode. Depending on the keycode, different methods are called in the native MTC apps.
Click to expand...
Click to collapse
Thanks for the help. I knew that it has to do with com.microntek.irkeyDown. do you know how is the syntax with the keycode included in the intent? there is also an intentcom.microntek.irkeyUp, but I cannon understand the difference.
What are the methods that are called in the mtcapps? Can you help me with the call for next/previous preset of the radioapp, and next/previous track of the music/DVD app?
As of now the app changes the mode between radio/music/DVD/spotify and it successfully stop the music played from the other apps, so only the active app plays music.
As I am planingbto release it here, I would like to have suggestions from many of you , what apps you want to be included here
p_mike83 said:
Thanks for the help. I knew that it has to do with com.microntek.irkeyDown. do you know how is the syntax with the keycode included in the intent? there is also an intentcom.microntek.irkeyUp, but I cannon understand the difference.
What are the methods that are called in the mtcapps? Can you help me with the call for next/previous preset of the radioapp, and next/previous track of the music/DVD app?
As of now the app changes the mode between radio/music/DVD/spotify and it successfully stop the music played from the other apps, so only the active app plays music.
As I am planingbto release it here, I would like to have suggestions from many of you , what apps you want to be included here
Click to expand...
Click to collapse
The keycode is an integer, and its value is compared to determine what happens. Take a look at the android.microntek.service.MicrontekServer class in the MTCManager.apk. On the FTP server listed in the wiki, you'll find a VTS project that I zipped up, with all of the MTC apps decompiled.
com.microntek.irkeyUp is just the intent sent after the button is released. I don't think I've run across anything that really uses this though.
agentdr8 said:
The keycode is an integer, and its value is compared to determine what happens. Take a look at the android.microntek.service.MicrontekServer class in the MTCManager.apk. On the FTP server listed in the wiki, you'll find a VTS project that I zipped up, with all of the MTC apps decompiled.
com.microntek.irkeyUp is just the intent sent after the button is released. I don't think I've run across anything that really uses this though.
Click to expand...
Click to collapse
thank you, i will check it out in the next days.
agentdr8 said:
The keycode is an integer, and its value is compared to determine what happens. Take a look at the android.microntek.service.MicrontekServer class in the MTCManager.apk. On the FTP server listed in the wiki, you'll find a VTS project that I zipped up, with all of the MTC apps decompiled.
com.microntek.irkeyUp is just the intent sent after the button is released. I don't think I've run across anything that really uses this though.
Click to expand...
Click to collapse
Hey, I know this is quite an old topic. But could you point me to the location of the VTS project you mentioned?
What I'm looking for is to patch stock MTC apps so that I can make calls using only buttons on the steering wheel. It looks so dumb that I have to make so many touches of the screen (which distracts from driving) just to make a call to one of recent persons... At least it works this way on my device. And there is a hope that it's got fixed on the newer versions..
Rustam_G said:
Hey, I know this is quite an old topic. But could you point me to the location of the VTS project you mentioned?
Click to expand...
Click to collapse
It used to be on the FTP server that was hosted at huifei.fs-fileserver.de. I don't think that exists any more though. Unfortunately I no longer have the original ZIP file.
I'm trying to make a module that replaces methods, modify variables that are passed as parameters, and call methods relatively to the hooked class (this.privateMethod()). But the offial wiki doesn't show how to either replace methods or use parameters.
Now some questions that I have are:
How can I create/modify instances of Objects that exists only in the hooked app? For example if a CustomClass object is passed as a parameter of a method I have hooked, how can I modify variables and call methods in the variable? And how can I create a new instance?
What should I return in a method I hooked with XC_MethodReplacement? It is registered as an Object so I should return something, but the method I'm hooking is a void.
How can I call private methods of a class I have an instance hooked of? Normally I'd call them with this.method(), but I don't think I have access to this "this" variable. Do I?
That's all I can think of from the top of my head, but more are bound to come up along the way. So if you have a reliable source of information like a guide, tutorial or blog post, please tell me!
Baconator724 said:
I'm trying to make a module that replaces methods, modify variables that are passed as parameters, and call methods relatively to the hooked class (this.privateMethod()). But the offial wiki doesn't show how to either replace methods or use parameters.
Now some questions that I have are:
Click to expand...
Click to collapse
http://api.xposed.info/
How can I create/modify instances of Objects that exists only in the hooked app? For example if a CustomClass object is passed as a parameter of a method I have hooked, how can I modify variables and call methods in the variable? And how can I create a new instance?
Click to expand...
Click to collapse
Simply use methods from XposedHelpers class. E.g. you can modify any field of CustomClass instance using appropriate setIntField, setObjectField, ... (depedning on type of variable you need to modify). For calling methods use XposedHelpers.callMethod() or callStaticMethod() in case of static methods.
To create new instance, get one of the defined constructors and call newInstance() (check with Java reflection docs).
What should I return in a method I hooked with XC_MethodReplacement? It is registered as an Object so I should return something, but the method I'm hooking is a void.
Click to expand...
Click to collapse
Simply return null
How can I call private methods of a class I have an instance hooked of? Normally I'd call them with this.method(), but I don't think I have access to this "this" variable. Do I?
Click to expand...
Click to collapse
XposedHelpers.callMethod(object, "methodName", params...)
where object is instance of class method belongs to. If you are within a hook, simply use params.thisObject as object.
Thanks! But could you explain this a bit more detailed?
C3C076 said:
To create new instance, get one of the defined constructors and call newInstance() (check with Java reflection docs).
Click to expand...
Click to collapse
Do I need to import the target APK in my project for this to work?
Baconator724 said:
Thanks! But could you explain this a bit more detailed?
Do I need to import the target APK in my project for this to work?
Click to expand...
Click to collapse
No. Use XposedHelpers.findConstructorExact() to get one of the constructors of class you want to instantiate and call newInstance() on that constructor supplying constructor parameters (if any).
Example : https://github.com/GravityBox/Gravi...low/gravitybox/quicksettings/QsTile.java#L123
Hi,
First, a disclaimer.
I am a Java and xposed noob. My background is in embedded C development so I can get by with some simple Java code and thanks to the great tutorials online I have been able to put together an xposed module but I'm struggling with a problem that is beyond my abilities now and am reaching out to the community for help.
Next, the background.
I have an Android head unit in my car. There is an app that provides me with CarPlay functionality but none of the controls on the steering wheel work with the app. When I analysed the code I found that they handle all of their button inputs using proprietary methods that do not inject an event into any input streams. I wrote an xposed module to hook the button press methods and then inject a proper input into one of the event streams.
Initially I tried to use the command line 'input' command to do this but since it is a Java app and takes about 1s to load it was too slow. My only other option was to create a virtual device on an input stream that I could then use to inject keypresses through the hooked method. To create a virtual device I needed to write C code that my xposed module would be able to access through the JNI. Long story short, after some pain I was able to get the native library integrated into the project and compiling using the NDK.
Finally, the problem.
When I was using the module without the native library it worked but just with a large delay because of the time it takes to load the 'input' java app. I was able to see logs from the module in the logcat as I hooked the method and as I went through the various actions within the hook.
As soon as I introduce the native library though the entire xposed module just stops running completely. I do not get any logs from the module even though I have installed, activated and rebooted. It shows up in the xposed installer but it just does nothing. The funny thing is that this happens even if I make no reference whatsoever to any native functions within the library. All I need to do to kill the module is to build it with the System.loadlibrary line in the Main.java uncommented. As soon as I comment that piece of code out the module starts to hook the function and output logs again. Below is the code from the Main.Java that I am referring to. I am happy to make any manifest, C and gradle files available too. Looking for any ideas as to why the module dies completely as soon as I include this...
Code:
package projects.labs.spike.zlink_xposed_swc;
import de.robv.android.xposed.XposedBridge;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.IXposedHookZygoteInit;
import de.robv.android.xposed.XSharedPreferences;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import de.robv.android.xposed.XposedHelpers;
import android.app.AndroidAppHelper;
import android.content.Intent;
import android.os.Bundle;
import android.content.Context;
/* shellExec and rootExec methods */
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import android.view.KeyEvent;
import android.media.AudioManager;
public class Main implements IXposedHookLoadPackage {
public static final String TAG = "ZLINK_XPOSED ";
public static void log(String message) {
XposedBridge.log("[" + TAG + "] " + message);
}
//public native int CreateVirtualDevice();
//public native int SendPrev();
@Override
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
log("handleLoadPackage: Loaded app: " + lpparam.packageName);
if (lpparam.packageName.equals("com.syu.ms")) {
findAndHookMethod("module.main.HandlerMain", lpparam.classLoader, "mcuKeyRollLeft", new XC_MethodHook() {
@Override
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
// previous
log("PREVKEYHIT");
//rootExec("input keyevent 88");
log("EVENTSENT");
//Below was trying to use media keys which zlink never responded to...
/* Context context = (Context) AndroidAppHelper.currentApplication();
AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PREVIOUS);
mAudioManager.dispatchMediaKeyEvent(event);
KeyEvent event2 = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PREVIOUS);
mAudioManager.dispatchMediaKeyEvent(event2);*/
//Below is the failed broadcast intent method...
/*Context mcontext = (Context) AndroidAppHelper.currentApplication();
Intent i = new Intent("com.android.music.musicservicecommand");
i.putExtra("command", "pause");
mcontext.sendBroadcast(i);*/
}
});
}
}
public static String rootExec(String... strings) {
String res = "";
DataOutputStream outputStream = null;
InputStream response = null;
try {
Process su = Runtime.getRuntime().exec("su");
outputStream = new DataOutputStream(su.getOutputStream());
response = su.getInputStream();
for (String s : strings) {
s = s.trim();
outputStream.writeBytes(s + "\n");
outputStream.flush();
}
outputStream.writeBytes("exit\n");
outputStream.flush();
try {
su.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
res = readFully(response);
} catch (IOException e) {
e.printStackTrace();
} finally {
Closer.closeSilently(outputStream, response);
}
return res;
}
public static String readFully(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = 0;
while ((length = is.read(buffer)) != -1) {
baos.write(buffer, 0, length);
}
return baos.toString("UTF-8");
}
static {
System.loadLibrary("native-lib");
}
}
Have you tried capturing an ADB log _during the bootup_?
Xposed bugs in general are unfortunaley hard to identify and harder to fix, since the underlying code isn't well understood and/or maintained by many people.
Namnodorel said:
Have you tried capturing an ADB log _during the bootup_?
Xposed bugs in general are unfortunaley hard to identify and harder to fix, since the underlying code isn't well understood and/or maintained by many people.
Click to expand...
Click to collapse
Thanks for the response. I think that I have it figured out. The System.loadlibrary method looks for the native library within a path relative to the process that it is running within. The code within the apk ultimately does not run within that apk process, it runs within the xposed process. You therefore need to give xposed an absolute path to the library using the system.load method instead. Going to do some fiddling tonight and see if it works.
looxonline said:
Thanks for the response. I think that I have it figured out. The System.loadlibrary method looks for the native library within a path relative to the process that it is running within. The code within the apk ultimately does not run within that apk process, it runs within the xposed process. You therefore need to give xposed an absolute path to the library using the system.load method instead. Going to do some fiddling tonight and see if it works.
Click to expand...
Click to collapse
What about an alternative without using library we discussed earlier? Are you planning to test this as well?
If so, please let me know how it went.
C3C076 said:
What about an alternative without using library we discussed earlier? Are you planning to test this as well?
If so, please let me know how it went.
Click to expand...
Click to collapse
I didn't try it yet for two reasons.
1.) From the research I have done it seems as if my app would need the system INJECT_EVENTS permission in order to send keypress events outside of its own process. I cannot get this permission unless I sign my apk with the system cert that the ROM is compiled with. Maybe the method that you are using in the suggestion does not need this cert? Have you personally used this to inject key events across processes? I did see that you are getting the context of the system input service so maybe that solves this issue if the request appears to come from that PID...???
2.) The unit that I am working with has only two input devices and none of them have the keycodes I require. Does your method use a completely virtual device that is created on the fly? If so then it could work well without the need for me to create an HID input device.
I mostly was just on a role with the method that I was trying and I didn't want to turn back since I was so far down the road. I'm sure you understand how addictive certain challenges become and its quite fun to try to get them working even if they may not be the most optimal way.
In any case I managed to get the native library working last night and can successfully convince Android that I have a real HID keyboard plugged in and then send key events through that keyboard. Still not done though as there are a few hiccups that need solving. May still try your original suggestion. Thanks
looxonline said:
I didn't try it yet for two reasons.
1.) From the research I have done it seems as if my app would need the system INJECT_EVENTS permission in order to send keypress events outside of its own process. I cannot get this permission unless I sign my apk with the system cert that the ROM is compiled with. Maybe the method that you are using in the suggestion does not need this cert? Have you personally used this to inject key events across processes? I did see that you are getting the context of the system input service so maybe that solves this issue if the request appears to come from that PID...???
2.) The unit that I am working with has only two input devices and none of them have the keycodes I require. Does your method use a completely virtual device that is created on the fly? If so then it could work well without the need for me to create an HID input device.
I mostly was just on a role with the method that I was trying and I didn't want to turn back since I was so far down the road. I'm sure you understand how addictive certain challenges become and its quite fun to try to get them working even if they may not be the most optimal way.
In any case I managed to get the native library working last night and can successfully convince Android that I have a real HID keyboard plugged in and then send key events through that keyboard. Still not done though as there are a few hiccups that need solving. May still try your original suggestion. Thanks
Click to expand...
Click to collapse
I see.
1) Depends on in what process (package) your hooks are running within because permissions of this process apply of course, not the permissions you define in your module's manifest.
I am using key injecting method within "android" process (package) which means it works without me needing to worry about INJECT_EVENTS permission as "android" process already has it.
By the way, missing permissions are not of a big issue when developing with xposed as you can really do some magic with it.
E.g. I was adding some functionality to SystemUI that required some additional permissions that SystemUI typically lacks. So my module takes care of it.
https://github.com/GravityBox/Gravi...eco/pie/gravitybox/PermissionGranter.java#L75
C3C076 said:
I see.
1) Depends on in what process (package) your hooks are running within because permissions of this process apply of course, not the permissions you define in your module's manifest.
I am using key injecting method within "android" process (package) which means it works without me needing to worry about INJECT_EVENTS permission as "android" process already has it.
By the way, missing permissions are not of a big issue when developing with xposed as you can really do some magic with it.
E.g. I was adding some functionality to SystemUI that required some additional permissions that SystemUI typically lacks. So my module takes care of it.
https://github.com/GravityBox/Gravi...eco/pie/gravitybox/PermissionGranter.java#L75
Click to expand...
Click to collapse
Wow! I had no idea that you can use an xposed helper function to grant permissions to whatever process you are hooked within like that. That is VERY cool. Thanks so much for sharing