Android监听Log,悬浮显示

参考网址:http://blog.csdn.net/m_changgong/article/details/7661940

实现原理:1)执行logcat命令;

2)在service中把监听到的log内容通过广播发送出去;

3)Client端接收广播,获取log内容;

4)注意,添加读取log的权限

为什么要监听Log?

通过分析log可以监听系统安装、卸载软件等操作。

具体实现,见代码:

 

Runtime.getRuntime().exec("logcat -c").waitFor();
pro = Runtime.getRuntime().exec("logcat");

 

 

package com.taoshijie.debug.service;

import android.app.Service;

import android.content.Intent;

import android.graphics.PixelFormat;

import android.graphics.Rect;

import android.os.Handler;

import android.os.IBinder;

import android.os.Message;

import android.view.Gravity;

import android.view.LayoutInflater;

import android.view.MotionEvent;

import android.view.View;

import android.view.WindowManager;

import android.widget.ScrollView;

import android.widget.TextView;



import com.taoshijie.debug.R;



import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;





public class LogFloatService extends Service implements Runnable{

    private int statusBarHeight;// 状态栏高度

    private View view;// 透明窗体

    private TextView tv_show = null;

    private ScrollView scrollView = null;

    private boolean viewAdded = false;// 透明窗体是否已经显示

    private boolean viewHide = false; // 窗口隐藏

    private WindowManager windowManager;

    private WindowManager.LayoutParams layoutParams;

    private boolean isObserverLog; //是否监听log

    private Handler handler = new Handler(){

        @Override

        public void handleMessage(Message msg) {

            if(msg.what == 0){

                refresh((String)msg.obj, true);

            }

        }

    };



    @Override

    public IBinder onBind(Intent arg0) {

        return null;

    }



    @Override

    public void onCreate() {

        super.onCreate();

        createFloatView();

    }



    @Override

    public int onStartCommand(Intent intent, int flags, int startId) {

        viewHide = false;

        startLogObserver();

        return super.onStartCommand(intent, flags, startId);

    }



    @Override

    public void onDestroy() {

        super.onDestroy();

        stopLogObserver();



    }





    public void removeView() {

        if (viewAdded) {

            windowManager.removeView(view);

            viewAdded = false;

        }

    }



    private void createFloatView() {

        view = LayoutInflater.from(this).inflate(R.layout.view_float_log, null);

        tv_show = (TextView) view.findViewById(R.id.tv_show);

        scrollView = (ScrollView) view.findViewById(R.id.scroll_view);

        windowManager = (WindowManager) this.getSystemService(WINDOW_SERVICE);



        layoutParams = newWindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT,

                WindowManager.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,

                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);

        layoutParams.gravity = Gravity.LEFT | Gravity.TOP;





        view.setOnTouchListener(new View.OnTouchListener() {

            float[] temp = new float[] { 0f, 0f };

            public boolean onTouch(View v, MotionEvent event) {

                layoutParams.gravity = Gravity.LEFT | Gravity.TOP;

                int eventaction = event.getAction();

                switch (eventaction) {

                    case MotionEvent.ACTION_DOWN: // 按下事件,记录按下时手指在悬浮窗的XY坐标值

                        temp[0] = event.getX();

                        temp[1] = event.getY();

                        break;

                    case MotionEvent.ACTION_MOVE:

                        refreshView((int) (event.getRawX() - temp[0]),

                                (int) (event.getRawY() - temp[1]));

                        break;

                }

                return true;

            }

        });



        view.findViewById(R.id.btn_clear).setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                refresh(null, false);

            }

        });

        view.findViewById(R.id.btn_close).setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                refresh(null, false);

                stopSelf();

            }

        });

    }

    private void refreshView(int x, int y) {

// 状态栏高度不能立即取,不然得到的值是0

        if (statusBarHeight == 0) {

            View rootView = view.getRootView();

            Rect r = new Rect();

            rootView.getWindowVisibleDisplayFrame(r);

            statusBarHeight = r.top;

        }

        layoutParams.x = x;

// y轴减去状态栏的高度,因为状态栏不是用户可以绘制的区域,不然拖动的时候会有跳动

        layoutParams.y = y - statusBarHeight;// STATUS_HEIGHT;

        refresh(null, true);

    }

    private void refresh(String value, boolean isAppend) {

        if(!isObserverLog){

            return ;

        }

        if(isAppend){

            if(value != null){

                tv_show.append(value);

            }

        }else{

            tv_show.setText(value);

        }

        scrollView.post(new Runnable() {

            public void run() {

                scrollView.fullScroll(ScrollView.FOCUS_DOWN);

            }

        });

// 如果已经添加了就只更新view

        if (viewAdded) {

            windowManager.updateViewLayout(view, layoutParams);

        } else {

            windowManager.addView(view, layoutParams);

            viewAdded = true;

        }

    }

    public void startLogObserver() {

        if(!isObserverLog){

            isObserverLog = true;

            Thread mTherad = new Thread(this);

            mTherad.start();

        }

    }


    public void stopLogObserver() {

        isObserverLog = false;

        if(handler != null){

            handler.removeMessages(0);

        }

        removeView();

    }


    @Override

    public void run() {

        Process pro = null;

        try {

            Runtime.getRuntime().exec("logcat -c").waitFor();

            pro = Runtime.getRuntime().exec("logcat");

        } catch (InterruptedException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }

        if(pro == null){

            return ;

        }



        BufferedReader dis = new BufferedReader(newInputStreamReader(pro.getInputStream()));

        String line = null;

        while (isObserverLog) {

            try {

                while ((line = dis.readLine()) != null) {

                    if(handler != null){

                        Message msg=handler.obtainMessage();

                        msg.what = 0;

                        msg.obj = line+"\n";

                        handler.sendMessage(msg);

                    }

                    Thread.yield();

                }

            } catch (Exception e) {

                e.printStackTrace();

            }

        }

    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值