在智能电视开发过程中,需要经常连接电视或者盒子。 连接设备需要知道设备的IP地址,于是我们不得不通过遥控器去系统中找设置,找到无线和网络的设置。判断当前是无线还是以太网,再选择去查看设备的IP,操作比较繁琐。如果能够在电视屏幕的下方,始终显示着系统的IP信息,岂不是更方便我们调试吗。
需求就是原动力,之前放过一个ADB命令免输入的工具,参见 ADB命令免输入工具(远程调试android设备使用) 。 这个小工具其实非常简单,就是悬浮在屏幕的某个位置,将IP地址展示给我们。当监听打到网络发生变化时,能够重新获得当前设备的IP。
好了,接下来我们自己动手开发一个,这里需要解决三个问题
1.悬浮框
2. 获取设备的IP
3.通知悬浮框位置发生变化
2.获取IP地址,不多说
3.通知悬浮框位置发生变化
附效果图:
需求就是原动力,之前放过一个ADB命令免输入的工具,参见 ADB命令免输入工具(远程调试android设备使用) 。 这个小工具其实非常简单,就是悬浮在屏幕的某个位置,将IP地址展示给我们。当监听打到网络发生变化时,能够重新获得当前设备的IP。
好了,接下来我们自己动手开发一个,这里需要解决三个问题
1.悬浮框
2. 获取设备的IP
3.通知悬浮框位置发生变化
下面给出各个问题的实现思路及代码,文章最后提供demo。
1、悬浮框
悬浮窗口在任何情况下,都处于其他所有窗口的最顶端。在该View创建时,只要将这个View的窗体布局参数的类型WindowManager.LayoutParams.Type设置为WindowManager.LayoutParams.TYPE_PHONE 即可。该View会处于所有窗口的顶端,但是位于status bar下面。
这样设置需要权限:
<uses-permission android:name = "android.permission.SYSTEM_ALERT_WINDOW" />
另外,这个View需要在Service中创建,才会悬浮在系统中。如果是在Activity中创建,只会悬浮在应用的窗口内。
核心代码:
@Override
public void onCreate() {
super .onCreate();
LayoutInflater mInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE );
view = mInflater.inflate(R.layout. floating , null );
tvIp = (TextView) view.findViewById(R.id. tvIp );
wm = (WindowManager) getSystemService(WINDOW_SERVICE );
wmParams = new WindowManager.LayoutParams();
wmParams. height = WindowManager.LayoutParams.WRAP_CONTENT ;
wmParams. width = WindowManager.LayoutParams.WRAP_CONTENT ;
wmParams. alpha = ( float ) 0.99;
//从sp 拿位置信息
wmParams. gravity = getSharedPreferences(Constaint.SP_FLOAT , MODE_PRIVATE ).getInt(Constaint. GRAVITY, (Gravity. RIGHT | Gravity.BOTTOM ));
wmParams. x = 10;
wmParams. y = 10;
wmParams. flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE ; // 表示不接受键盘输入时间
wmParams. type = WindowManager.LayoutParams.TYPE_PHONE ; // 表示系统级别窗口
wmParams. format = PixelFormat. RGBA_8888 ;
wm.addView( view, wmParams);
}
2.获取IP地址,不多说
private String getLocalIPAddress() throws SocketException {
for (Enumeration<NetworkInterface> en = NetworkInterface
. getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr
.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()
&& (inetAddress instanceof Inet4Address)) {
return inetAddress.getHostAddress().toString();
}
}
}
return "null" ;
}
获取网络状态,当然不要忘记申请监听网络的权限
<uses-permission android:name ="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name ="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name ="android.permission.INTERNET" />
3.通知悬浮框位置发生变化
上面说道悬浮框是通过Service启动的,当我们在设置中,改变了悬浮框位置,需要通知悬浮框。使用Intent启动Service时,只有第一次启动Service是时候,会调用Service的OnCreate()方法。OnCreate()方法之后,调用的是onStartCommand()方法;
如果再次使用相同的Intent启动Service时,则不在调用Service的OnCreate()方法,而是直接调用onStartCommand()方法。
所以我们可以在Intent中封装悬浮框的位置信息,在Service的onStartCommand()中解析位置信息,并刷新悬浮框的位置信息。
如果再次使用相同的Intent启动Service时,则不在调用Service的OnCreate()方法,而是直接调用onStartCommand()方法。
所以我们可以在Intent中封装悬浮框的位置信息,在Service的onStartCommand()中解析位置信息,并刷新悬浮框的位置信息。
/**
* 重复启动service,不会调用 oncreate,会调用onStartCommand
* @param intent
* @param flags
* @param startId
* @return
*/
public int onStartCommand(Intent intent, int flags, int startId) {
wmParams. gravity = intent.getIntExtra( "gravity", 0);
//为0说明灭有接收到
if (wmParams .gravity != 0) {
wm.updateViewLayout( view, wmParams);
}
return super .onStartCommand(intent , flags, startId);
};
附效果图:
附demo下载:点我下载
原文链接:http://www.67tgb.com/?p=588
转载注明:望月听涛