动态PieChart

该应用程序提供在线数据捕获和分析功能,支持开始、停止数据捕获,并实时展示数据分布的饼图。通过与服务器交互,实现数据捕获状态的监控及在线分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.ics.aop.activity;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.text.InputFilter.LengthFilter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ics.aop.R;
import com.ics.aop.adapter.ResultListAdapter;
import com.ics.aop.api.OnlineService;
import com.ics.aop.model.ResultInfo;
import com.ics.aop.model.TempResult;
import com.ics.aop.model.WarRoomBean;
import com.ics.aop.tool.HttpTool;
import com.ics.aop.tool.JsonHelper;
import com.ics.aop.tool.ProgressDialogUtils;
import com.ics.aop.view.PieChart;

public class OnlineActivity extends BaseActivity {

    private Context mContext;

    /**0:还没开始 1:点击了开始,等待服务器响应 2:正在运行**/
    private int isCapturing = 0;
    private Button btn_online_start;
    private Button btn_online_analysis;
    private Button btn_online_complete;
    private OnlineClickListener mClickListener;

    // 饼图相关开始
    private View mCurrentHeader;
    private ListView list_result;
    // 饼图相关结束

    private ExecutorService mExecutorService;
    private boolean drawingPieFlag = false;
    private OnlineService mOnlineService;
    private String mVpnUserId;
    private String mVpnTaskId;
    private ProgressDialogUtils mProgressDialogUtils;
    private boolean detectServerState;

    private NetReceiver mNetReceiver;

    /**
     * 监听网络变化
     * @author 詹子聪
     *
     */
    private class NetReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            // 监测到网络发生变化,退出当前界面
            if (!HttpTool.isNetworkConnected(OnlineActivity.this)) {
                Toast.makeText(OnlineActivity.this, "请检查网络", Toast.LENGTH_SHORT).show();
                OnlineActivity.this.finish();
            }
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_online);
        setTitle("在线功能");

        IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        mNetReceiver = new NetReceiver();
        registerReceiver(mNetReceiver, intentFilter);

        mOnlineService = new OnlineService();
        mVpnUserId = getIntent().getStringExtra("vpnUserId");
        initComponent();
    }

    @Override
    public void onBackPressed() {
        // TODO Auto-generated method stub
        //super.onBackPressed();
        if (isCapturing != 0) {
            exitPacketDialog();
        } else {
            super.onBackPressed();
        }
    }

    /**
     * 弹出对话框,询问用户是否真的退出
     * @param packetPath
     */
    private void exitPacketDialog() {
        final AlertDialog dialog = new AlertDialog.Builder(OnlineActivity.this).create();
        dialog.show();
        dialog.setContentView(R.layout.dialog_customed);

        TextView tv_dialog_title = (TextView) dialog.findViewById(R.id.tv_dialog_title);
        TextView tv_dialog_desc = (TextView) dialog.findViewById(R.id.tv_dialog_desc);
        tv_dialog_title.setText("温馨提示");
        tv_dialog_desc.setText("您决定退出在线分析吗?");
        TextView tv_confirm = (TextView) dialog.findViewById(R.id.tv_confirm);
        TextView tv_cancel = (TextView) dialog.findViewById(R.id.tv_cancel);

        tv_confirm.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                dialog.cancel();
                // 发送结束指令给服务器
                new StopOnlineTask(mVpnTaskId, "3").execute();
                finish();
            }
        });

        tv_cancel.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                dialog.cancel();
            }
        });
    }

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        drawingPieFlag = false;
        detectServerState = false;
        mExecutorService.shutdown();

        if (mNetReceiver != null) {
            unregisterReceiver(mNetReceiver);
        }
    }

    /**
     * 初始化控件
     */
    private void initComponent() {
        mContext = OnlineActivity.this;

        btn_online_start = (Button) findViewById(R.id.btn_online_start);
        btn_online_analysis = (Button) findViewById(R.id.btn_online_analysis);
        btn_online_complete = (Button) findViewById(R.id.btn_online_complete);
        list_result = (ListView) findViewById(R.id.result_list);

        mClickListener = new OnlineClickListener();
        btn_online_start.setOnClickListener(mClickListener);
        btn_online_analysis.setOnClickListener(mClickListener);
        btn_online_complete.setOnClickListener(mClickListener);

        mExecutorService = Executors.newFixedThreadPool(4);

//      PreferencesUtils mPreferencesUtils = PreferencesUtils.getInstance(this);
//      String vpnAccount = mPreferencesUtils.getString("vpnAccount");
//      homeUrl = String.format(ApiUrl.API_WEBIE, vpnAccount, vpnAccount);

        mProgressDialogUtils = new ProgressDialogUtils(this);

        list_result.setOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                // TODO Auto-generated method stub

            }
        });
    }


    Handler mHandler = new Handler(new Handler.Callback() {

        @Override
        public boolean handleMessage(Message msg) {
            // TODO Auto-generated method stub
            switch (msg.what) {
            case 10:
                // 监听到服务器状态
                String taskStatus = (String) msg.obj;
                if (!TextUtils.isEmpty(taskStatus)) {
                    if (TextUtils.equals("2", taskStatus)) {
                        mProgressDialogUtils.hide();
                        // 服务器成功开始,开始绘制饼图,显示停止按钮
                        if (!drawingPieFlag) {
                            drawingPieFlag = true;
                            drawPieChart();
                            isCapturing = 2;
                            btn_online_start.setText("停止");
                            btn_online_start.setEnabled(true);
                            Toast.makeText(mContext, "现在可以去其他应用浏览数据了", Toast.LENGTH_SHORT).show();
                        }
                    } else if (TextUtils.equals("5", taskStatus)) {
                        // 已经绘制了最后一个饼图,此时已经停止绘制饼图,显示开始按钮
                        mProgressDialogUtils.hide();
                        drawingPieFlag = false;
                        isCapturing =0;
                        btn_online_start.setText("开始");
                        btn_online_start.setEnabled(true);

                        // 发送指令给服务器将状态改为10
                        new StopOnlineTask(mVpnTaskId, "10").execute();
                    } else if (TextUtils.equals("12", taskStatus)) {
                        // 双重保障,怕被忽略掉了
                        drawingPieFlag = false;
                        isCapturing =0;
                        btn_online_start.setText("开始");
                        btn_online_start.setEnabled(true);

                        // 停止去服务器查询状态,显示竞分按钮
                        detectServerState = false;
                        btn_online_analysis.setEnabled(true);
                        btn_online_complete.setEnabled(true);
                    } else if (TextUtils.equals("13", taskStatus)) {
                        // 竞分失败
                        btn_online_complete.setEnabled(false);
                        Toast.makeText(mContext, "竞分失败", Toast.LENGTH_SHORT).show();
                    }
                }
                break;

            case 5:
                String pieData = (String) msg.obj;
                try {
                    resolvePieData(pieData);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                break;
            default:
                break;
            }
            return true;
        }
    });

    /**
     * 服务器成功开始,开始绘制饼图,显示停止按钮
     */
    private void drawPieChart() {
        mExecutorService.execute(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                while (drawingPieFlag) {
                    // 不断从服务器获取饼图数据
                    String pieData = mOnlineService.getPieData(mVpnTaskId);
                    if (!TextUtils.isEmpty(pieData) && !TextUtils.equals("null", pieData)) {
                        // 解析获取的饼图数据
                        try {
                            // 在主线程绘制饼图
                            Message msg = Message.obtain();
                            msg.what = 5;
                            msg.obj = pieData;
                            mHandler.sendMessage(msg);
                        } catch (Exception e) {
                            // TODO: handle exception
                        }
                    }
                    try {
                        Thread.sleep(7000);
                    } catch (Exception e) {
                        // TODO: handle exception
                        e.printStackTrace();
                    }
                } 
            }
        });
    }

    /**
     * 解析饼图数据
     * @param jsonString
     * @throws IOException 
     * @throws JsonProcessingException 
     */
    private void resolvePieData(String jsonString) throws Exception {
        String resultJson = null;
        ObjectMapper mapper = new ObjectMapper();
        JsonNode jsonNode = null;
        jsonNode = mapper.readTree(jsonString);
        resultJson = jsonNode.get("result").toString();

        // 设置其他列表数据
        List<ResultInfo> resultList = new ArrayList<>();
        ResultListAdapter adapter = new ResultListAdapter(this, resultList, 0.05f);

        if (!TextUtils.isEmpty(resultJson)) {

            resultList.clear();
            List<TempResult> tempResults = JsonHelper.convertList(resultJson, TempResult.class);

            // 设置每个扇形区域的颜色
            String colors[] = getResources().getStringArray(R.array.pie_colors);
            int colorLength = colors.length;
            for (int i = 0, length = tempResults.size(); i < length; i++) {
                TempResult tempResult = tempResults.get(i);
                ResultInfo resultInfo = new ResultInfo();
                resultInfo.setSubprot_name(tempResult.getSubprot_name());
                resultInfo.setTraffic_amount(tempResult.getTraffic_amount());
                resultInfo.setTraffic_percentage(tempResult.getTraffic_percentage());
                if (i >= colorLength) {
                    resultInfo.setColor(colors[i % colorLength]);
                } else {
                    resultInfo.setColor(colors[i]);
                }
                resultList.add(resultInfo);
            }

            for (ResultInfo resultInfo : resultList) {
                resultInfo.setTraffic_percentage(resultInfo.getTraffic_percentage() / 100.0f);
            }

            // 设置饼状图数据
            String name[] = new String[resultList.size()];
            float rate[] = new float[resultList.size()];
            for (int i = 0; i < resultList.size(); i++) {
                name[i] = resultList.get(i).getSubprot_name();
                rate[i] = resultList.get(i).getTraffic_percentage();
            }

            list_result.removeHeaderView(mCurrentHeader);
            View view = LayoutInflater.from(mContext).inflate(R.layout.header_online_result, null);
            PieChart pie = (PieChart) view.findViewById(R.id.result_pie);
            pie.init(name, rate, 0.05f);
            mCurrentHeader = view;
            list_result.addHeaderView(view);

            list_result.setAdapter(adapter);
            adapter.notifyDataSetChanged();

            // 画完一个图之后再去请求数据来画
            //drawPieChart();
        }
    }

    /**
     * 点击开始之后发送请求通知服务器开始
     * @author 詹子聪
     *
     */
    private class StartOnlineTask extends AsyncTask<Void, Void, String> {

        private String taskId;
        private String vpnUserId;

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();

            if (mProgressDialogUtils == null) {
                mProgressDialogUtils = new ProgressDialogUtils(OnlineActivity.this);
            }

            mProgressDialogUtils.show();
        }

        public StartOnlineTask(String taskId, String vpnUserId) {
            // TODO Auto-generated constructor stub
            this.taskId = taskId;
            this.vpnUserId = vpnUserId;
        }

        @Override
        protected String doInBackground(Void... params) {
            // TODO Auto-generated method stub
            return mOnlineService.startForTaskId(taskId, vpnUserId);
        }

        @Override
        protected void onPostExecute(String result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            if (!TextUtils.isEmpty(result)) {
                ObjectMapper mapper = new ObjectMapper();
                try {
                    JsonNode jsonNode = mapper.readTree(result);
                    if (jsonNode != null) {
                        // 服务器响应点击开始的动作,返回全局VpnTaskId
                        mVpnTaskId = jsonNode.get("taskId").toString();
                        detectServerState();
                    } else {
                        Toast.makeText(mContext, "服务器异常", Toast.LENGTH_SHORT).show();
                    }
                } catch (JsonProcessingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } else {
                // 点击了开始,服务器没响应
                mProgressDialogUtils.hide();
                Toast.makeText(OnlineActivity.this, "服务器没响应", Toast.LENGTH_SHORT).show();
                btn_online_start.setEnabled(true);
            }
        }
    }

    /**
     * 开始侦查服务器状态
     */
    private void detectServerState() {
        detectServerState = true;
        // 同时开启一个线程,每隔三秒去获取服务器的响应状态
        mExecutorService.execute(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                while (detectServerState) {
                    if (!TextUtils.isEmpty(mVpnTaskId)) {
                        Message msg = Message.obtain();
                        String json = mOnlineService.detectServerState(mVpnTaskId);
                        if (!TextUtils.isEmpty(json)) {
                            String taskStatus = null; 
                            ObjectMapper mapper = new ObjectMapper();
                            JsonNode node;
                            try {
                                node = mapper.readTree(json);
                                if (node != null) {
                                    taskStatus = node.get("taskStatus").toString();
                                }
                            } catch (JsonProcessingException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }

                            if (!TextUtils.isEmpty(taskStatus)) {
                                msg.obj = taskStatus;
                                msg.what = 10;
                                mHandler.sendMessage(msg);
                            }
                        }
                    }

                    try {
                        Thread.sleep(7000);
                    } catch (Exception e) {
                        // TODO: handle exception
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    /**
     * 停止在线抓包
     * @author 詹子聪
     *
     */
    private class StopOnlineTask extends AsyncTask<Void, Void, String> {

        private String vpnTaskId;
        private String taskStatus;

        public StopOnlineTask(String vpnTaskId, String taskStatus) {
            super();
            this.vpnTaskId = vpnTaskId;
            this.taskStatus = taskStatus;
        }

        @Override
        protected String doInBackground(Void... params) {
            // TODO Auto-generated method stub
            return mOnlineService.stopOnlineTask(vpnTaskId, taskStatus);
        }

        @Override
        protected void onPostExecute(String result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);

            if (result == null) {
                // 服务器没有接收到指令
                mProgressDialogUtils.hide();
                isCapturing = 2;
                btn_online_start.setEnabled(true);
            }
        }
    }

    /**
     * 监听点击
     * @author 詹子聪
     *
     */
    private class OnlineClickListener implements OnClickListener {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            switch (v.getId()) {
            case R.id.btn_online_start:
                if (isCapturing == 2) {
                    // 模拟点击了结束按钮,等待服务器那边结束,此时结束按钮不可用
                    btn_online_start.setEnabled(false);
                    mProgressDialogUtils.show();
                    isCapturing = 1;

                    // 发送结束指令给服务器
                    new StopOnlineTask(mVpnTaskId, "3").execute();
                } else if (isCapturing == 0){
                    // 点击了开始按钮,等待服务器那边开始,此时开始按钮不可用
                    mVpnTaskId = null;
                    isCapturing = 1;
                    btn_online_start.setEnabled(false);
                    btn_online_analysis.setEnabled(false);
                    btn_online_complete.setEnabled(false);

                    new StartOnlineTask("1", mVpnUserId).execute();
                }

                break;
            case R.id.btn_online_analysis:
                Toast.makeText(mContext, "开始分析", Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_online_complete:
                Toast.makeText(mContext, "在线竟分", Toast.LENGTH_SHORT).show();
                new WarRoomTask().execute();
                break;

            default:
                break;
            }
        }
    }

    private class WarRoomTask extends AsyncTask<Void, Void, String> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            mProgressDialogUtils.show();
        }

        @Override
        protected String doInBackground(Void... params) {
            return mOnlineService.WarRoomTask(mVpnTaskId);
        }

        @Override
        protected void onPostExecute(String result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);

            mProgressDialogUtils.hide();
            if (!TextUtils.isEmpty(result)) {
                WarRoomBean warRoomData = JsonHelper.convert(result, WarRoomBean.class);
                if (warRoomData != null) {
                    Intent warRoomIntent = new Intent(OnlineActivity.this,WarRoomActivity.class);
                    warRoomIntent.putExtra("warRoomData", warRoomData);
                    startActivity(warRoomIntent);
                }
            } else {
                Toast.makeText(mContext, "获取竞分失败", Toast.LENGTH_SHORT).show();
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ithouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值