Android 动态监听网络变化

很多时候我们需要对当前手机的网络状态进行判断。

例如:

没有网络时打开应用,应该加载缓存数据,不去请求数据等。
当前为wifi网络时,应该加载高清图片,视频自动下载缓存等。
当前为2G网络时,应该停止下载等高流量需求的操作,并提示用户等。
.....
.....

如何监听网络的变化呢?用后台服务是一个很好的选择。既能实时获取当前Android的网络状态,还能不依赖与Activity的生命周期。

一.编写服务类

代码注释已经很详细了,主要步骤就是自定义广播实例,并注册系统网络连接的广播(IntentFilter).

public class NetworkStateService extends Service {

    // Class that answers queries about the state of network connectivity.
    // 系统网络连接相关的操作管理类.

    private ConnectivityManager connectivityManager;
    // Describes the status of a network interface.
    // 网络状态信息的实例
    private NetworkInfo info;

    /**
     * 当前处于的网络
     * 0 :null 
     * 1 :2G/3G 
     * 2 :wifi
     */
    public static int networkStatus; 

    public static final String NETWORKSTATE = "com.text.android.network.state"; // An action name

    /**
     * 广播实例
     */
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // The action of this intent or null if none is specified.
            // action是行动的意思,也许是我水平问题无法理解为什么叫行动,我一直理解为标识(现在理解为意图)
            String action = intent.getAction(); //当前接受到的广播的标识(行动/意图)

            // 当当前接受到的广播的标识(意图)为网络状态的标识时做相应判断
            if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                // 获取网络连接管理器
                connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

                // 获取当前网络状态信息
                info = connectivityManager.getActiveNetworkInfo();

                if (info != null && info.isAvailable()) {

                    //当NetworkInfo不为空且是可用的情况下,获取当前网络的Type状态
                    //根据NetworkInfo.getTypeName()判断当前网络
                    String name = info.getTypeName();

                    //更改NetworkStateService的静态变量,之后只要在Activity中进行判断就好了
                    if (name.equals("WIFI")) {
                        networkStatus = 2;
                    } else {
                        networkStatus = 1;
                    }

                } else {

                    // NetworkInfo为空或者是不可用的情况下
                    networkStatus = 0;

                    Toast.makeText(context, "没有可用网络!\n请连接网络后刷新本界面", Toast.LENGTH_SHORT).show();

                    Intent it = new Intent();
                    it.putExtra("networkStatus", networkStatus);
                    it.setAction(NETWORKSTATE);
                    sendBroadcast(it); //发送无网络广播给注册了当前服务广播的Activity
                    /**
                     * 这里推荐使用本地广播的方式发送:
                     * LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
                     */
                }
            }
        }
    };

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

    @Override
    public void onCreate() {
        super.onCreate();

        //注册网络状态的广播,绑定到mReceiver
        IntentFilter mFilter = new IntentFilter();
        mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(mReceiver, mFilter);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //注销接收
        unregisterReceiver(mReceiver);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    /** 
     * 判断网络是否可用 
     */  
    public static boolean isNetworkAvailable(Context context) {  
        // 获取网络连接管理器
        ConnectivityManager mgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);  

        // 获取当前网络状态信息
        NetworkInfo[] info = mgr.getAllNetworkInfo();  
        if (info != null) {  
            for (int i = 0; i < info.length; i++) {  
                if (info[i].getState() == NetworkInfo.State.CONNECTED) {  
                    return true;  
                }  
            }  
        }

        return false;  
    }  
}

二.启动服务

在Activity中启动服务

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.qzmobile_main);
    Intent intent = new Intent();
    intent.setAction("com.text.service.NetworkStateService");
    startService(intent);
}

三.注册服务

服务是四大组件之一,当然不能忘记在AndroidManifest.xml中注册服务。

<service android:name="com.text.service.NetworkStateService" >
    <intent-filter android:priority="1000" >
        <action android:name="com.text.service.NetworkStateService" />
    </intent-filter>
</service>

最后不要忘了网络权限

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

至此,你就能通过自己定义的服务实施监控网络状态了,当网络状态转变的时候,你也对Activity发出相应要处理的广播即可。


在播放器中,我们常常可以看到这么一个设计,就是用户通过在屏幕的某个部分上下滑动就可以调节屏幕的亮度,在某个部分上下滑动就可以调节播放的音量。而左右滑动就可以调节播放的进度。

今天,我要说一下亮度的调节。其实主要是通过设置View的属性实现的。

[java] view plain copy
  1. public void onLightChange(float delta, int distance, Window window) {  
  2.       WindowManager.LayoutParams params = window.getAttributes();  
  3.   
  4.       mCurrentDeltaBrintness = mCurrentDeltaBrintness + delta;  
  5.   
  6.       if (params.screenBrightness == WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE) {  
  7.           params.screenBrightness = getScreenBrightness(getContext());  
  8.       }  
  9.   
  10.       if (Math.abs(mCurrentDeltaBrintness) >= mScrolledPixPerBringhtness) {  
  11.           float deltaBrightness = mCurrentDeltaBrintness / (mScrolledPixPerBringhtness * MAX_BRINTNESS);  
  12.           params.screenBrightness = params.screenBrightness + deltaBrightness;  
  13. t;pre name="code" class="java">    private void performLightChange(float brightness) {  
  14.       int resId = R.drawable.light_0;  
  15.   
  16.       if (brightness <= 0.01f) {  
  17.           resId = R.drawable.light_0;  
  18.       } else if (brightness <= 0.25f) {  
  19.           resId = R.drawable.light_25;  
  20.       } else if (brightness <= 0.5f) {  
  21.           resId = R.drawable.light_50;  
  22.       } else if (brightness < 1.0f) {  
  23.           resId = R.drawable.light_75;  
  24.       } else {  
  25.           resId = R.drawable.light_100;  
  26.       }  
  27.   
  28.       updateViews(resId, (int) (brightness * 100));  
  29.   }  

if (params.screenBrightness <= 0.01f) { params.screenBrightness = 0.01f; } window.setAttributes(params); mCurrentDeltaBrintness = 0; } performLightChange(params.screenBrightness); }

 
上述代码就是在左边部分上下滑动的时候会被调用。 

另附performLigthChange的代码。

[java] view plain copy
  1. private void performLightChange(float brightness) {  
  2.     int resId = R.drawable.light_0;  
  3.   
  4.     if (brightness <= 0.01f) {  
  5.         resId = R.drawable.light_0;  
  6.     } else if (brightness <= 0.25f) {  
  7.         resId = R.drawable.light_25;  
  8.     } else if (brightness <= 0.5f) {  
  9.         resId = R.drawable.light_50;  
  10.     } else if (brightness < 1.0f) {  
  11.         resId = R.drawable.light_75;  
  12.     } else {  
  13.         resId = R.drawable.light_100;  
  14.     }  
  15.   
  16.     updateViews(resId, (int) (brightness * 100));  
  17. }  

我们在举一个相对好切入的例子。

[java] view plain copy
  1. 复制代码  
  2.  1 package android.lekko.tools;  
  3.  2   
  4.  3 import android.app.Activity;  
  5.  4 import android.content.ContentResolver;  
  6.  5 import android.provider.Settings;  
  7.  6 import android.provider.Settings.System;  
  8.  7 import android.view.WindowManager;  
  9.  8 import android.widget.Toast;  
  10.  9   
  11. 10 public class LightnessControl {  
  12. 11     // 判断是否开启了自动亮度调节   
  13. 12     public static boolean isAutoBrightness(Activity act) {   
  14. 13         boolean automicBrightness = false;   
  15. 14         ContentResolver aContentResolver = act.getContentResolver();  
  16. 15         try {   
  17. 16             automicBrightness = Settings.System.getInt(aContentResolver,   
  18. 17                    Settings.System.SCREEN_BRIGHTNESS_MODE) == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;   
  19. 18         } catch (Exception e) {   
  20. 19             Toast.makeText(act,"无法获取亮度",Toast.LENGTH_SHORT).show();  
  21. 20         }   
  22. 21         return automicBrightness;   
  23. 22     }       
  24. 23     // 改变亮度  
  25. 24     public static void SetLightness(Activity act,int value)  
  26. 25     {          
  27. 26         try {  
  28. 27             System.putInt(act.getContentResolver(),System.SCREEN_BRIGHTNESS,value);   
  29. 28             WindowManager.LayoutParams lp = act.getWindow().getAttributes();   
  30. 29             lp.screenBrightness = (value<=0?1:value) / 255f;  
  31. 30             act.getWindow().setAttributes(lp);  
  32. 31         } catch (Exception e) {  
  33. 32             Toast.makeText(act,"无法改变亮度",Toast.LENGTH_SHORT).show();  
  34. 33         }          
  35. 34     }  
  36. 35     // 获取亮度  
  37. 36     public static int GetLightness(Activity act)  
  38. 37     {  
  39. 38         return System.getInt(act.getContentResolver(),System.SCREEN_BRIGHTNESS,-1);  
  40. 39     }  
  41. 40     // 停止自动亮度调节   
  42. 41     public static void stopAutoBrightness(Activity activity) {   
  43. 42         Settings.System.putInt(activity.getContentResolver(),   
  44. 43                 Settings.System.SCREEN_BRIGHTNESS_MODE,   
  45. 44                 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);   
  46. 45     }  
  47. 46     // 开启亮度自动调节   
  48. 47     public static void startAutoBrightness(Activity activity) {   
  49. 48         Settings.System.putInt(activity.getContentResolver(),   
  50. 49                 Settings.System.SCREEN_BRIGHTNESS_MODE,   
  51. 50                 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);   
  52. 51     }   
  53. 52 }  
  54. 复制代码  
  55.   这是一个单独可工作的类,主要用于调节屏幕亮度,有部分注释了,解释几个概念,不标准,供参考:  
  56.   ContentResolver类,为访问其它应用程序的对外共享数据提供方法,如上面获取、设置亮度时使用的System.getInt(),System.setInt()。  
  57.   Activity类,android程序的主要类,一个界面必有此类提供后台支持,需要继承此类。  
  58.   Settings类,android程序系统相关的设置类,各种设置都可在此找。  
  59.   LayoutParams类,android界面相关的参数,如高度、宽度、亮度等。  
  60.   Toast类,一个可自动消失的提示框,轻型控件。  


好,屏幕的亮度调节就到这里,很简单的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值