[Miscellaneous Android Development] Chron0s:
Mediatek and GPS, ah, how we love trying to get it to work. People have been making foil antennas, tweaking GPS.conf, meddling with NTP and all manner of other things to get it working only to find that the very next day it is back to sullenly sitting there with ne'er a satellite in view. Duff hardware? It seems likely - only it's not. There is nothing at all wrong with the Mediatek GPS hardware. When it is allowed to work, it works as well as anything I've come across, SiRF included.

The problem is assumption on the part of manufacturers and our insatiable lust for a bargain. Assume makes an ass of u and me.

Prerequisites:

Root and the ability to mount /system RW. Sorry if you're one of these people who flatly refuses to root their devices, this is not the solution you're looking for <fx:waves hands/>

Some method of getting into MTK Engineering Mode, whether that's MobileUncle, the "secret" dialler code, GravityBox etc.

A text editor that doesn't follow the MS rule that their line breaks are correct and everyone else+dog is wrong. Notepad++ will do for those of you who cannot break the Redmond shackles. MS Notepad is just going to corrupt the files.

ADB set up and working.

No allergy to XML. If you start sneezing, your eyes start streaming or anything happens to your vision after looking at a few <>'s, please discontinue use.

Step 1: Disable EPO. It's worse than useless for any other starting location but Shenzhen. If you don't believe me, try enabling it again after you complete the rest of the steps. Go into engineering mode and, under Location/Location based service/EPO deselect the obvious checkboxes. This on its own improves matters enormously. With some ROMs you can also do this through Settings by tapping the "GPS satellites" item in Location access and deselect the "Enable EPO assistance" checkbox.

Step 2: Mount /system read/write with whatever method you normally use, whether that's adb remount, adb shell mount -o rw,remount /system or whatever.

Step 3: cd to a clean directory, say MTKGPS.

Step 4: adb pull the following files:

/system/etc/gps.conf
/system/etc/agps_profiles_conf.xml
/data/data/com.mediatek.lbs.em/shared_prefs/agps_profile.xml

Careful with that last one, it appears in more than one place but it is the com.mediatek.lbs.em version we want

Note the file permissions for these files as they stand on your particular ROM.

-rw-r--r-- root root 164 2014-06-19 18:29 gps.conf
-rw-r--r-- root root 9502 2014-06-20 15:29 agps_profiles_conf.xml
-rw-rw---- u0_a39 u0_a39 2659 2014-06-20 20:21 agps_profile.xml or
-rw-rw---- 10039 10039 2659 2014-06-20 20:21 agps_profile.xml

The owner of the agps_profile.xml file should be the user's UID. It may be different on your handset. Check it first, please. If any of these differ on your ROM, use the permissions on yours as canonical. This is just a guide.

Step 5: Now we're going to do what FasterGPS does, only a bit more. Edit the gps.conf to look something like this:

NTP_SERVER=<your country>.pool.ntp.org
SUPL_HOST=supl.nokia.com
SUPL_PORT=7275
INTERMEDIATE_POS=1
ACCURACY_THRES=5000
DEFAULT_AGPS_ENABLE=TRUE
DEFAULT_USER_PLANE=TRUE

Purists will note I'm using Nokia's SUPL server here. A little research tells me that Google's SUPL is, well, it's a bit pants - and not just because it's one more way they get PII from you. YMMV, beware of the leopard, and so forth. If you want to use the chocolate factory's SUPL, just swap the SUPL_HOST line to supl.google.com.

Save the file.

Step 6: Now let's undo the mistakes of the manufacturer. Unfortunately we have to delve into some unholy XML for this but don't worry, it's not that difficult despite how daunting the file looks in a text editor. Open agps_profile.xml in your editor.

Make sure the following lines (amongst loads of others that should be left alone) appear as shown:

<int name="slp_port" value="7275" />
<string name="slp_code">NOKIA</string>
<boolean name="agps_enable" value="true" />
<string name="slp_addr">supl.nokia.com</string>

That's the barebones. Don't exit the file yet. Locate the following lines:

<float name="nTargetAreaGeolat" value="nn.nnnnn" />
<float name="nTargetAreaGeolng" value="nn.nnnnn" />

See the problem? Try sticking the co-ords from your file into an online mapper. These are passed to the SUPL server no matter what CellID your phone reports. Worse, if you have no cellular radio, it's taken as gospel so you get ephemeris for the middle of China. Useful. This is why cold start takes even longer than it would on a standalone GPS from cold.

Now, what we need to do is set those up for your general location. It doesn't need to be point precise, just a general 0.1 degree lat and long.

IMPORTANT: If you are West of the Meridian, you need to do some jiggery-pokery with your longitude. This file treats the world as a 360 degree ball, so you need to subtract your longitude from 360. For example, if you're 4 deg W of Greenwich, your longitude would be 356.0. 110.3W equates to 249.7. Yes, this number drops as your longitude goes up if you're West.

Save this file.

Step 7: Now let's edit the agps_profiles_conf.xml. This one's fairly easy, just change the end to look like this, with the usual GOOGLE in default_profile if that's your bag:

<agps_conf_para
agps_enable="yes"
ca_enable="no"
cdma_agps_preferred="0"
cp_auto_reset="no"
cp_gemini_pref_sim="1"
cp_up_selection="up"
default_cdma_profile="CDMA1"
default_profile="NOKIA"
disable_after_reboot="no"
ecid_enable="yes"
gpevt="no"
log_file_max_num="10"
ni_request="yes"
notify_timeout="8"
roaming="yes"
si_mode="mb"
supl_version="1"
verify_timeout="8"
/>
</agps_profiles>

Note cp_gemini_pref_sim can be set to 2 if that's your main SIM that usually has a signal. It is used as the CellID source for aGPS, not the data connection the aGPS data is fetched on.

Save the file.

Step 8: Push the files back with adb and set up their ownership and permissions:

adb remount
adb push gps.conf /system/etc/gps.conf
adb push agps_profiles_conf.xml /system/etc/agps_profiles_conf.xml
adb push agps_profile.xml /data/data/com.mediatek.lbs.em/shared_prefs/agps_profile.xml
adb shell chown 10039:10039 /data/data/com.mediatek.lbs.em/shared_prefs/agps_profile.xml
adb shell chmod 660 /data/data/com.mediatek.lbs.em/shared_prefs/agps_profile.xml
adb shell chmod 644 /system/etc/agps_profiles_conf.xml
adb shell chmod 644 /system/etc/gps.conf

Step 9: Reboot and retry your GPS. Once you have checked everything is working, you can re-enable EPO, clear the aGPS data in Engineering Mode and try again just to verify I'm not talking out of my backside. EPO really doesn't help in this guise, at least not in the UK.

In conclusion, these can be made to work. With these changes in place I can get an indoor lock in airplane mode in just under ten seconds a day and a reboot after last using the GPS. You need a rooted device and some bright spark will no doubt automate all of this - I'm no Android hacker so don't look at me. GravityBox would be my guess as it's developed at a remarkable pace - thanks for the app, BTW ;)

I do hope this works for everyone. It would be nice to put this one to bed once and for all. A final note: There may be errors in this. I'm only human. Check, double check, triple check, take backups, all the usual stuff. Flames to /dev/null, please.