GeoLocation available to webservers? - G1 Q&A, Help & Troubleshooting

I use my G1's default browser to access a website hosted by an Apache server running on my home Linux box.
I'd like to modify some of my cgi-bin Perl scripts to record the GeoLocation (Latitude/Longitude) of my G1 at the time its browser accesses those scripts on my home website.
I had hoped the Lat/Long info would automatically be sent to my home server from my G1's browser within some ENV variable. Eg, the HTTP_USER_AGENT variable contains info that's useful to any webserver, such as ".... Android 1.6; ..... G1 Build/DRC83 .... Mobile Safari/525.20.1" and so on.
Is there a way to get the G1 browser to send the GeoPosition info to my home webserver? Or is it already being sent and I just need to look for it in another place?
Thanks in advance for any tips!

I found one answer that works!
This solution, cobbled together with pieces from code on two websites I found, uses javascript and Google Gears.
I'm posting it here in case anyone else searching for the same answer I was happens to stumble on this thread. Just put the code below into a .htm / .html file.
Best regards.
***** NOTE: DUE TO NEW USER RESTRICTIONS IN THIS FORUM FORBIDDING USE OF LINKS IN POSTINGS (SUSPICIONS THAT IT IS SPAM), I'VE BROKEN UP THE TWO URL'S JUST BELOW WITH BLANKS THAT YOU'LL HAVE TO REMOVE.
*****
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript"
src="http : // ajax. googleapis. com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript"
src="http : // code. google. com/apis/gears/gears_init.js"></script>
<script type="text/javascript">
function updatePosition(position) {
alert('Your Latitude/Longitude is: ' + position.coords.latitude + ',' +
position.coords.longitude);
}
function handleError(positionError) {
alert('Attempt to get location failed: ' + positionError.message);
}
var geo = "";
try {window.navgeo = !!(typeof navigator.geolocation != 'undefined');}
catch(e){}
if (window.navgeo) {
geo = navigator.geolocation;
document.write('HTML5: Waiting for permission from User ');
} else {
try {window.gears =
!!(typeof GearsFactory != 'undefined' ||
navigator.mimeTypes['application/x-googlegears'] ||
new ActiveXObject('Gears.Factory')
);
}
catch(e){}
if (window.gears) {
geo = google.gears.factory.create('beta.geolocation');
document.write('Google Gears: Waiting for permission from User.');
}
}
if (geo != "") {
geo.getCurrentPosition(updatePosition, handleError);
} else {
document.write('No GPS data avalable with this Browser/Device.');
}
</script>
</head>
</html>

code not working
Hi,
I'm a newbie.
I tried your code both in 2.2 android emulator, I get the following ..
"Attempt to get location failed. The last location provider is no longer avaialbe"
Also you dont need to add google gears support.. you just do with this -
if (geo != "") {
geo.getCurrentPosition(updatePosition, handleError, {enableHighAccuracy:true});
} else {
document.write('No GPS data avalable with this Browser/Device.');
}
Can you help me out with this?

Related

HTML Panel Help

Hello all. Been a lurker here for ahwile but finally had a question so figured i would sign up.
Ive been working on a panel that is basically a front end to a parts search page online.
Ive got it somewhat working but am having some issues.
Basically what i need to do is take input from the user, pass that into a url and then pass that url into the
Open URL
ive been trying to do this via javascript but i cant seem to get it... is it possible to use a java function such as self.location = "extended://app:start ect ect " to open up the link in IE?
the only way i can get IE to open is via <a href="extended.......>
sorry im not in anyway a java or html guru and havent done anything like this in years so please forgive my ignorance..
any help would be appreciated..
for reference here is the code im attempting to use..if its sloppy or messy, again im not very well versed in html or javascript..
Code:
<html>
<head>
<meta name="MobileOptimized" content="240">
<meta http-equiv="PRAGMA" content="NO-CACHE">
<title>Partsurfer Mobile</title>
<base href="http://partsurfer.hp.com/cgi-bin/spi/main">
<script type="text/javascript">
function gosearchprod() {
var searchstring = document.getElementById('prodsearch').value;
var url ="extended://app:start?app=iexplore.exe&arg=http://partsurfer.hp.com/cgi-bin/spi/main?sel_flg=modsrch&template=main&cpric=&prodsrch=";
var searchurl = url + searchstring;
self.location = searchurl;
}
function gosearchpart() {
var searchstring = document.getElementById('partsearch').value;
var url =
"extended://app:start?app=iexplore.exe&arg=http://partsurfer.hp.com/cgi-bin/spi/main?sel_flg=partinfo&template=main&cpric=&psrchmode=&partsrch=";
var searchurl = url + searchstring;
self.location = searchurl;
}
</script>
</head>
<body>
Mobile Partsurfer<br>
<br>
<br>
By model number or name:<br>
<input name="prodsearch" id="prodsearch" value=""
type="text">
<input name="gobutton" id="gobutton" value="Go!"
onclick="gosearchprod();" type="button"><br>
<br>
By part number:<br>
<input name="partsearch" id="partsearch" value=""
type="text">
<input name="gobutton" id="gobutton" value="Go!"
onclick="gosearchpart();" type="button">
</body>
</html>
anyone?? common i cant be the only one attempting to create html panels here....even if people who know javascript can take a peek that would be awesome..
help... please.?!?
or does anyone know if you can pass variables into the "arg=" instead of say passing in "arg=http:///..........."
say "arg=id1 bla bla bla" ??

[GUIDE] Communication without a context object

Okay guys.
I have seen a lot of posts where people need to trigger an action inside their own app from the xposed class they hooked. Sometimes (quite often) there is no context object to obtain where we could usually send a broadcast or start a service or even maybe an activity from our own apps we wrote.
This guide will allow me to show you how this is possible without the use of a context object. I have used this myself in multiple modules and it works quite wonderfully. I am going to provide as much code as possible without being too specific, that is where you will need your own intuition to figure out some simple things.
Now for the guide
First, obviously, we need to create a new xposed module. That's another thread found here. For the duration of this guide, I am going to assume you have read that. If you have not, stop reading this, and click that link and go read that please Its fun!
Alright, our module has been created, all manifest declarations established all jars imported. Sweet.
Now we are looking at an empty class file that implements the IXPosedHookLoadPackage.
Next, we need to create a class that extends Service. You can either create a nested class inside the Xposed class, or, my personal choice, create an entirely new class inside your package. ***(Don't forget to add this service to your manifest!!!)
Next, we need to create a boot receiver that will start our newly created service when our device gets booted so its already up and running. (Google that if you don't know how to do that.) here is a great read on how to do this.
Now, go back to your service class (either nested or its own file) and create the "onCreate" method. (If not done already)
Inside the onCreate method of your service, we will need to create a file inside the apps files directory. You can do this in the constructor as well if you please. I have the code below showing how to create your new file.
Code:
@Override
public void onCreate() {
super.onCreate();
File myCommands = new File(this.getFilesDir(), "commands");
}
Yes its that
Now that we have our file object created, we need to actually create the file as follows:
Code:
if(!myCommands.exists()) { //Make sure the file doesn't already exist first.
try {
myCommands.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
However, there are some things we need to do to allow the xposed hooked method permissions to read them, which are simple and as follows.
Code:
myCommands.setReadable(true, false);
myCommands.setWritable(true, false);
We need to use the method "setReadable" and "setWriteable" to set the files permission. The first boolean argument sets the file writeable or readable, the second boolean argument restricts it to the owner only, which since we used false, means that everyone can read and write to this file.
So, now lets take a look at our entire onCreate method thus far:
Code:
@Override
public void onCreate() {
super.onCreate();
File myCommands = new File(this.getFilesDir(), "commands");
if(!myCommands.exists()) {
try {
myCommands.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
myCommands.setReadable(true, false);
myCommands.setWritable(true, false);
}
Pretty simple. Now, we need to actually do something with this file. This is where the magic begins to happen
After our file is created, we need to create what is called a FileObserver. The following code explains how to do that.
Code:
FileObserver myActionsObserver = new FileObserver(myCommands.getAbsolutePath()) {
@Override
public void onEvent(int event, String path) {
// This is where things are done. Every time you open, write to, close etc a file. This method is executed.
}
};
Now our file observer is created. However, it is doing nothing. As of now, it does not even listen for file changes. I want to further define what to do on a file change first before I start receiving the changes.
The "onEvent(int event, String path)" method is what we will be defining.
The "event" argument determines what type of event was acted upon the file. For a full explanation, click here. The "CONSTANTS" table shows the different types of events acted upon a file. For this guide, I will be using the constant "CLOSE_WRITE".
So inside the onEvent method we should have this:
Code:
@Override
public void onEvent(int event, String path) {
// This is where things are done. Every time you open, write to, close etc a file. This method is executed.
if(event == FileObserver.CLOSE_WRITE) {
//This is where we are notified that something has happened.
//This is where we can communicate from the xposed hooked method to our own app where we can do whatever we need to do :)
}
}
Now we are notified of the "CLOSE_WRITE" action onto our file. The next step would be to read the text file for our actual command. For instance, we need to start up an activity. So, for the instance of this guide, I will use the command "startActivity".
Once our "onEvent" method is executed and we see that its action was CLOSE_WRITE, we are going to read the file for the action. This is simple, I really don't feel like I should/have to go into this, but I will to make the guide full.
Here we are going to read the file, I am using a BufferedReader for this.
Code:
try {
BufferedReader br = new BufferedReader(new FileReader(myCommands));
String action = br.readLine();
br.close();
} catch(Exception e) {
e.printStackTrace();
}
Now we got a string object of the contents of the file to determine the necessary actions to take. Don't forget to change the myCommands file to final
Now that we have all that setup, we can finally start receiving actions for the file. We simply do this by calling the "startWatching" method of FileObserver as follows.
Code:
myActionsObserver.startWatching();
Now, whenever that file is written to, we will get notified of it in our service
So now that our service is setup, we need to setup our xposed hooked method to write to the file.
I am going to make something up that prolly doesn't exist in android source, but its just an example method that I am going to hook
The only thing to note when creating the file is that we need to hard code the file's path.
Code:
@Override
protected void afterHookedMethod(MethodHookParam param) {
boolean status = (Boolean)XposedHelpers.getObjectField(param.thisObject, "status");
if(status) {
File myCommand = new File(Environment.getDataDirectory() + <your package name here>, "commands");
FileWriter fw = new FileWriter(myCommands);
fw.write("startActivity");
fw.close();
}
Now we have written to our file and our service will receive the action.
That about sums it up You can also do the reverse, you can create a FileObserver inside your xposed hooked method, and use your own activity or service to write to it and then have the xposed hooked method do some actions regarding the command being written to the file.
Please hit thanks and donate if I helped you out! Don't hesitate to ask questions either!
Thanks!
need help
Hi I`m using your code and it`s work I seccessed to comunicate between the module and the FileObserver.
But my problem is that I want to activate some class or send a intent to activate some function from the FileObserver and I don`t find a way to do it.
Do you have any solution for me??
Thanks
doronmazor said:
Hi I`m using your code and it`s work I seccessed to comunicate between the module and the FileObserver.
But my problem is that I want to activate some class or send a intent to activate some function from the FileObserver and I don`t find a way to do it.
Do you have any solution for me??
Thanks
Click to expand...
Click to collapse
This method is beyond hackey. TBH, I'd be embarrassed to use it in my code.
If you want to communicate from Xposed to your main app, add a broadcast reciever and talk to it via intent and putextra. Provided you're not passing sensitive data, this works wonderfully.
digitalhigh said:
This method is beyond hackey. TBH, I'd be embarrassed to use it in my code.
If you want to communicate from Xposed to your main app, add a broadcast reciever and talk to it via intent and putextra. Provided you're not passing sensitive data, this works wonderfully.
Click to expand...
Click to collapse
lol
Why would you be embarrassed? This works perfectly when we have no context object in the class/method being hooked. If coded properly, it functions the exact same way as a broadcast receiver. Where is your solution to communicating without a context object? Not exactly sure why you think this method doesn't work...
elesbb said:
lol
Why would you be embarrassed? This works perfectly when we have no context object in the class/method being hooked. If coded properly, it functions the exact same way as a broadcast receiver. Where is your solution to communicating without a context object? Not exactly sure why you think this method doesn't work...
Click to expand...
Click to collapse
Look, not trying to be mean...it's just a very hacky solution. There are other ways to resolve the context of the class/method being hooked, and better ways to communicate between xposed and the apk code besides writing a file to the /data partition and then watching it. Sure, it works, but IMHO, it's...well...hacky.
digitalhigh said:
Look, not trying to be mean...it's just a very hacky solution. There are other ways to resolve the context of the class/method being hooked, and better ways to communicate between xposed and the apk code besides writing a file to the /data partition and then watching it. Sure, it works, but IMHO, it's...well...hacky.
Click to expand...
Click to collapse
I am not taking you as being mean. Not one bit. Just trying to expand my knowledge and better my code. You said there are other ways to resolve the context of the class/method being hooked, what are they? You said there are better ways to communicate between xposed and the apk code other than writing and listening to a file, well what are they? lol. I am asking so I can use them.
I have done ample research when I wrote this guide, and there were no other ways to communicate when you couldn't get a context object. I do know you can call other methods and such using xposed to get objects, but that in itself is also hacky. I really would like to know what other ways there are so I can use them instead of the current method. A lot of "helper" class files have issues where there is no context because its not needed. Say you have a class file labeled "MathHelper" and you want to hook the method "getFirstZero" and in that method the user wrote something simple like this:
Code:
private int firstZero(String address) {
int returnValue = address.indexOf("0");
return returnValue;
}
THIS IS JUST A POOR EXAMPLE.
You have no context object. And the class is huge. You want your app to, i don't know, show a notification and perform some task when the address is equal to some explicit value. There is no way of telling your app what the address is.
So what would you personally do to resolve this aside from simply creating a method inside the xposed class with the proper actions. I'm honestly curious.

[Q] setBooleanField can't find field?

I feel like I'm missing a piece of the puzzle here.
Basically, I'm trying to hook a constructor with a Context for an argument. The field I'm trying to access is initialized in the same class but outside of the constructor. Neither the constructor nor the field are static, but they are both private (if that makes a difference).
But for whatever reason I just can't find the field in order to modify it (the module throws NoSuchFieldError). What am I doing wrong, and is there a workaround?
My code:
Code:
public void initZygote(final StartupParam sp) throws Throwable {
if (devicePlatformVersion >= 4.0) {
final Class<?> clsViewConfig = ViewConfiguration.class;
try {
final Constructor<?> cstViewConfig = XposedHelpers.findConstructorExact(clsViewConfig, Context.class);
XposedBridge.hookMethod(cstViewConfig, new XC_MethodHook(XCallback.PRIORITY_HIGHEST) {
protected void beforeHookedMethod(final MethodHookParam mhp) {
XposedBridge.log("Inside beforeHookedMethod routine from ViewConfiguration callback....");
XposedHelpers.setBooleanField(mhp.thisObject, "sHasPermanentMenuKeySet", true);
}
});
} catch (Throwable t) {
XposedBridge.log(t);
}
try {
XposedHelpers.findAndHookMethod(clsViewConfig, "hasPermanentMenuKey", XC_MethodReplacement.returnConstant(false));
} catch (Throwable t) {
XposedBridge.log(t);
}
}
}
And here's the target class:
https://github.com/android/platform...core/java/android/view/ViewConfiguration.java
Thanks!
I may have found out why the error is being thrown.
The setBooleanField method tries to call the findField method. findField returns the field as a Field object back to the calling method (setBooleanField). However, if the field is null, findField throws a NoSuchFieldError.
From the XposedHelpers class:
Code:
public static Field findField(Class<?> clazz, String fieldName) {
StringBuilder sb = new StringBuilder(clazz.getName());
sb.append('#');
sb.append(fieldName);
String fullFieldName = sb.toString();
if (fieldCache.containsKey(fullFieldName)) {
Field field = fieldCache.get(fullFieldName);
if (field == null)
throw new NoSuchFieldError(fullFieldName);
return field;
}
try {
Field field = findFieldRecursiveImpl(clazz, fieldName);
field.setAccessible(true);
fieldCache.put(fullFieldName, field);
return field;
} catch (NoSuchFieldException e) {
fieldCache.put(fullFieldName, null);
throw new NoSuchFieldError(fullFieldName);
}
}
Since the field I'm trying to find has only been initialized, it doesn't yet have a value, making findField catch and throw an exception that isn't exactly true. There is such a field, it's just hasn't been set.
Is anyone aware of this potential problem?
I'm going to see if I can get my code to work by catching the exception, hiding the error, and seeing if the field can, in fact, be set with a true.
You might want to open an issue at GitHub. Regarding your problem, couldn't you use afterHookedMethod instead of beforeHookedMethod to set the variable to the value you want?
Thanks for the reply!
I'm using the "before" variant as I want to set the field before the code inside the constructor is executed. Unless I'm overlooking something?
I recently switched to the findAndHookConstructor method to help simplify things a bit, and I tried getting the context from args[0] to see if I could set the field with that. But no matter what I try, NoSuchFieldError keeps getting thrown.
Sent from my SAMSUNG-SGH-I747
(I suggested using afterHookedMethod if the constructor didn't access sHasPermanentKey. Since it does, ignore that suggestion. )
If I understand what you want to do correctly, you could hook the hasPermanentMenuKey method instead?
Anyway, after reading your question again and checking the classes, I think the problem is that the field really isn't there.
getField is just a helper that uses normal reflection, and it should definitely find the field if it exists. I'm guessing you're using a different Android version than the one you're checking the source for, or you're not running AOSP and it's been modified.
If that doesn't help, you could decompile framework.jar (if memory serves right) and make sure the field exists.
I have the method that returns a boolean hooked already, and that works fine. However, many apps use the "get" method to generate a new configuration from the constructor when a context is provided. Hence why I also want to hook the constructor.
I'll definitely find out if my device actually has the field tonight.
Sent from my SAMSUNG-SGH-I747
Well. This explains a lot.
https://github.com/CyanogenMod/andr...core/java/android/view/ViewConfiguration.java
I feel like an idiot now. I have no idea why I just automatically assumed that CM would have kept that field from AOSP. Well, now I just need to dig around in CM's source for a bit.
One more question:
Is there a way to programatically check to see which flavor of Android ROM the user is running? I know there's a check for version/API level, but is there a better way than, say, looking for a file only found in CM releases to verify the user is in fact running CM (as opposed to AOSP, Omni, and anything else that has an original base)?
Thanks!
JJohnson1988 said:
One more question:
Is there a way to programatically check to see which flavor of Android ROM the user is running? I know there's a check for version/API level, but is there a better way than, say, looking for a file only found in CM releases to verify the user is in fact running CM (as opposed to AOSP, Omni, and anything else that has an original base)?
Thanks!
Click to expand...
Click to collapse
As far as I know, the only way would require you to would require you to know every ROM out there. Usually it's enough to just use a try/catch statement for each ROM dependent hook/action.

[Q] Load Local Javascript (Help)

I'm having difficulty loading my Local HTML File with Javascript. I will try explain this my issue as best as possible.
I have created a HTML5 website with Javascript and I've placed this in (main/assets/354) so inside the 354 is the HTML website with the javascript, but not in a folder. I intensionally did not add a JS folder inside the website folder so everything is in the 354 folder including images.
Now when I test the app on the Android Tablet everything seems fine but when I click the (image) which directs me to the local HTML file nothing appears (a white screen) but when you click the screen you can see a loading icon which is the HTML file. I know the reason why its working, its due to not having an extension to the url link. Example /354/index.html?lc=uk but I solved this by adding
HTML:
<body onload="setGetParameter('lc', 'uk');">
in the coding.
But for some reason it doesnt seem to pick up the Javascript or something else (this is what I'm confused on)
If someone could help me figure this out would be much appreciated.
(710.java)
HTML:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_710);
WebView view = new WebView(this);
view.getSettings().setJavaScriptEnabled(true);
view.loadUrl("file:///android_asset/354/index.html");
setContentView(view);
}

Help needed with a View class.

Hi, this is my first post here so please forgive me if I have put this in the wrong section, it was a bit confusing.
I have an application that takes the touch coordinates from onTouchEvent and and puts them in to an SQLite Database.
My three relevant classes:
Main class: TouchDetector.
Custom View class: TouchDetectorView.
Database class: TouchDatabaseHandler.
TouchDetectorView captures the touches and stores the x, y values in variables. I need to access the TouchDatabaseHandler class from this view class in order to send them to the database.
Constructor inside TouchDatabaseHandler class where data is sent to database:
Code:
public TouchDatabaseHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
View class constructor.
Code:
public TouchDetectorView(Context context, AttributeSet attrs) {
super(context, attrs);
dbHandler = new TouchDatabaseHandler([COLOR="Red"][U]this[/U][/COLOR], null, null, 1);
}
What do I replace the this with to make my code work? The tutorial I was following had the dbHandler inside the onCreate but since I am in a View class I do not have on. I apologise if this is very vague, I am a beginner and would appreciate any help and/or feedback.

Categories

Resources