parent
9db2a305d9
commit
4c9c9b4d06
@ -0,0 +1,191 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
tools:context=".LogActivity">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/logs"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_margin="4dp"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:background="@drawable/textview_border"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:lineSpacingMultiplier="1.25"
|
||||||
|
android:scrollbars="vertical"
|
||||||
|
android:singleLine="false"
|
||||||
|
android:text="Logs"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textIsSelectable="true"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
Reference in New Issue