Android Open Source - logcat-activity-android Logcat Activity






From Project

Back to project page logcat-activity-android.

License

The source code is released under:

Apache License

If you think the Android project logcat-activity-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package io.leftshift.logcat;
//w w w  .ja v a 2  s .  co  m
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.MenuItemCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.Toast;

public class LogcatActivity extends ListActivity {
    static final SimpleDateFormat LOG_DATE_FORMAT = new SimpleDateFormat(
            "MMM d, yyyy HH:mm:ss ZZZZ");
    private static final Executor EX = Executors.newCachedThreadPool();

    static final int FILTER_DIALOG = 1;

    private static final int PREFS_REQUEST = 1;

    private static final int MENU_FILTER = 1;
    private static final int MENU_SHARE = 5;
    private static final int MENU_PLAY = 6;
    private static final int MENU_CLEAR = 8;
    private static final int MENU_SAVE = 9;
    private static final int MENU_PREFS = 10;
    private static final int MENU_JUMP_TOP = 11;
    private static final int MENU_JUMP_BOTTOM = 12;

    static final int WINDOW_SIZE = 1000;

    static final int CAT_WHAT = 0;
    static final int CLEAR_WHAT = 2;

    private AlertDialog mFilterDialog;
    static final SimpleDateFormat LOG_FILE_FORMAT = new SimpleDateFormat(
            "yyyy-MM-dd-HH-mm-ssZ");

    private ListView mLogList;
    private LogEntryAdapter mLogEntryAdapter;
    private MenuItem mPlayItem;
    private MenuItem mFilterItem;

    private Level mLastLevel = Level.V;
    private Logcat mLogcat;
    private Prefs mPrefs;
    private LogcatActivity mThis;
    private boolean mPlay = true;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case CAT_WHAT:
                    final List<String> lines = (List<String>) msg.obj;
                    cat(lines);
                    break;
                case CLEAR_WHAT:
                    mLogEntryAdapter.clear();
                    break;
            }
        }
    };

    private void jumpTop() {
        pauseLog();
        mLogList.post(new Runnable() {
            public void run() {
                mLogList.setSelection(0);
            }
        });
    }

    private void jumpBottom() {
        playLog();
        mLogList.setSelection(mLogEntryAdapter.getCount() - 1);
    }

    private void cat(final String s) {
        if (mLogEntryAdapter.getCount() > WINDOW_SIZE) {
            mLogEntryAdapter.remove(0);
        }

        Format format = mLogcat.mFormat;
        Level level = format.getLevel(s);
        if (level == null) {
            level = mLastLevel;
        } else {
            mLastLevel = level;
        }

        final LogEntry entry = new LogEntry(s, level);
        mLogEntryAdapter.add(entry);
    }

    private void cat(List<String> lines) {
        for (String line : lines) {
            cat(line);
        }
        jumpBottom();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.logcat_log);
        getWindow().setTitle(getResources().getString(R.string.app_name));

        mThis = this;
        mPrefs = new Prefs(this);

        mLogList = (ListView) findViewById(android.R.id.list);
        mLogList.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {

            @Override
            public void onCreateContextMenu(ContextMenu menu, View v,
                                            ContextMenuInfo menuInfo) {
                MenuItem jumpTopItem = menu.add(0, MENU_JUMP_TOP, 0,
                        R.string.jump_start_menu);
                jumpTopItem.setIcon(android.R.drawable.ic_media_previous);

                MenuItem jumpBottomItem = menu.add(0, MENU_JUMP_BOTTOM, 0,
                        R.string.jump_end_menu);
                jumpBottomItem.setIcon(android.R.drawable.ic_media_next);
            }
        });
        mLogList.setOnScrollListener(new AbsListView.OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                //pauseLog();
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                                 int visibleItemCount, int totalItemCount) {
            }
        });
    }

    private void init() {
        mLogList.setBackgroundColor(Color.WHITE);
        mLogList.setCacheColorHint(Color.WHITE);

        mLogEntryAdapter = new LogEntryAdapter(this, R.layout.logcat_entry,
                new ArrayList<LogEntry>(WINDOW_SIZE));
        setListAdapter(mLogEntryAdapter);
        reset();
        setKeepScreenOn();
    }

    @Override
    public void onResume() {
        //Debug.startMethodTracing("alogcat");
        super.onResume();
        onNewIntent(getIntent());
        init();
        // Log.v("alogcat", "resumed");
    }

    @Override
    public void onPause() {
        super.onPause();
        // Log.v("alogcat", "paused");

        //Debug.stopMethodTracing();
    }

    @Override
    public void onStop() {
        super.onStop();
        if (mLogcat != null) {
            mLogcat.stop();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        pauseLog();
        // Log.v("alogcat", "destroyed");
    }

    @Override
    protected void onSaveInstanceState(Bundle b) {
        // Log.v("alogcat", "save instance");
    }

    @Override
    protected void onRestoreInstanceState(Bundle b) {
        // Log.v("alogcat", "restore instance");
    }

    public void reset() {
        Toast.makeText(this, "Reading logs, please wait.", Toast.LENGTH_SHORT).show();
        mLastLevel = Level.V;

        if (mLogcat != null) {
            mLogcat.stop();
        }

        mPlay = true;

        EX.execute(new Runnable() {
            public void run() {
                mLogcat = new Logcat(mThis, mHandler);
                mLogcat.start();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);

        // TODO: maybe this should be in a menu.xml file. ;)
        mPlayItem = menu.add(0, MENU_PLAY, 0, R.string.pause_menu);
        mPlayItem.setIcon(android.R.drawable.ic_media_pause);
        MenuItemCompat.setShowAsAction(mPlayItem,
                MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
        setPlayMenu();

        mFilterItem = menu.add(
                0,
                MENU_FILTER,
                0,
                getResources().getString(R.string.filter_menu,
                        mPrefs.getFilter()));
        mFilterItem.setIcon(android.R.drawable.ic_menu_search);
        MenuItemCompat.setShowAsAction(mFilterItem,
                MenuItemCompat.SHOW_AS_ACTION_IF_ROOM
                        | MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
        setFilterMenu();

        MenuItem clearItem = menu.add(0, MENU_CLEAR, 0, R.string.clear_menu);
        clearItem.setIcon(android.R.drawable.ic_menu_close_clear_cancel);
        MenuItemCompat.setShowAsAction(clearItem,
                MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);

        MenuItem shareItem = menu.add(0, MENU_SHARE, 0, R.string.share_menu);
        shareItem.setIcon(android.R.drawable.ic_menu_share);
        MenuItemCompat.setShowAsAction(shareItem,
                MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);

        MenuItem saveItem = menu.add(0, MENU_SAVE, 0, R.string.save_menu);
        saveItem.setIcon(android.R.drawable.ic_menu_save);
        MenuItemCompat.setShowAsAction(saveItem,
                MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);

        return true;
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        return true;
    }

    public void setPlayMenu() {
        if (mPlayItem == null) {
            return;
        }
        if (mPlay) {
            mPlayItem.setTitle(R.string.pause_menu);
            mPlayItem.setIcon(android.R.drawable.ic_media_pause);
        } else {
            mPlayItem.setTitle(R.string.play_menu);
            mPlayItem.setIcon(android.R.drawable.ic_media_play);
        }
    }

    void setFilterMenu() {
        if (mFilterItem == null) {
            return;
        }
        int filterMenuId;
        String filter = mPrefs.getFilter();
        if (filter == null || filter.length() == 0) {
            filterMenuId = R.string.filter_menu_empty;
        } else {
            filterMenuId = R.string.filter_menu;
        }
        mFilterItem.setTitle(getResources().getString(filterMenuId, filter));
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case MENU_FILTER:
                showDialog(FILTER_DIALOG);
                return true;
            case MENU_SHARE:
                save();
                return true;
            case MENU_SAVE:
                save();
                return true;
            case MENU_PLAY:
                if (mPlay) {
                    pauseLog();
                } else {
                    jumpBottom();
                }
                return true;
            case MENU_CLEAR:
                clear();
                reset();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case PREFS_REQUEST:
                setKeepScreenOn();
                break;
        }
    }

    private void setKeepScreenOn() {
        if (mPrefs.isKeepScreenOn()) {
            getWindow()
                    .addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        } else {
            getWindow().clearFlags(
                    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        }

    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case MENU_JUMP_TOP:
                Toast.makeText(this, "Jumping to top of log ...",
                        Toast.LENGTH_SHORT).show();
                jumpTop();
                return true;
            case MENU_JUMP_BOTTOM:
                Toast.makeText(this, "Jumping to bottom of log ...",
                        Toast.LENGTH_SHORT).show();
                jumpBottom();
                return true;
            default:
                return super.onContextItemSelected(item);
        }
    }

    private void clear() {
        try {
            Runtime.getRuntime().exec(new String[] { "logcat", "-c" });
        } catch (IOException e) {
            Log.e("alogcat", "error clearing log", e);
        } finally {
        }
    }

    private String dump(boolean html) {
        StringBuilder sb = new StringBuilder();
        Level lastLevel = Level.V;

        // make copy to avoid CME
        List<LogEntry> entries = new ArrayList<LogEntry>(
                mLogEntryAdapter.getEntries());

        for (LogEntry le : entries) {
            if (!html) {
                sb.append(le.getText());
                sb.append('\n');
            } else {
                Level level = le.getLevel();
                if (level == null) {
                    level = lastLevel;
                } else {
                    lastLevel = level;
                }
                sb.append("<font color=\"");
                sb.append(level.getHexColor());
                sb.append("\" face=\"sans-serif\"><b>");
                sb.append(TextUtils.htmlEncode(le.getText()));
                sb.append("</b></font><br/>\n");
            }
        }

        return sb.toString();
    }

    private void share(File file) {
        final Uri uri = Uri.fromFile(file);

        EX.execute(new Runnable() {
            public void run() {
                boolean html = mPrefs.isShareHtml();
                String content = dump(html);

                Intent shareIntent = new Intent(
                        Intent.ACTION_SEND);

                // emailIntent.setType("message/rfc822");
                if (html) {
                    shareIntent.setType("text/html");
                } else {
                    shareIntent.setType("text/plain");
                }

                shareIntent.putExtra(Intent.EXTRA_SUBJECT,
                        "Android Log: " + LOG_DATE_FORMAT.format(new Date()));
                shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
                shareIntent.putExtra(Intent.EXTRA_SUBJECT, "* Android debug logs");
                shareIntent.putExtra(Intent.EXTRA_EMAIL, "android@leftshift.io");
                startActivity(Intent.createChooser(shareIntent,
                        "Share Android Log ..."));
            }
        });

    }


    private File save() {
        final File path = new File(Environment.getExternalStorageDirectory(),
                "alogcat");
        final File file = new File(path + File.separator + "alogcat."
                + LOG_FILE_FORMAT.format(new Date()) + ".txt");

        // String msg = "saving log to: " + file.toString();
        // Log.d("alogcat", msg);

        EX.execute(new Runnable() {
            public void run() {
                String content = dump(false);

                if (!path.exists()) {
                    path.mkdir();
                }

                BufferedWriter bw = null;
                try {
                    file.createNewFile();
                    bw = new BufferedWriter(new FileWriter(file), 1024);
                    bw.write(content);
                } catch (IOException e) {
                    Log.e("alogcat", "error saving log", e);
                } finally {
                    if (bw != null) {
                        try {
                            bw.close();
                        } catch (IOException e) {
                            Log.e("alogcat", "error closing log", e);
                        }
                    }
                }
                share(file);
            }
        });

        return file;
    }

    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case FILTER_DIALOG:
                mFilterDialog = new FilterDialog(this);
                return mFilterDialog;
        }
        return null;
    }

    private void pauseLog() {
        if (!mPlay) {
            return;
        }
        getWindow()
                .setTitle(getResources().getString(R.string.app_name_paused));
        if (mLogcat != null) {
            mLogcat.setPlay(false);
            mPlay = false;
        }
        setPlayMenu();
    }

    private void playLog() {
        if (mPlay) {
            return;
        }
        getWindow().setTitle(getResources().getString(R.string.app_name));
        if (mLogcat != null) {
            mLogcat.setPlay(true);
            mPlay = true;
        } else {
            reset();
        }
        setPlayMenu();
    }
}




Java Source Code List

io.leftshift.logcat.Buffer.java
io.leftshift.logcat.Buffer.java
io.leftshift.logcat.FilterDialog.java
io.leftshift.logcat.FilterDialog.java
io.leftshift.logcat.Format.java
io.leftshift.logcat.Format.java
io.leftshift.logcat.Level.java
io.leftshift.logcat.Level.java
io.leftshift.logcat.LogEntryAdapter.java
io.leftshift.logcat.LogEntryAdapter.java
io.leftshift.logcat.LogEntry.java
io.leftshift.logcat.LogEntry.java
io.leftshift.logcat.LogcatActivity.java
io.leftshift.logcat.LogcatActivity.java
io.leftshift.logcat.Logcat.java
io.leftshift.logcat.Logcat.java
io.leftshift.logcat.Prefs.java
io.leftshift.logcat.Prefs.java
io.leftshift.logcatsample.MainActivity.java