android 悬浮框service 三

主要用到的技术Service+WindowManager+LayoutParams的type

1.使用service来弹出此悬浮框,从而保证能长期存在。  

2.使用window manager来控制悬浮框漂浮在所有view的上层。参数具体设置见代码。  

3.使用TrafficStats来检测网络流量状态。  

4.使用ConnectivityManager 来对Wifi,3G等网络状态进行检测。  

5.使用handler在线程中异步刷新主界面。  

package com.wenix;  

import android.app.Service;  
import android.content.Intent;  
import android.graphics.PixelFormat;  
import android.net.TrafficStats;  
import android.os.Handler;  
import android.os.IBinder;  
import android.os.Message;  
import android.util.Log;  
import android.view.Gravity;  
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.WindowManager;  
import android.widget.ImageView;  
import android.widget.TextView;  

import com.wenix.util.NetworkUtil;  

public class TopFloatService extends Service {  
    protected static final String TAG = "TopFloatService";  
    protected static final int WHAT = 0x123456;  
    WindowManager wm = null;  
    WindowManager.LayoutParams wmParams = null;  
    View view;  
    ImageView downloadIv;  
    TextView flowTxt;  

    private float mTouchStartX;  
    private float mTouchStartY;  
    private float x;  
    private float y;  

    private String flowInfoStr;  
    private Handler mHandler;  

    @Override  
    public void onCreate() {  
        super.onCreate();  
        // 获取WindowManager  
        wm = (WindowManager) getApplicationContext().getSystemService("window");  
        // 设置LayoutParams(全局变量)相关参数  
        wmParams = new WindowManager.LayoutParams();  

        // setForeground(true);  
        view = LayoutInflater.from(this).inflate(R.layout.floating, null);  
        downloadIv = (ImageView) view.findViewById(R.id.downloadingImgBtn);  
        flowTxt = (TextView) view.findViewById(R.id.downloadingInfoTxt);  

        new Thread(new Runnable() {  

            @Override  
            public void run() {  
                // TODO Auto-generated method stub  
                while (!Thread.interrupted()) {  
                    if (NetworkUtil.isNetworkAvailable(getApplicationContext())) {  
                        float reciveBytes = TrafficStats.getMobileRxBytes() / 1024.0f;  
                        float sendBytes = TrafficStats.getMobileTxBytes() / 1024.0f;  
                        String flowInfo = getApplicationContext().getResources().getString(R.string.networkflow);  
                        flowInfoStr = String.format(flowInfo, reciveBytes, sendBytes);  
                        Log.i(TAG, "reciveBytes=" + reciveBytes + ",sendBytes=" + sendBytes);  
                        Message msg = new Message();  
                        msg.what = WHAT;  
                        mHandler.sendMessage(msg);  
                    }  
                }  
            }  
        }).start();  

        mHandler = new Handler() {  

            @Override  
            public void handleMessage(Message msg) {  
                // TODO Auto-generated method stub  
                super.handleMessage(msg);  
                if (WHAT == msg.what) {  
                    flowTxt.setText(flowInfoStr);  
                }  
            }  

        };  
    }  

    @Override  
    public void onStart(Intent intent, int startId) {  
        // TODO Auto-generated method stub  
        super.onStart(intent, startId);  
        createView();  
    }  

    private void createView() {  
        wmParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;  
        // 该类型提供与用户交互,置于所有应用程序上方,但是在状态栏后面  
        // TYPE_TOAST TYPE_SYSTEM_OVERLAY 在其他应用上层 在通知栏下层 位置不能动鸟  
        // TYPE_PHONE 在其他应用上层 在通知栏下层  
        // TYPE_PRIORITY_PHONE TYPE_SYSTEM_ALERT 在其他应用上层 在通知栏上层 没试出来区别是啥  
        // TYPE_SYSTEM_ERROR 最顶层(通过对比360和天天动听歌词得出)  
        // 用别的TYPE还出报错... 也希望大家补充一下  

        wmParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;// 不接受任何按键事件  
        wmParams.gravity = Gravity.LEFT | Gravity.TOP; // 调整悬浮窗口至左上角  
        // 以屏幕左上角为原点,设置x、y初始值  
        wmParams.x = 0;  
        wmParams.y = 0;  
        // 设置悬浮窗口长宽数据  
        wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;  
        wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;  
        wmParams.format = PixelFormat.RGBA_8888;  

        wm.addView(view, wmParams);  

        view.setOnTouchListener(new OnTouchListener() {  
            public boolean onTouch(View v, MotionEvent event) {  
                // 获取相对屏幕的坐标,即以屏幕左上角为原点  
                x = event.getRawX();  
                // 25是系统状态栏的高度,也可以通过方法得到准确的值,自己微调就是了  
                y = event.getRawY();  
                switch (event.getAction()) {  
                case MotionEvent.ACTION_DOWN:  
                    // 获取相对View的坐标,即以此View左上角为原点  
                    mTouchStartX = event.getX();  
                    mTouchStartY = event.getY() + view.getHeight() / 2;  
                    return false;  
                case MotionEvent.ACTION_MOVE:  
                    updateViewPosition();  
                    break;  
                case MotionEvent.ACTION_UP:  
                    updateViewPosition();  
                    mTouchStartX = mTouchStartY = 0;  
                    return false;  
                }  
                return true;  
            }  

        });  

        view.setOnClickListener(new OnClickListener() {  

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

    }  

    private void updateViewPosition() {  
        // 更新浮动窗口位置参数  
        wmParams.x = (int) (x - mTouchStartX);  
        wmParams.y = (int) (y - mTouchStartY);  
        wm.updateViewLayout(view, wmParams);  
    }  

    @Override  
    public IBinder onBind(Intent intent) {  
        return null;  
    }  
}  

工具类:  

[java] view plaincopyprint?package com.wenix.util;    
    
import android.content.Context;    
import android.net.ConnectivityManager;    
import android.net.NetworkInfo;    
import android.util.Log;    
    
public class NetworkUtil {    
    private static final String TAG = "NetworkUtil";    
    
    public static boolean isNetworkAvailable(Context context) {    
        ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);   
        if (connectivity == null) {    
            Log.i("NetWorkState", "Unavailabel");    
        } else {    
            NetworkInfo[] info = connectivity.getAllNetworkInfo();    
            if (info != null) {    
                for (int i = 0; i < info.length; i++) {    
                    if (info[i].getState() == NetworkInfo.State.CONNECTED) {    
                        Log.i(TAG, info[i].getTypeName() + " Availabel");    
                    }    
                }    
            }    
            return true;    
        }    
        return false;    
    }    
}    

package com.wenix.util;  

import android.content.Context;  
import android.net.ConnectivityManager;  
import android.net.NetworkInfo;  
import android.util.Log;  

public class NetworkUtil {  
    private static final String TAG = "NetworkUtil";  

    public static boolean isNetworkAvailable(Context context) {  
        ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
        if (connectivity == null) {  
            Log.i("NetWorkState", "Unavailabel");  
        } else {  
            NetworkInfo[] info = connectivity.getAllNetworkInfo();  
            if (info != null) {  
                for (int i = 0; i < info.length; i++) {  
                    if (info[i].getState() == NetworkInfo.State.CONNECTED) {  
                        Log.i(TAG, info[i].getTypeName() + " Availabel");  
                    }  
                }  
            }  
            return true;  
        }  
        return false;  
    }  
}  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值