You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
191 lines
6.0 KiB
Java
191 lines
6.0 KiB
Java
5 months ago
|
package com.xypower.mpapp;
|
||
|
|
||
|
import androidx.annotation.NonNull;
|
||
|
import androidx.appcompat.app.AppCompatActivity;
|
||
|
|
||
|
import android.os.Bundle;
|
||
|
import android.os.FileObserver;
|
||
|
import android.os.Handler;
|
||
|
import android.os.Looper;
|
||
|
import android.os.Message;
|
||
|
import android.os.Messenger;
|
||
|
import android.text.method.ScrollingMovementMethod;
|
||
|
import android.util.Log;
|
||
|
import android.view.MenuItem;
|
||
|
|
||
|
import com.xypower.common.MicroPhotoContext;
|
||
|
import com.xypower.mpapp.databinding.ActivityLogBinding;
|
||
|
import com.xypower.mpapp.utils.RandomReader;
|
||
|
|
||
|
import java.io.File;
|
||
|
|
||
|
public class LogActivity extends AppCompatActivity {
|
||
|
|
||
|
public static final String TAG = "MPLOG";
|
||
|
|
||
|
public static final int MSG_WHAT_LOG_OBSERVER = MicroPhotoService.MSG_WHAT_MAX + 10;
|
||
|
|
||
|
public static final int MAX_LOG_LINES = 480;
|
||
|
public static final int MIN_LOG_LINES = 120;
|
||
|
|
||
|
private ActivityLogBinding binding;
|
||
|
|
||
|
private Handler mHandler = null;
|
||
|
|
||
|
private LogFileObserver mLogFileObserver = null;
|
||
|
|
||
|
@Override
|
||
|
protected void onCreate(Bundle savedInstanceState) {
|
||
|
super.onCreate(savedInstanceState);
|
||
|
|
||
|
binding = ActivityLogBinding.inflate(getLayoutInflater());
|
||
|
setContentView(binding.getRoot());
|
||
|
|
||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||
|
|
||
|
binding.logs.setText("");
|
||
|
binding.logs.setMovementMethod(ScrollingMovementMethod.getInstance());
|
||
|
binding.logs.setScrollbarFadingEnabled(false);
|
||
|
|
||
|
mHandler = new Handler(Looper.myLooper()) {
|
||
|
@Override
|
||
|
public void handleMessage(@NonNull Message msg) {
|
||
|
switch (msg.what) {
|
||
|
case MSG_WHAT_LOG_OBSERVER:
|
||
|
{
|
||
|
byte[] bytes = (byte[])msg.obj;
|
||
|
int bytesRead = msg.arg1;
|
||
|
String log = null;
|
||
|
try {
|
||
|
log = new String(bytes, 0, bytesRead, "UTF-8");
|
||
|
} catch (Exception e) {
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
if (log != null) {
|
||
|
binding.logs.append(log);
|
||
|
int offset = binding.logs.getLineCount() * binding.logs.getLineHeight();
|
||
|
if (offset > binding.logs.getHeight()) {
|
||
|
binding.logs.scrollTo(0, offset - binding.logs.getHeight() + binding.logs.getLineHeight());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
@Override
|
||
|
protected void onResume() {
|
||
|
// call the superclass method first
|
||
|
super.onResume();
|
||
|
|
||
|
try {
|
||
|
String logFilePath = MicroPhotoContext.buildAppDir(this.getApplicationContext());
|
||
|
logFilePath += "logs";
|
||
|
File file = new File(logFilePath);
|
||
|
if (!file.exists()) {
|
||
|
file.mkdirs();
|
||
|
}
|
||
|
logFilePath += "/log.txt";
|
||
|
file = new File(logFilePath);
|
||
|
if (!file.exists()) {
|
||
|
file.createNewFile();
|
||
|
}
|
||
|
|
||
|
mLogFileObserver = new LogFileObserver(logFilePath);
|
||
|
mLogFileObserver.startWatching();
|
||
|
Log.i(TAG, "Log Observer Started");
|
||
|
|
||
|
int lines = binding.logs.getLineCount();
|
||
|
if (lines > MAX_LOG_LINES) {
|
||
|
int excessLineNumber = lines - MIN_LOG_LINES;
|
||
|
int eolIndex = -1;
|
||
|
CharSequence charSequence = binding.logs.getText();
|
||
|
for (int i = 0; i < excessLineNumber; i++) {
|
||
|
do {
|
||
|
eolIndex++;
|
||
|
} while (eolIndex < charSequence.length() && charSequence.charAt(eolIndex) != '\n');
|
||
|
}
|
||
|
if (eolIndex < charSequence.length()) {
|
||
|
binding.logs.getEditableText().delete(0, eolIndex + 1);
|
||
|
}
|
||
|
}
|
||
|
} catch (Exception e) {
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected void onPause() {
|
||
|
// call the superclass method first
|
||
|
super.onPause();
|
||
|
|
||
|
try {
|
||
|
if (mLogFileObserver != null) {
|
||
|
mLogFileObserver.stopWatching();
|
||
|
mLogFileObserver = null;
|
||
|
Log.i(TAG, "Log Observer Stopped");
|
||
|
}
|
||
|
} catch (Exception e) {
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||
|
switch (item.getItemId()) {
|
||
|
case android.R.id.home:
|
||
|
// todo: goto back activity from here
|
||
|
|
||
|
finish();
|
||
|
return true;
|
||
|
|
||
|
default:
|
||
|
return super.onOptionsItemSelected(item);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
private class LogFileObserver extends FileObserver {
|
||
|
|
||
|
private long mOffset = 0;
|
||
|
private String mPath = null;
|
||
|
public LogFileObserver(String path) {
|
||
|
super(path, FileObserver.MODIFY | FileObserver.CREATE);
|
||
|
|
||
|
mPath = path;
|
||
|
File file = new File(path);
|
||
|
if (file.exists()) {
|
||
|
mOffset = file.length();
|
||
|
}
|
||
|
}
|
||
|
@Override
|
||
|
public void onEvent(int event, String s) {
|
||
|
int e = event & FileObserver.ALL_EVENTS;
|
||
|
|
||
|
if (e == FileObserver.MODIFY) {
|
||
|
File file = new File(mPath);
|
||
|
long newOffset = file.length();
|
||
|
if (newOffset > mOffset) {
|
||
|
RandomReader reader = new RandomReader(mPath, mOffset);
|
||
|
|
||
|
byte[] bytes = new byte[(int)(newOffset - mOffset)];
|
||
|
int bytesRead = reader.read(bytes);
|
||
|
mOffset += bytesRead;
|
||
|
|
||
|
Message msg = Message.obtain();
|
||
|
msg.what = MSG_WHAT_LOG_OBSERVER;
|
||
|
msg.obj = bytes;
|
||
|
msg.arg1 = bytesRead;
|
||
|
mHandler.sendMessage(msg);
|
||
|
}
|
||
|
} else if (e == FileObserver.CREATE) {
|
||
|
mOffset = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|