package com.eolwral.osmonitor.ui; import java.io.File; import java.io.FileWriter; import java.nio.ByteBuffer; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Locale; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.content.Context; import android.content.DialogInterface; import android.content.res.Resources; import android.graphics.Color; import android.os.Bundle; import android.os.Environment; import android.support.v4.app.DialogFragment; import android.text.format.DateFormat; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; import com.eolwral.osmonitor.R; import com.eolwral.osmonitor.core.logPriority; import com.eolwral.osmonitor.core.logcatInfo; import com.eolwral.osmonitor.core.logcatInfoList; import com.eolwral.osmonitor.ipc.IpcService; import com.eolwral.osmonitor.ipc.IpcService.ipcClientListener; import com.eolwral.osmonitor.ipc.ipcCategory; import com.eolwral.osmonitor.ipc.ipcData; import com.eolwral.osmonitor.ipc.ipcMessage; import com.eolwral.osmonitor.settings.Settings; import com.eolwral.osmonitor.util.UserInterfaceUtil; public class ProcessLogViewFragment extends DialogFragment implements ipcClientListener { // ipc client private static IpcService ipcService = IpcService.getInstance(); // set pid public final static String TARGETPID = "TargetPID"; public final static String TARGETNAME = "TargetName"; private int targetPID = 0; private String targetName = ""; // data private ArrayList<logcatInfo> viewLogcatData = new ArrayList<logcatInfo>(); private byte logType = ipcCategory.LOGCAT_MAIN_R; private MessageListAdapter messageList = null; private Settings settings = null; private TextView messageCount = null; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // settings settings = Settings.getInstance(getActivity().getApplicationContext()); // set list messageList = new MessageListAdapter(getActivity().getApplicationContext()); // get pid targetPID = getArguments().getInt(TARGETPID); targetName = getArguments().getString(TARGETNAME); } public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.ui_message_fragment, container, false); // set count messageCount = ((TextView) v.findViewById(R.id.id_message_count)); // set list ListView list = (ListView) v.findViewById(android.R.id.list); list.setAdapter(messageList); // set title getDialog().setTitle(targetName); Button exportButton = (Button) v.findViewById(R.id.id_message_exportbtn); exportButton.setVisibility(View.VISIBLE); exportButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { final Resources exportRes = getActivity().getResources(); final Calendar calendar = Calendar.getInstance(); final SimpleDateFormat formatter = new SimpleDateFormat( "yyyy-MM-dd-hh.mm.ss", Locale.getDefault()); Builder exportDialog = new AlertDialog.Builder(getActivity()); View exportView = LayoutInflater.from(getActivity()).inflate( R.layout.ui_message_export, null); TextView exportFile = (TextView) exportView .findViewById(R.id.id_export_filename); exportFile.setText("Log-" + formatter.format(calendar.getTime())); exportDialog.setView(exportView); exportDialog.setTitle(exportRes.getText(R.string.ui_menu_logexport)); exportDialog.setNegativeButton( exportRes.getText(R.string.ui_text_cancel), null); exportDialog.setPositiveButton( exportRes.getText(R.string.ui_text_okay), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { String FileName = ((EditText) ((AlertDialog) dialog) .findViewById(R.id.id_export_filename)).getText() .toString(); exportLog(FileName); } }); exportDialog.create().show(); } }); return v; } private void exportLog(String fileName) { if (fileName.trim().equals("")) return; if (!fileName.contains(".csv")) fileName += ".csv"; try { File logFile = new File(Environment.getExternalStorageDirectory() .getPath() + "/" + fileName); if (logFile.exists()) { new AlertDialog.Builder(getActivity()) .setTitle(R.string.ui_menu_logexport) .setMessage(R.string.ui_text_fileexist) .setPositiveButton(R.string.ui_text_okay, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }).create().show(); return; } logFile.createNewFile(); int LogCount = viewLogcatData.size(); FileWriter logWriter = new FileWriter(logFile); final Calendar calendar = Calendar.getInstance(); for (int index = 0; index < LogCount; index++) { StringBuilder logLine = new StringBuilder(); calendar.setTimeInMillis(viewLogcatData.get(index).seconds() * 1000); logLine.append(DateFormat.format("yyyy-MM-dd hh:mm:ss", calendar.getTime()) + ","); switch (viewLogcatData.get(index).priority()) { case logPriority.SILENT: logLine.append("SILENT,"); break; case logPriority.UNKNOWN: logLine.append("UNKNOWN,"); break; case logPriority.DEFAULT: logLine.append("DEFAULT,"); break; case logPriority.VERBOSE: logLine.append("VERBOSE,"); break; case logPriority.WARN: logLine.append("WARNING,"); break; case logPriority.INFO: logLine.append("INFORMATION,"); break; case logPriority.FATAL: logLine.append("FATAL,"); break; case logPriority.ERROR: logLine.append("ERROR,"); break; case logPriority.DEBUG: logLine.append("DEBUG,"); break; } logLine.append(viewLogcatData.get(index).tag() + ","); logLine.append(viewLogcatData.get(index).message() + "\n"); logWriter.write(logLine.toString()); } logWriter.close(); } catch (Exception e) { new AlertDialog.Builder(getActivity()) .setTitle(R.string.ui_menu_logexport) .setMessage(e.getMessage()) .setPositiveButton(R.string.ui_text_okay, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }).create().show(); return; } new AlertDialog.Builder(getActivity()) .setTitle(R.string.ui_menu_logexport) .setMessage(R.string.ui_text_exportdone) .setPositiveButton(R.string.ui_text_okay, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }).create().show(); return; } @Override public void onStart() { super.onStart(); ipcService.removeRequest(this); byte newCommand[] = { logType }; ipcService.addRequest(newCommand, 0, this); } @Override public void onStop() { super.onStop(); ipcService.removeRequest(this); } @Override public void onRecvData(byte [] result) { if (result == null) { byte newCommand[] = new byte[1]; newCommand[0] = logType; ipcService.addRequest(newCommand, settings.getInterval(), this); return; } // clean up viewLogcatData.clear(); // convert data ipcMessage ipcMessageResult = ipcMessage.getRootAsipcMessage(ByteBuffer.wrap(result)); for (int index = 0; index < ipcMessageResult.dataLength(); index++) { try { ipcData rawData = ipcMessageResult.data(index); logcatInfoList list = logcatInfoList.getRootAslogcatInfoList(rawData.payloadAsByteBuffer().asReadOnlyBuffer()); for (int count = 0; count < list.listLength(); count++) { logcatInfo lgInfo = list.list(count); // filter if (lgInfo.pid() != this.targetPID) continue; viewLogcatData.add(lgInfo); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } // refresh messageList.refresh(); // send command again byte newCommand[] = new byte[1]; newCommand[0] = logType; ipcService.addRequest(newCommand, settings.getInterval(), this); } /** * implement viewholder class for connection list */ private class ViewHolder { // main information TextView time; TextView tag; TextView level; TextView msg; } private class MessageListAdapter extends BaseAdapter { private LayoutInflater itemInflater = null; private ViewHolder holder = null; public MessageListAdapter(Context mContext) { itemInflater = (LayoutInflater) mContext .getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { return viewLogcatData.size(); } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { View sv = null; // prepare view if (convertView == null) { sv = (View) itemInflater.inflate(R.layout.ui_message_item, parent, false); holder = new ViewHolder(); holder.time = ((TextView) sv.findViewById(R.id.id_message_time)); holder.level = ((TextView) sv.findViewById(R.id.id_message_level)); holder.tag = ((TextView) sv.findViewById(R.id.id_message_tag)); holder.msg = ((TextView) sv.findViewById(R.id.id_message_text)); sv.setTag(holder); } else { sv = (View) convertView; holder = (ViewHolder) sv.getTag(); } // draw current color for each item if (position % 2 == 0) sv.setBackgroundColor(getResources().getColor(R.color.dkgrey_osmonitor)); else sv.setBackgroundColor(getResources().getColor(R.color.black_osmonitor)); // get data logcatInfo item = viewLogcatData.get(position); final Calendar calendar = Calendar.getInstance(); final java.text.DateFormat convertTool = java.text.DateFormat .getDateTimeInstance(); calendar.setTimeInMillis(item.seconds() * 1000); holder.time.setText(convertTool.format(calendar.getTime())); holder.tag.setText(item.tag()); holder.msg.setText(item.message().toString()); holder.level.setTextColor(Color.BLACK); holder.level.setBackgroundColor(UserInterfaceUtil.getLogcatColor(item.priority())); holder.level.setText(UserInterfaceUtil.getLogcatTag(item.priority())); // avoid to trigger errors when refreshing sv.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return true; } }); return sv; } public void refresh() { messageCount.setText(String.format("%,d", viewLogcatData.size())); notifyDataSetChanged(); } } }