web-dev-qa-db-fra.com

Lire logcat par programme dans l'application

Je souhaite lire et réagir aux journaux logcat au sein de mon application.

J'ai trouvé le code suivant: 

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) {}

Ce code renvoie en effet les journaux logcat créés jusqu'au démarrage de l'application - 

Mais est-il possible d'écouter en permanence même les nouveaux journaux logcat?

96
David

Vous pouvez continuer à lire les journaux en supprimant simplement l'indicateur "-d" dans votre code ci-dessus.

L'indicateur "-d" indique à logcat d'afficher le contenu du journal et de quitter. Si vous supprimez l'indicateur, logcat ne se terminera pas et continuera à envoyer toute nouvelle ligne ajoutée à celle-ci.

N'oubliez pas que cela peut bloquer votre application si elle n'est pas correctement conçue.

bonne chance.

51
Luis

Vous pouvez effacer votre logcat avec cette méthode que j'utilise pour effacer après avoir écrit logcat dans un fichier afin d'éviter les lignes en double

public void clearLog(){
     try {
         Process process = new ProcessBuilder()
         .command("logcat", "-c")
         .redirectErrorStream(true)
         .start();
    } catch (IOException e) {
    }
}
8
Jan Ziesse

Le drapeau "-c" efface le tampon.

-c Efface (efface) la totalité du journal et quitte.

3
Allen

Voici un moyen rapide de montage/insertion qui peut être utilisé pour capturer tous les éléments de journal actuels ou tous nouveaux (depuis la dernière demande).

Vous devriez modifier/étendre cela, parce que vous voudrez peut-être renvoyer un flux continu plutôt qu'un LogCapture.

Le "Manuel" Android LogCat: https://developer.Android.com/studio/command-line/logcat.html importer 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);
  }

}

Dans votre projet qui effectue la journalisation des activités:

Logger log = new Logger("SuperLog");
// perform logging methods

Lorsque vous voulez capturer tout ce que vous avez enregistré via "Logger"

LogCapture capture = Logger.getLogCat("main");

Quand vous avez faim et que vous voulez grignoter plus de bûches

LogCapture nextCapture = capture.getNextCapture();

Vous pouvez obtenir la capture sous forme de chaîne avec

String captureString = capture.toString();

Ou vous pouvez obtenir les éléments de journal de la capture avec

String logItem = capture.log.get(itemNumber);

Il n’existe pas de méthode statique exacte pour capturer les clés de journal étrangères, mais il existe néanmoins un moyen

LogCapture foreignCapture = Logger.getLogCat("main", null, foreignCaptureKeyList);

En utilisant ce qui précède, vous pourrez également appeler Logger.this.nextCapture sur la capture étrangère.

2
Hypersoft Systems
            //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"))
              {
              }
            }

Je l'utilise dans mon application et cela fonctionne . Et vous pouvez utiliser le code ci-dessus dans Timer Task afin qu'il n'arrête pas votre thread principal 

        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);
      }
0
Reetpreet Brar