Here are a few methods to make debugging places easier.
Using mock location
The first suggested method allows a developer to mock location updates. This test doesn’t take into account the underlying logic of the OS, but can be useful for ensuring a proper integration
Android provides the ability to mock location updates on the phone using a number of commands. In order to support this the app is required to include a permission. In order to set this up add the following line to your AndroidManifest:
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
Next, on a device that your app is installed on, install a second app that will allow you to mock the location in the background. One such app we have used for testing is MockGeoFix. In order to properly setup location mocking, follow the steps provided by MockGeoFix for enabling Mock Locations in developer options.
Once MockGeoFix is configured correctly, identify your devices I.P. Address. On a Samsung Galaxy device, this can be found by going to the WiFi networks screen in settings and tapping on the wifi network you are connected to. Take that I.P. Address and run the telnet command. An example would look as follows (with 10.4.0.86 as the I.P. address and 5554 as the default port):
telnet 10.4.0.86 5554
Once connected you can then mock location updates on your device by running the geo
command as follows (the -71.06080111
as the longitude and 42.35937288
as the latitude):
geo fix -71.06080111 42.35937288
Walkabout testing
Using mock location can be useful as a proof of concept, but the proper way to test places is by taking a number of test devices out for a walk around town. The issue with this approach is that it will remove any feedback you have while testing, most importantly logs. To eliminate this concern SDK 4.5 has introduced a new API: Localytics.redirectLogsToDisk(boolean writeExternally, Context context)
Setup
The new API for redirecting logs takes in two parameters:
-
context
: The Applications context object. -
writeExternally
: a boolean value to indicate where to write the logs. If set to false then the logs will be written inside the applications file system. If set to true, then the app will write the logs to the devices external storage.
If a developer chooses to use the external storage then some additional setup is required. In order to write to external storage, the app must ask for permissions to do so. To set this up add the permission to the AndroidManifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Then, inside the onCreate
of your app’s MainActivity
, check to see if the permission was granted, and if not request it:
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_EXTERNAL_PERMISSION); } else { Localytics.redirectLogsToDisk(true, getApplicationContext()); }
Finally, make sure to handle the response of the permission result:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case REQUEST_EXTERNAL_PERMISSION: if (permissions.length > 0 && permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE) && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Localytics.redirectLogsToDisk(true, getApplicationContext()); } break; } }
Setup for SDK <4.5
Setup for SDK <4.5 should be exactly the same as 4.5, but wherever there is a call to Localytics#redirectLogsToDisk replace that with a method call containing the following code:
public static void redirectLogsToDisk(final boolean writeExternally, @NonNull final Context context) { setLoggingEnabled(true); String fileName; if (writeExternally) { fileName = Environment.getExternalStorageDirectory().getPath() + "/console.log"; } else { fileName = context.getFilesDir() + "/console.log"; } try { File file = new File(fileName); if (file.exists() || file.createNewFile()) { String[] cmd = new String[] { "/system/bin/logcat", "-f", fileName, "-v", "time"}; Runtime.getRuntime().exec(cmd); } else { Log.e("TESTING", "Failed to pipe log output to file; Couldn't create log file."); } } catch (Exception e) { Log.e("TESTING", "Failed to pipe log output to file", e); } }
Retrieving the log files
Once that is all setup you can then go for a walk around town to test places. Once you have returned you can pull your logs from the location you specified. In order to do this we suggest the following methods:
-
writeExternally=false
: Android Studio 3.0 has a new Device File Explorer tab. Open up the device file explorer, navigate intodata/data/YOUR_APP_PACKAGE/files/
. Inside this directory you should be able to see aconsole.log
file which can be viewed and extracted.Note, The file explorer doesn’t update on it’s own. If the file isn’t showing up initially, you may have to right click and hit synchronize
-
writeExternally=true
: Writing externally stores the file in your devices external storage. The easiest way to access this is through adb. Run:
adb pull /storage/emulated/0/console.log