Send Debug Info ¶
Setup ¶
Download the
SendDebugInfo
project
archive file or clone the project with Git
See the Configure Android Example guide.
Run the example ¶
In Android Studio, from the
File
menu, select
Sync
Project
with
Gradle
Files
|
How it works ¶

1override fun onCreate(savedInstanceState: Bundle?)
2{
3 super.onCreate(savedInstanceState)
4 setContentView(R.layout.activity_main)
5 progressBar = findViewById(R.id.progressBar)
6 gemSurfaceView = findViewById(R.id.gem_surface)
7 sendDebugInfoButton = findViewById(R.id.sendDebugInfo)
8 progressBar.visibility = View.VISIBLE
9 sendDebugInfoButton.setOnClickListener {
10 var subject = ""
11 SdkCall.execute {
12 subject = GemSdk.sdkVersion?.let {
13 String.format("User feedback (SDK example) - %d.%d.%d.%d.%s", it.major, it.minor, it.year, it.week, it.revision)
14 } ?: "User feedback"
15 System.gc()
16 }
17 GEMLog.debug(this, "This is an UI message!")
18 sendFeedback(this, "support@magicearth.com", subject)
19 }
20 SdkSettings.onMapDataReady = {
21 Util.postOnMain {
22 progressBar.visibility = View.GONE
23 sendDebugInfoButton.visibility = View.VISIBLE
24 }
25 }
26 SdkSettings.onApiTokenRejected = {
27 showDialog("TOKEN REJECTED")
28 }
29 if (!Util.isInternetConnected(this))
30 {
31 showDialog("You must be connected to the internet!")
32 }
33}
onCreate()
function is overridden in the
MainActivity:
AppCompatActivity()
class, and checks if
internet access is available, showing a dialog message if not.
findViewById()
is used to obtain pointers to the various
graphical user interface elements where text or graphical data
is to be displayed.
sendDebugInfoButton.setOnClickListener
{
sendFeedback(this,
"support@magicearth.com",
subject)
SdkSettings.onMapDataReady
=
{
sendDebugInfoButton.visibility
=
View.VISIBLE
1private fun sendFeedback(a: Activity, email: String, subject: String)
2{
3 val sendFeedbackTask = SendFeedbackTask(a, email, subject)
4 sendFeedbackTask.execute(null)
5}
sendFeedback()
function executes the
sendFeedbackTask
.
1private class SendFeedbackTask(val activity: Activity, val email: String, val subject: String)
2: CoroutinesAsyncTask<Void, Void, Intent>()
3{
4 override fun doInBackground(vararg params: Void?): Intent
5 {
6 val subjectText = subject
7 val sendIntent = Intent(Intent.ACTION_SEND_MULTIPLE)
8 sendIntent.type = "message/rfc822"
9 sendIntent.putExtra(Intent.EXTRA_EMAIL, arrayOf(email))
10 sendIntent.putExtra(Intent.EXTRA_SUBJECT, subjectText)
11 val emailBody = "\n\n$subjectText"
12 sendIntent.putExtra(Intent.EXTRA_TEXT, emailBody)
13 var publicLogPath = ""
14 val privateLogPath = GemSdk.appLogPath
15 privateLogPath?.let {
16 val path = GemUtil.getApplicationPublicFilesAbsolutePath(activity, "phoneLog.txt")
17 if (GemUtil.copyFile(it, path))
18 {
19 publicLogPath = path
20 }
21 }
22 val uris = ArrayList<Uri>()
23 if (publicLogPath.isNotEmpty())
24 {
25 val file = File(publicLogPath)
26 file.deleteOnExit()
27 try
28 {
29 uris.add(FileProvider.getUriForFile(activity, activity.packageName + ".provider", file))
30 }
31 catch (e: Exception)
32 {
33 GEMLog.error(this, "SendFeedbackTask.doInBackground(): error = ${e.message}")
34 }
35 }
36 if (GemSdk.internalStoragePath.isNotEmpty())
37 {
38 val gmCrashesPath = GemSdk.internalStoragePath + File.separator + "GMcrashlogs" + File.separator + "last"
39 val file = File(gmCrashesPath)
40 if (file.exists() && file.isDirectory)
41 {
42 val files = file.listFiles()
43 files?.forEach breakLoop@{
44 try
45 {
46 uris.add(FileProvider.getUriForFile(activity, activity.packageName + ".provider", it))
47 }
48 catch (e: Exception)
49 {
50 GEMLog.error(this, "SendFeedbackTask.doInBackground(): error = ${e.message}")
51 }
52 return@breakLoop
53 }
54 }
55 }
56 sendIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris)
57 return sendIntent
58 }
59 override fun onPostExecute(result: Intent?)
60 {
61 if (result == null)
62 {
63 return
64 }
65 activity.startActivity(result)
66 }
67}
sendFeedbackTask
class contains two overridden functions:
override
fun
doInBackground()
override
fun
onPostExecute()