在Android应用上屏幕显示日志消息

18

在Android应用程序中,是否有可能将我使用android.util.Log打印的日志消息显示在屏幕上?

是否有其他更好的方法只是在屏幕上输出行?

类似于System.out.println的东西?


14
人们总是不看问题的关键点,很奇妙。显然,楼主想在屏幕上打印文本行,而所有的答案都指向了记录解决方案。 - Kyberias
4个回答

3

是的,zero4

你正在尝试在Android shell上运行“logcat”命令,并将命令输出作为输出流获取。这个链接会对你有所帮助。


3
像其他人建议的一样,您可以使用日志记录。如果您正在使用模拟器或调试设备,则可以使用adb logcat查看消息。在Eclipse调试透视图中,有一个窗口可以为您执行此操作。
另一种方法是在没有附加调试器的情况下使用CatLog - Logcat Reader应用程序。

1
这非常有用,但如果您需要在应用程序中包含日志,则下面100rabh的答案就是所需的。(一种读取android.util.Log并在应用程序中显示它的方法) - dubmojo
1
另外,CatLog现在需要Root权限。如果您没有Root权限,则我迄今为止找到的唯一方法是作为非root shell命令从您的应用程序中调用"logcat"(请参见100rabh的回答提供的链接)。 - dubmojo
androidPIT.com的链接已经失效,日期为2018年1月25日。 - Mneckoee

2
我使用"android.widget.Toast.makeText(Context context, CharSequence text, int duration)"来实现你所要求的功能。这似乎是在屏幕上快速显示一些消息并自动消失的最简单方法(基于最后一个参数)。
:-)

1
真的吗?Toast是用于消息的,而不是像android.util.Log一样用于流日志输出。尝试在10秒内使用LENGTH_SHORT将Toast重复50次。您将在接下来的5分钟内一个接一个地查看Toast。另外,您是如何从android.util.Log中读取信息的呢? - dubmojo
在你决定给我点踩之前,请参考一下问题。他想要一种将日志消息打印到屏幕上的方法。请注意,问题不是如何从日志中读取并写入屏幕,而是在代码进行日志记录时控制它。我并没有建议使用 toast 来编写他所有的日志(这显然不是一个好主意),但如果他想要在屏幕上看到一些关键信息(这是他问题的主要要求),我仍然坚持我的“备选” Toast 建议(除了 logcat),除非我看到你的“更好和通用”的解决方案,而这个解决方案不是 logcat。 - Kumar Rangarajan
我明白了。“他想要一种将日志消息打印到屏幕上的方法。” 不,他想要一种将android.util.Log消息打印到屏幕上的方法。如果您自己需要这样做(我需要,这就是为什么我偶然发现了这个SO问题),您不会建议使用Toast,因为它无法从应用程序中读取Log,也无法显示记录到android.util.Log的消息类型。 Log不仅是调试的一种方式,而Toast是一种替代调试工具。您无法从应用程序中的任何位置进行Toast,但可以进行Log。对我来说,-1分也失去了分数。这个答案没有帮助。 - dubmojo
说得好。我猜我误解了问题,应该被扣1分 :) - Kumar Rangarajan
太好了!我和许多人一样丢失了我的logcat(参见:https://dev59.com/-GQm5IYBdhLWcg3wrAeX)。这是一个很好的解决方法。谢谢! - Ray Tayek

0

嗯,有一个解决方案可以使用this库在屏幕上记录任何你想要的内容。但它对我来说没有用,所以我开发了自己的解决方案,你可以在这里找到一个示例。它非常简单,只需将OnScreenLog类添加到你的项目中即可。

package br.com.ideiageni.onscreenlogSample;

import android.app.Activity;
import android.graphics.Color;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;


/**
 * Created by ariel on 07/07/2016.
 */
    public class OnScreenLog {
    private static int timeoutTime = 1000;
    private static TextView tvLog;
    private static int logCount = 0;
    private static int logCountMax = 30;
    private static String[] logs = new String[logCountMax];
    private static int cntClicks = 0;
    private static boolean visibility = false;
    private static Activity activity;
    private int maxClicks = 5;

    public OnScreenLog(){}

    public OnScreenLog(Activity activity, int ViewID){
        OnScreenLog.activity = activity;
        tvLog = new TextView(activity.getApplicationContext());
        maintainLog("Log is working");
        tvLog.setLayoutParams(new RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.WRAP_CONTENT,
            RelativeLayout.LayoutParams.WRAP_CONTENT));
        tvLog.setTextColor(Color.BLACK);
        tvLog.setBackgroundColor(Color.LTGRAY);
        tvLog.setAlpha((float) 0.4);

        View v = null;
        LinearLayout linearLayout;
        RelativeLayout relativeLayout;
        try {
            linearLayout = (LinearLayout) activity.findViewById(ViewID);
        } catch (ClassCastException e) {linearLayout = null;};

        try {
            relativeLayout = (RelativeLayout) activity.findViewById(ViewID);
        } catch (ClassCastException e) {relativeLayout = null;};
        if(linearLayout != null) {
            linearLayout.addView(tvLog);
            v = linearLayout;
        } else if(relativeLayout != null) {
            relativeLayout.addView(tvLog);
            v = relativeLayout;
        }

        if(v != null) {
            v.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            cntClicks++;
                            timerHandler.removeCallbacks(rTimeout);
                            timerHandler.postDelayed(rTimeout, timeoutTime);

                            if (cntClicks > maxClicks-1) {
                                setLogVisible(!visibility);
                                timerHandler.removeCallbacks(rTimeout);
                                cntClicks = 0;
                            }
                            break;

                    }
                    return false;
                }
            });
        }

    }

    public void log (String text){
        String logText = text;
        maintainLog(logText);
    }

    public void log (int text){
        String logText = String.valueOf(text);
        maintainLog(logText);
    }

    public void log (int[] text){
        StringBuilder builder = new StringBuilder();
        for (int i : text) {
            builder.append(i);
            builder.append("-");
        }
        String logText = builder.toString();
        maintainLog(logText);
    }

    public void log (byte[] text){
        StringBuilder builder = new StringBuilder();
        for (int i : text) {
            builder.append(i);
            builder.append("-");
        }
        String logText = builder.toString();
        maintainLog(logText);
    }

    private void maintainLog(String newText){
        String logText = "";
        if(logCount<logCountMax) logCount++;
        for(int i=logCount-1; i>0; i--){
            logs[i] = logs[i-1];
        }
        logs[0] = newText;
        for(int i=0; i<logCount; i++){
            if(i<logCount-1) logText+=logs[i]+System.getProperty("line.separator");
            else logText+=logs[i];
        }
        tvLog.setText(logText);
    }

    public void clearLog(){
        tvLog.setText("");
    }

    public void setLogVisible(boolean visibility){
        if(visibility) tvLog.setVisibility(View.VISIBLE);
        else tvLog.setVisibility(View.INVISIBLE);
        OnScreenLog.visibility = visibility;
    }

    public static int getLogCountMax() {
        return logCountMax;
    }

    public static void setLogCountMax(int logCountMax) {
        OnScreenLog.logCountMax = logCountMax;
        logs = new String[logCountMax];
    }

    public int getMaxClicks() {
        return maxClicks;
    }

    public void setMaxClicks(int maxClicks) {
        this.maxClicks = maxClicks;
    }

    Handler timerHandler = new Handler();
    Runnable rTimeout = new Runnable() {

        @Override
        public void run() {
            cntClicks = 0;
        }
    };
}

那么,例如:

public class Activity1 extends AppCompatActivity {

private OnScreenLog log;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_1);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    log = new OnScreenLog(this, R.id.content_1);
    log.log("Started log on Activity 1");

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(getApplicationContext(), Activity2.class);
            startActivity(intent);
            log.log("Starting Activity 2");
            Snackbar.make(view, "Starting Activity 2", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });
}

其中R.id.content_1是您活动的主要LinearLayout或RelativeLayout的名称。

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/content_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="br.com.ideiageni.onscreenlogSample.Activity1"
tools:showIn="@layout/activity_1">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Activity 1!" />

</RelativeLayout>

两种解决方案都没有打印当前日志信息,因此您需要告诉它将今天在当前日志上记录的相同信息记录到屏幕上。

工作尚未完成,但可供需要的任何人使用。缺少一些如何使用的说明。欢迎提出建议。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接