내 애플리케이션 내에서 logcat 로그를 읽고 이에 반응하고 싶습니다.
다음 코드를 찾았습니다.
try {
Process process = Runtime.getRuntime().exec("logcat -d");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
StringBuilder log=new StringBuilder();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
}
TextView tv = (TextView)findViewById(R.id.textView1);
tv.setText(log.toString());
}
catch (IOException e) {}
이 코드는 실제로 응용 프로그램이 시작될 때까지 만든 logcat 로그를 반환합니다.
하지만 새로운 logcat 로그도 계속들을 수 있습니까?
답변
위 코드에서 “-d”플래그를 제거하면 로그를 계속 읽을 수 있습니다.
“-d”플래그는 logcat에 로그 내용을 표시하고 종료하도록 지시합니다. 플래그를 제거하면 logcat이 종료되지 않고 추가 된 새 행을 계속 보냅니다.
올바르게 설계되지 않은 경우 애플리케이션이 차단 될 수 있음을 명심하십시오.
행운을 빕니다.
답변
중복 줄을 피하기 위해 logcat을 파일에 쓴 후 지우는 데 사용하는이 방법으로 logcat을 지울 수 있습니다.
public void clearLog(){
try {
Process process = new ProcessBuilder()
.command("logcat", "-c")
.redirectErrorStream(true)
.start();
} catch (IOException e) {
}
}
답변
코 루틴과 공식 lifecycle-livedata-ktx 및 lifecycle-viewmodel-ktx 라이브러리를 사용하면 다음과 같이 간단합니다.
class LogCatViewModel : ViewModel() {
fun logCatOutput() = liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
Runtime.getRuntime().exec("logcat -c")
Runtime.getRuntime().exec("logcat")
.inputStream
.bufferedReader()
.useLines { lines -> lines.forEach { line -> emit(line) }
}
}
}
용법
val logCatViewModel by viewModels<LogCatViewModel>()
logCatViewModel.logCatOutput().observe(this, Observer{ logMessage ->
logMessageTextView.append("$logMessage\n")
})
답변
다음은 모든 현재 또는 모든 새로운 (마지막 요청 이후) 로그 항목을 캡처하는 데 사용할 수있는 빠른 연결 / 드롭 인입니다.
LogCapture가 아닌 연속 스트림을 반환하고자 할 수 있으므로이를 수정 / 확장해야합니다.
Android LogCat “매뉴얼”: https://developer.android.com/studio/command-line/logcat.html
import android.util.Log;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Stack;
/**
* Created by triston on 6/30/17.
*/
public class Logger {
// http://www.java2s.com/Tutorial/Java/0040__Data-Type/SimpleDateFormat.htm
private static final String ANDROID_LOG_TIME_FORMAT = "MM-dd kk:mm:ss.SSS";
private static SimpleDateFormat logCatDate = new SimpleDateFormat(ANDROID_LOG_TIME_FORMAT);
public static String lineEnding = "\n";
private final String logKey;
private static List<String> logKeys = new ArrayList<String>();
Logger(String tag) {
logKey = tag;
if (! logKeys.contains(tag)) logKeys.add(logKey);
}
public static class LogCapture {
private String lastLogTime = null;
public final String buffer;
public final List<String> log, keys;
LogCapture(String oLogBuffer, List<String>oLogKeys) {
this.buffer = oLogBuffer;
this.keys = oLogKeys;
this.log = new ArrayList<>();
}
private void close() {
if (isEmpty()) return;
String[] out = log.get(log.size() - 1).split(" ");
lastLogTime = (out[0]+" "+out[1]);
}
private boolean isEmpty() {
return log.size() == 0;
}
public LogCapture getNextCapture() {
LogCapture capture = getLogCat(buffer, lastLogTime, keys);
if (capture == null || capture.isEmpty()) return null;
return capture;
}
public String toString() {
StringBuilder output = new StringBuilder();
for (String data : log) {
output.append(data+lineEnding);
}
return output.toString();
}
}
/**
* Get a list of the known log keys
* @return copy only
*/
public static List<String> getLogKeys() {
return logKeys.subList(0, logKeys.size() - 1);
}
/**
* Platform: Android
* Get the logcat output in time format from a buffer for this set of static logKeys.
* @param oLogBuffer logcat buffer ring
* @return A log capture which can be used to make further captures.
*/
public static LogCapture getLogCat(String oLogBuffer) { return getLogCat(oLogBuffer, null, getLogKeys()); }
/**
* Platform: Android
* Get the logcat output in time format from a buffer for a set of log-keys; since a specified time.
* @param oLogBuffer logcat buffer ring
* @param oLogTime time at which to start capturing log data, or null for all data
* @param oLogKeys logcat tags to capture
* @return A log capture; which can be used to make further captures.
*/
public static LogCapture getLogCat(String oLogBuffer, String oLogTime, List<String> oLogKeys) {
try {
List<String>sCommand = new ArrayList<String>();
sCommand.add("logcat");
sCommand.add("-bmain");
sCommand.add("-vtime");
sCommand.add("-s");
sCommand.add("-d");
sCommand.add("-T"+oLogTime);
for (String item : oLogKeys) sCommand.add(item+":V"); // log level: ALL
sCommand.add("*:S"); // ignore logs which are not selected
Process process = new ProcessBuilder().command(sCommand).start();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
LogCapture mLogCapture = new LogCapture(oLogBuffer, oLogKeys);
String line = "";
long lLogTime = logCatDate.parse(oLogTime).getTime();
if (lLogTime > 0) {
// Synchronize with "NO YEAR CLOCK" @ unix epoch-year: 1970
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date(oLogTime));
calendar.set(Calendar.YEAR, 1970);
Date calDate = calendar.getTime();
lLogTime = calDate.getTime();
}
while ((line = bufferedReader.readLine()) != null) {
long when = logCatDate.parse(line).getTime();
if (when > lLogTime) {
mLogCapture.log.add(line);
break; // stop checking for date matching
}
}
// continue collecting
while ((line = bufferedReader.readLine()) != null) mLogCapture.log.add(line);
mLogCapture.close();
return mLogCapture;
} catch (Exception e) {
// since this is a log reader, there is nowhere to go and nothing useful to do
return null;
}
}
/**
* "Error"
* @param e
*/
public void failure(Exception e) {
Log.e(logKey, Log.getStackTraceString(e));
}
/**
* "Error"
* @param message
* @param e
*/
public void failure(String message, Exception e) {
Log.e(logKey, message, e);
}
public void warning(String message) {
Log.w(logKey, message);
}
public void warning(String message, Exception e) {
Log.w(logKey, message, e);
}
/**
* "Information"
* @param message
*/
public void message(String message) {
Log.i(logKey, message);
}
/**
* "Debug"
* @param message a Message
*/
public void examination(String message) {
Log.d(logKey, message);
}
/**
* "Debug"
* @param message a Message
* @param e An failure
*/
public void examination(String message, Exception e) {
Log.d(logKey, message, e);
}
}
활동 로깅을 수행하는 프로젝트에서 :
Logger log = new Logger("SuperLog");
// perform logging methods
“Logger”를 통해 기록한 모든 것을 캡처하려는 경우
LogCapture capture = Logger.getLogCat("main");
배가 고파서 더 많은 통나무를 먹고 싶을 때
LogCapture nextCapture = capture.getNextCapture();
캡처를 문자열로 가져올 수 있습니다.
String captureString = capture.toString();
또는 다음을 사용하여 캡처의 로그 항목을 가져올 수 있습니다.
String logItem = capture.log.get(itemNumber);
외래 로그 키를 캡처하는 정확한 정적 방법은 없지만 더 적은 방법이 있습니다.
LogCapture foreignCapture = Logger.getLogCat("main", null, foreignCaptureKeyList);
위의 내용을 사용하면 Logger.this.nextCapture
해외 캡처 를 요청할 수도 있습니다 .
답변
“-c”플래그는 버퍼를 지 웁니다.
-c 전체 로그를 지우고 (플러시) 종료합니다.
답변
//CLEAR LOGS
Runtime.getRuntime().exec("logcat -c");
//LISTEN TO NEW LOGS
Process pq=Runtime.getRuntime().exec("logcat v main");
BufferedReader brq = new BufferedReader(new InputStreamReader(pq.getInputStream()));
String sq="";
while ((sq = brq.readLine()) != null)
{
//CHECK YOUR MSG HERE
if(sq.contains("send MMS with param"))
{
}
}
내 앱에서 이것을 사용하고 있으며 작동합니다. 그리고 Timer Task에서 위의 코드를 사용하여 메인 스레드를 중지하지 않도록 할 수 있습니다.
Timer t;
this.t.schedule(new TimerTask()
{
public void run()
{
try
{
ReadMessageResponse.this.startRecord();//ABOVE METHOD HERE
}
catch (IOException ex)
{
//NEED TO CHECK SOME VARIABLE TO STOP MONITORING LOGS
System.err.println("Record Stopped");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
ReadMessageResponse.this.t.cancel();
}
}
}, 0L);
}