Skip to content

Commit 08eccda

Browse files
authored
Merge pull request #380 from AppDevNext/StrictMode
Strict mode
2 parents 07cc8d9 + 55e9ca0 commit 08eccda

File tree

5 files changed

+77
-41
lines changed

5 files changed

+77
-41
lines changed
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
package info.hannes.logcat
22

33
import info.hannes.timber.FileLoggingTree
4+
import kotlinx.coroutines.CoroutineScope
5+
import kotlinx.coroutines.Dispatchers
6+
import kotlinx.coroutines.launch
47
import timber.log.Timber
58

69
open class FileLoggingApplication : LoggingApplication() {
710

811
override fun setupLogging() {
912
super.setupLogging()
10-
externalCacheDir?.let {
11-
Timber.plant(FileLoggingTree(it, this))
13+
CoroutineScope(Dispatchers.IO).launch {
14+
externalCacheDir?.let {
15+
Timber.plant(FileLoggingTree(it, this@FileLoggingApplication))
16+
}
1217
}
1318
}
1419
}

LogcatCoreLib/src/main/java/info/hannes/timber/FileLoggingTree.kt

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import android.util.Log
88
import androidx.lifecycle.LiveData
99
import androidx.lifecycle.MutableLiveData
1010
import info.hannes.logcat.Event
11+
import kotlinx.coroutines.CoroutineScope
12+
import kotlinx.coroutines.Dispatchers
13+
import kotlinx.coroutines.launch
1114
import java.io.File
1215
import java.io.FileWriter
1316
import java.text.SimpleDateFormat
@@ -28,15 +31,17 @@ open class FileLoggingTree(externalCacheDir: File, context: Context? = null, fil
2831
private var logImpossible = false
2932

3033
init {
31-
if (!externalCacheDir.exists()) {
32-
if (!externalCacheDir.mkdirs())
33-
Log.e(LOG_TAG, "couldn't create ${externalCacheDir.absoluteFile}")
34-
}
35-
val fileNameTimeStamp = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date())
36-
file = if (context != null) {
37-
File(externalCacheDir, "${context.packageName}.$fileNameTimeStamp.log")
38-
} else {
39-
File(externalCacheDir, "$filename.$fileNameTimeStamp.log")
34+
externalCacheDir.let {
35+
if (!it.exists()) {
36+
if (!it.mkdirs())
37+
Log.e(LOG_TAG, "couldn't create ${it.absoluteFile}")
38+
}
39+
val fileNameTimeStamp = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date())
40+
file = if (context != null) {
41+
File(it, "${context.packageName}.$fileNameTimeStamp.log")
42+
} else {
43+
File(it, "$filename.$fileNameTimeStamp.log")
44+
}
4045
}
4146
}
4247

@@ -55,11 +60,15 @@ open class FileLoggingTree(externalCacheDir: File, context: Context? = null, fil
5560
else -> "$priority"
5661
}
5762

58-
val writer = FileWriter(file, true)
5963
val textLine = "$priorityText $logTimeStamp$tag$message\n"
60-
writer.append(textLine)
61-
writer.flush()
62-
writer.close()
64+
CoroutineScope(Dispatchers.IO).launch {
65+
runCatching {
66+
val writer = FileWriter(file, true)
67+
writer.append(textLine)
68+
writer.flush()
69+
writer.close()
70+
}
71+
}
6372

6473
if (Thread.currentThread().name == "main")
6574
_lastLogEntry.value = Event(textLine)

LogcatCoreUI/src/main/java/info/hannes/logcat/base/LogBaseFragment.kt

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
1919
import androidx.recyclerview.widget.RecyclerView
2020
import com.google.android.material.snackbar.Snackbar
2121
import info.hannes.logcat.ui.R
22+
import kotlinx.coroutines.CoroutineScope
2223
import kotlinx.coroutines.Dispatchers
2324
import kotlinx.coroutines.launch
2425
import kotlinx.coroutines.withContext
@@ -223,33 +224,37 @@ abstract class LogBaseFragment : Fragment() {
223224
}
224225

225226
private fun sendLogContent(filterLogs: List<String>, filename: String) {
226-
val logToSend = File(requireActivity().externalCacheDir, filename)
227-
logToSend.writeText(filterLogs.joinToString("\n"))
228-
229-
val intent = Intent(Intent.ACTION_SEND)
230-
231-
val logsUri = FileProvider.getUriForFile(requireContext(), context?.applicationContext?.packageName + ".provider", logToSend)
232-
233-
intent.putExtra(Intent.EXTRA_EMAIL, emailAddress)
234-
val subject = String.format(filename, getString(R.string.app_name))
235-
intent.putExtra(Intent.EXTRA_SUBJECT, subject)
236-
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
237-
intent.type = MAIL_ATTACHMENT_TYPE
238-
intent.putExtra(Intent.EXTRA_STREAM, logsUri)
239-
try {
240-
// prevent from a "exposed beyond app through ClipData.Item.getUri()"
241-
// https://stackoverflow.com/questions/48117511/exposed-beyond-app-through-clipdata-item-geturi
242-
val builder = StrictMode.VmPolicy.Builder()
243-
StrictMode.setVmPolicy(builder.build())
244-
245-
startActivity(Intent.createChooser(intent, "$filename ..."))
246-
} catch (e: ActivityNotFoundException) {
247-
val snackBar = Snackbar.make(
227+
CoroutineScope(Dispatchers.IO).launch {
228+
val logToSend = File(requireActivity().externalCacheDir, filename)
229+
logToSend.writeText(filterLogs.joinToString("\n"))
230+
231+
val intent = Intent(Intent.ACTION_SEND)
232+
233+
val logsUri = FileProvider.getUriForFile(requireContext(), context?.applicationContext?.packageName + ".provider", logToSend)
234+
235+
intent.putExtra(Intent.EXTRA_EMAIL, emailAddress)
236+
val subject = String.format(filename, getString(R.string.app_name))
237+
intent.putExtra(Intent.EXTRA_SUBJECT, subject)
238+
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
239+
intent.type = MAIL_ATTACHMENT_TYPE
240+
intent.putExtra(Intent.EXTRA_STREAM, logsUri)
241+
try {
242+
// prevent from a "exposed beyond app through ClipData.Item.getUri()"
243+
// https://stackoverflow.com/questions/48117511/exposed-beyond-app-through-clipdata-item-geturi
244+
val builder = StrictMode.VmPolicy.Builder()
245+
StrictMode.setVmPolicy(builder.build())
246+
247+
startActivity(Intent.createChooser(intent, "$filename ..."))
248+
} catch (e: ActivityNotFoundException) {
249+
val snackBar = Snackbar.make(
248250
requireActivity().findViewById(android.R.id.content),
249251
R.string.log_send_no_app,
250252
Snackbar.LENGTH_LONG
251-
)
252-
snackBar.show()
253+
)
254+
CoroutineScope(Dispatchers.Main).launch {
255+
snackBar.show()
256+
}
257+
}
253258
}
254259
}
255260

sample/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ dependencies {
4141
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
4242
implementation "androidx.appcompat:appcompat:1.4.2"
4343
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
44+
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
4445

4546
androidTestImplementation 'com.github.AppDevNext:Moka:1.3'
4647
androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_core"

sample/src/main/java/info/hannes/logcat/sample/CrashlyticApplication.kt

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@ package info.hannes.logcat.sample
33
import android.annotation.SuppressLint
44
import android.os.Handler
55
import android.os.Looper
6+
import android.os.StrictMode
67
import android.provider.Settings
78
import com.google.firebase.crashlytics.FirebaseCrashlytics
89
import info.hannes.crashlytic.CrashlyticsTree
910
import info.hannes.logcat.LoggingApplication
1011
import info.hannes.timber.FileLoggingTree
12+
import kotlinx.coroutines.CoroutineScope
13+
import kotlinx.coroutines.Dispatchers
14+
import kotlinx.coroutines.launch
1115
import timber.log.Timber
1216

1317

@@ -17,8 +21,20 @@ class CrashlyticApplication : LoggingApplication() {
1721
override fun onCreate() {
1822
super.onCreate()
1923

20-
externalCacheDir?.let {
21-
Timber.plant(FileLoggingTree(it, this))
24+
StrictMode.setThreadPolicy(
25+
StrictMode.ThreadPolicy.Builder()
26+
.detectDiskReads()
27+
.detectDiskWrites()
28+
.detectNetwork()
29+
.penaltyDialog()
30+
.penaltyLog()
31+
.build()
32+
)
33+
34+
CoroutineScope(Dispatchers.IO).launch {
35+
externalCacheDir?.let {
36+
Timber.plant(FileLoggingTree(it, this@CrashlyticApplication))
37+
}
2238
}
2339

2440
FirebaseCrashlytics.getInstance().setCustomKey("VERSION_NAME", info.hannes.logcat.ui.BuildConfig.VERSIONNAME)

0 commit comments

Comments
 (0)