Android之广播与服务<一>

转发请注明出处:http://blog.csdn.net/qq_28055429/article/details/52014058

前言:作为四大组件成员--广播和服务,虽然在用户使用时它们通常是隐身的,但是好多地方都有它们的身影,如:发送短信,状态栏通知,夜间模式,后台音乐播放等等....


One  ----------- 广播:

一,基本知识:

(1)名字:BroadcastReceiver

(2)作用:用于监听系统全局的广播消息,以便实现系统中不同组件之间的通信

(3)经常用途:飞行模式,后台音乐播放(与Service结合),电池电量,短信收接,电源断接,apk装卸,内存,拍照,开机自启等

二,基本用法:

(1)创建需要启动的BroadcastReceiver的Intent(可以设置Intent的相关属性)

(2)调用Context的sendBroadcast()或sendOrderedBroadcast()方法来启动指定的广播

例子:

在主类中:

    Intent intent = new Intent();   //创建要启动广播的Intent
    intent.setAction("com.maiyu.action.MAIYU_BROADCAST");   //为Intent设置相关属性,这里采用自定义动作(需要去注册)
    intent.putExtra("msg" , "自定义的广播");
        sendBroadcast(intent);
自定义广播接收器,一般是继承:

public class MyReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context , "接收到的Action为:" + intent.getAction()
                + "\n消息内容是:" + intent.getStringExtra("msg") ,Toast.LENGTH_SHORT).show();
    }
}

然后在Manifest中注册:

<receiver android:name=".MyReceiver">
            <intent-filter>
                <action android:name="com.maiyu.action.MAIYU_BROADCAST"/>
            </intent-filter>
        </receiver>

三,广播的分类:

Normal Broadcast  ----  普通广播:同时被接受,无法传递接收处理后的结果,无法终止传播

  -------用sendBroadcast()方法发送 

Ordered Broadcast------ 有序广播:按等级传播,高--低(可用IntentFilter.setPriority()设置,低于的不能接收到,高的接收后,

可以终止继续传播

 -------- 用sendOrderedBroadcast()方法发送

四,另一种常用用法(常用此方法)

使用registerReceiver()来注册,步骤如下:

(1)自定义广播接收器,一般采用继承,然后重写onReceive()方法(可在里面判断动作):

如开机自启设置:

    //自定义开机自启广播接收器:
    class BootCompleteReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            /*Intent.ACTION_BOOT_COMPLETED:是系统开机自启的动作*/
            if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
                //FourActivity为当前Activity
                Intent  newIntent = new Intent(context , FourActivity.class);
                newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(newIntent);
            }
        }
    }

然后在FourActivity中,创建该广播接收器,并去注册:

在onCreate方法中:

BCreceiver  =   new BootCompleteReceiver();
在需要的监听代码中:

                //开机自启动的设置
                case R.id.startAfterBoot :
                    //下面三行可概括为:
                    // registerReceiver(BCreceiver , new IntentFilter("android.intent.action.BOOT_COMPLETED"));
                    IntentFilter inf = new IntentFilter();
                    inf.addAction(Intent.ACTION_BOOT_COMPLETED);
                    registerReceiver(BCreceiver , inf);
                    Toast.makeText(FourActivity.this , "开机自启已经完成" , Toast.LENGTH_SHORT).show();
                    break;
                case R.id.nostartAfterBoot :
                    if(BCreceiver != null){
                        unregisterReceiver(BCreceiver); //取消注册
                        Toast.makeText(FourActivity.this , "开机自启已经取消" , Toast.LENGTH_SHORT).show();
                    }
                    break;
记得添加自启动权限:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
由此可见:registerReceiver():接收两个参数,

------参数1:自定义的广播接收器对象

------参数2:IntentFilter对象

五,12个例子:拍照启动,耳机插入,电量电池低,电源断开与接入,

墙纸改变,手机重启,APK安装与卸载,SD卡插入与拔出,

系统与区域改变的设置,内存不足与锁屏解锁,开机自启 ,飞行模式设置,

(1)拍照启动:Intent.ACTION_CAMERA_BUTTON

  自定义广播接收器TakePhotoReceiver:继承BroadcastReceiver,重写onReceive方法:

    //自定义拍照广播接收器:
    class TakePhotoReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            if(intent.getAction().equals(Intent.ACTION_CAMERA_BUTTON)){
                Toast.makeText(FourActivity.this , "检测到拍照广播接收器" , Toast.LENGTH_SHORT).show();
            }
        }
    }

在onCreat方法中,创建该接收器:

        TPreceiver  =   new TakePhotoReceiver();
然后在需要的监听地方去实现:

                case R.id.startTake :
                    registerReceiver(TPreceiver , new IntentFilter(Intent.ACTION_CAMERA_BUTTON));
                    Toast.makeText(FourActivity.this , "拍照广播已启动" , Toast.LENGTH_SHORT).show();
                    break;
                case R.id.nostartTake :
                    if(TPreceiver != null){
                        unregisterReceiver(TPreceiver); //取消注册
                        Toast.makeText(FourActivity.this , "拍照广播已经取消" , Toast.LENGTH_SHORT).show();
                    }
                    break;

这里不需要添加权限,,,


(2)耳机插入:耳机插入时需要关闭播放效果,开启耳机模式

动作--------Intent.ACTION_HEADSET_PLUG

同理:

自定义广播接收器:EarphoneInsertReceiver ,继承BroadcastReceiver,重写onReceive方法,代码如下;

    //自定义拍照广播接收器:
    class EarphoneInsertReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            if(intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)){
                Toast.makeText(context, "检测到耳机插入广播" , Toast.LENGTH_SHORT).show();
            }
        }
    }
在onCreate方法中创建该接收器:

earphoneIR = new EarphoneInsertReceiver();
然后,在需要的地方,去实现和注册:

registerReceiver(earphoneIR , new IntentFilter(Intent.ACTION_HEADSET_PLUG));
取消注册:

 unregisterReceiver(earphoneIR );

取消注册时只需要广播接收器一个参数..

(3)到(11)的方法类似于上面就不粘贴代码了:

(3)电量电池低:

Action----------Intent.ACTION_BATTERY_LOW

(4)电源断开与接入:

 断开 ---------Intent.ACTION_POWER_DISCONNECTED

         接入-----------Intent.ACTION_POWER_CONNECTED

(5)手机墙纸改变:

                --------- Intent.ACTION_WALLPARER_CHANGED
(6)手机重启:

-------- Intent.ACTION_REBOOT


(7)APK安装与卸载:

安装  ------------Intent.ACTION_PACKAGE_ADDED

卸载 ------------Intent.ACTION_PACKAGE_REMOVED

(8)SD开插入与拔出

插入------------Intent.ACTION_MEDIA_MOUNTED

拔出------------Intent.ACTION_MEDIA_EJECT


(9)系统设置与区域设置的改变

系统设置---------Intent.ACTION_CONFIGURATION_CHANGED

区域设置---------Intent.ACTION_LOCALE_CHANGED

(10)内存不足与锁屏,解锁

内存不足---------Intent.ACTION_DEVICE_STORAGE_LOW

锁屏 --------------Intent.ACTION_SCREEN_OFF

解锁-------------- Intent.ACTION_SCREEN_ON

(11)开机自启:

-----------Intent.ACTION_BOOT_COMPLETED

   这里需要权限:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
12)飞行模式设置:这里有点不同,详见代码:

布局,两个按钮:分别是开启飞行模式和关闭飞行模式:

<!--定义基本布局:LinearLayout-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
<!--定义两个按钮:开启与关闭飞行模式-->
    <Button
        android:id="@+id/btn_startflying"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="开启飞行模式" />
    <Button
        android:id="@+id/btn_stopflying"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="关闭飞行模式" />
   
</LinearLayout>
主类中:用sendBroadcast来发送广播,代码如下:

public class MainActivity extends Activity {
	private Button btnStartFly , btnStopFly;//定义开启与关闭飞行模式按钮
	private ContentResolver cr;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		cr = getContentResolver();	//获取
		findView();		//为控件绑定ID
		setListener();	//设置监听
	}

	//为控件绑定ID
	private void findView() {
		btnStartFly = (Button) findViewById(R.id.btn_startflying);
		btnStopFly = (Button) findViewById(R.id.btn_stopflying);
	}

	// 设置监听
	private void setListener() {
		btnStartFly.setOnClickListener(listener);
		btnStopFly.setOnClickListener(listener);
	}

	OnClickListener listener = new OnClickListener() {
		@Override
		public void onClick(View v) {
			switch (v.getId()) {
			case R.id.btn_startflying:
				if (Settings.System.getString(cr,
						Settings.System.AIRPLANE_MODE_ON).equals("0")) {
					Log.e("AIRPLANE_MODE_ON", "0");
					// 获取当前飞行模式状态,返回的是String值0,或1.0为关闭飞行,1为开启飞行
					// 如果关闭飞行,则打开飞行
					Settings.System.putString(cr,
							Settings.System.AIRPLANE_MODE_ON, "1");
					// 设置需要启动的ACTION
					Intent intent = new Intent(
							Intent.ACTION_AIRPLANE_MODE_CHANGED).
							putExtra("state", true);;
					// 发送飞行广播
					sendBroadcast(intent);
					Toast.makeText(MainActivity.this,
							"已开启飞行模式",
							Toast.LENGTH_SHORT).show();
				}

				break;
			case R.id.btn_stopflying:
				if (Settings.System.getString(cr,
						Settings.System.AIRPLANE_MODE_ON).equals("1")) {
					Log.e("AIRPLANE_MODE_ON", "1");
					// 获取当前飞行模式状态,返回的是String值0,或1.0为关闭飞行,1为开启飞行
					// 如果打开飞行,则关闭飞行
					Settings.System.putString(cr,
							Settings.System.AIRPLANE_MODE_ON, "0");
					// 设置需要启动的ACTION
					Intent intent = new Intent(
							Intent.ACTION_AIRPLANE_MODE_CHANGED).
							putExtra("state", false);;
					// 发送飞行广播
					sendBroadcast(intent);
					Toast.makeText(MainActivity.this, "已关闭飞行模式",
							Toast.LENGTH_SHORT).show();
				}
				break;
			}
		}
	};
}
然后添加权限:

  <uses-permission android:name="android.permission.WRITE_SETTINGS" />
就可以了


TWO --------- 服务:

一,基本知识:

(1)名字:Service

(2)理解:类似于Activity,有自己的生命周期,在后台运行
(3)用法:两个步骤,创建子类,然后去AndroidManifest中配置

--------- (配置该Service时:可通过<intent-filter..../>来指定哪些Intent被启动)

二,基本方法:

第一种:调用startService()时:

onCreate():第一次创建时调用

onStartCommand():每次用户调用startService()时会调用

onDestroy():关闭服务前调用

第二种:调用bindService()时:

onCreate():第一次创建服务时调用

onBind():是Service子类必须实现的方法,返回一个IBinder对象

onUnbind():当服务上的所有客户端断开时调用

三,3个例子:定时任务,开车模式与夜间模式,音量控制

(1)定时任务:

布局:定义四个按钮,定时发送 / 关闭 :广播,服务

<?xml version="1.0" encoding="utf-8"?>
<!--定义基本布局:LinearLayout-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <!--放置四个按钮:定时发送广播,服务,定时关闭广播,服务-->
    <Button
        android:id="@+id/StartBroadcast"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn3_second"/>
    <Button
        android:id="@+id/StartService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn4_second"/>
    <Button
        android:id="@+id/StopBroadcast"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn5_second"/>
    <Button
        android:id="@+id/StopService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn6_second"/>

</LinearLayout>


字符串:

    <string name="btn3_second">定时发送广播</string>
    <string name="btn4_second">定时启动服务</string>
    <string name="btn5_second">停止定时广播</string>
    <string name="btn6_second">停止定时服务</string>

主类代码:如下:


package testsdcard.com.maiyu.s07_01.activity;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import testsdcard.com.maiyu.s07_01.R;
import testsdcard.com.maiyu.s07_01.broadcast.ActionBroadCast;
import testsdcard.com.maiyu.s07_01.service.ActionService;

/**
 * Created by maiyu on 2016/7/23.
 */
public class SecondActivity extends Activity {
    private Button  BtnStartBC , BtnStartSR , BtnStopBC , BtnStopSR;  //定义启动和停止:服务和广播
    private Notification  baseNF ;      //定义通知对象
    private NotificationManager nm ;    //定义通知管理对象
    private AlarmManager am ;           //闹钟管理
    private PendingIntent   pi1 , pi2 ;  //定义延迟发送的请求

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        am  =   (AlarmManager)getSystemService(ALARM_SERVICE);      //获取AlermManager服务
        nm  =   (NotificationManager)getSystemService(NOTIFICATION_SERVICE);    //获取通知服务
        findView();     //为控件绑定id
        setListener();  //为控件设置监听
    }

    //为各个控件设置监听
    private void setListener() {
        BtnStartBC.setOnClickListener(mylistener);
        BtnStartSR.setOnClickListener(mylistener);
        BtnStopSR.setOnClickListener(mylistener);
        BtnStopBC.setOnClickListener(mylistener);
    }

    //自定义监听器
    View.OnClickListener    mylistener  =   new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.StartBroadcast:   //开启闹钟广播
                    /**4个参数:
                     Context context, int requestCode, Intent intent, int flags
                     */
                    pi1 = PendingIntent.getBroadcast(SecondActivity.this, 0,
                            new Intent(SecondActivity.this, ActionBroadCast.class),
                            Intent.FILL_IN_ACTION); //得到延迟的PendingIntent
                    long  now = System.currentTimeMillis();
                    /**
                     * 4个参数:
                     * int type, long triggerAtMillis, long intervalMillis, PendingIntent operation
                     */
                    //设置重复闹钟
                    am.setInexactRepeating(AlarmManager.RTC_WAKEUP , now , 3000, pi1);

                    break;
                case R.id.StartService:
                    //获取延迟PendingIntent
                    pi2     =   PendingIntent.getService(SecondActivity.this , 0 ,
                            new Intent(SecondActivity.this , ActionService.class) , Intent.FILL_IN_ACTION);
                    long    now1 = System.currentTimeMillis();
                    //设置重复闹钟
                    am.setInexactRepeating(AlarmManager.RTC_WAKEUP , now1 , 3000 , pi2);
                    break;
                case R.id.StopBroadcast:
                    am.cancel(pi1);     //取消延迟的PendingIntent
                    break;
                case R.id.StopService:
                    am.cancel(pi2);
                    break;
                default:
                    break;
            }
        }
    };

    //为控件绑定Id
    private void findView() {
        BtnStartBC      =   (Button)findViewById(R.id.StartBroadcast);
        BtnStartSR      =   (Button)findViewById(R.id.StartService);
        BtnStopBC       =   (Button)findViewById(R.id.StopBroadcast);
        BtnStopSR       =   (Button)findViewById(R.id.StopService);
    }
}

字符串:

    <string name="btn8_second">开启行车模式</string>
    <string name="btn9_second">关闭行车模式</string>
    <string name="btn10_second">开启夜间模式</string>
    <string name="btn11_second">关闭夜间模式</string>

自定义服务类:

package testsdcard.com.maiyu.s07_01.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

/**
 * Created by maiyu on 2016/7/23.
 */
public class ActionService extends Service {
    private static int num = 0;
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("ActionService" , "New Message ! " + num++);
    }
}

自定义广播接收器:

package testsdcard.com.maiyu.s07_01.broadcast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class ActionBroadCast extends BroadcastReceiver{
    private static int  num = 0 ;
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("AciontBroadCast" ,"new message : " + num++ );
    }
}
这样就行了,,,

(2)开启行车模式和夜间模式:当开车时,需要开启行车模式(电话会自动接入)

布局:同样定义4个按钮:开启和关闭行车模式,开启和关闭夜间模式

<?xml version="1.0" encoding="utf-8"?>
<!--定义基本布局:LinearLayout-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <!--放置四个按钮:开启和关闭:行车模式,夜间模式-->
    <Button
        android:id="@+id/OpenDC"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn8_second"/>
    <Button
        android:id="@+id/CloseDC"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn9_second"/>
    <Button
        android:id="@+id/OpenN"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn10_second"/>
    <Button
        android:id="@+id/CloseN"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn11_second"/>

</LinearLayout>

主类中去,实现:

----先调用服务:UiModeManager

uiModeManager   =   (UiModeManager)getSystemService(Context.UI_MODE_SERVICE);   //获取系统UiModeManager服务
再去实现相关方法,

package testsdcard.com.maiyu.s07_01.activity;

import android.app.Activity;
import android.app.UiModeManager;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import testsdcard.com.maiyu.s07_01.R;

/**
 * Created by maiyu on 2016/7/23.
 */
public class SecondActivity extends Activity {
    private UiModeManager uiModeManager ;       //UiModeManager对象
    private Button BtnOpenDC , BtnCloseDC , BtnOpenN , BtnCloseN;       //开车模式和夜间模式

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        uiModeManager   =   (UiModeManager)getSystemService(Context.UI_MODE_SERVICE);   //获取系统UiModeManager服务
        findView();     //为控件绑定id
        setListener();  //为控件设置监听
    }

    //为各个控件设置监听
    private void setListener() {
        //行车模式和夜间模式
        BtnOpenDC.setOnClickListener(mylistener);
        BtnCloseDC.setOnClickListener(mylistener);
        BtnOpenN.setOnClickListener(mylistener);
        BtnCloseN.setOnClickListener(mylistener);
    }

    //自定义监听器
    View.OnClickListener    mylistener  =   new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.OpenDC:       //开车模式
                    uiModeManager.enableCarMode(UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME);
                    Toast.makeText(SecondActivity.this , "已经开启行车模式",Toast.LENGTH_SHORT).show();
                    break;
                case R.id.CloseDC:      //关闭开车模式
                    uiModeManager.disableCarMode(UiModeManager.DISABLE_CAR_MODE_GO_HOME);
                    Toast.makeText(SecondActivity.this , "已经关闭行车模式",Toast.LENGTH_SHORT).show();
                    break;
                case R.id.OpenN:        //开启夜间模式,
                    uiModeManager.setNightMode(UiModeManager.MODE_NIGHT_YES);
                    Toast.makeText(SecondActivity.this , "已经开启夜间模式",Toast.LENGTH_SHORT).show();
                    break;
                case R.id.CloseN:       //关闭夜间模式
                    uiModeManager.setNightMode(UiModeManager.MODE_NIGHT_NO);
                    Toast.makeText(SecondActivity.this , "已经关闭夜间模式",Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }
        }
    };
    
    //为控件绑定Id
    private void findView() {
        //行车与夜间模式
        BtnOpenDC       =   (Button)findViewById(R.id.OpenDC);
        BtnCloseDC      =   (Button)findViewById(R.id.CloseDC);
        BtnOpenN        =   (Button)findViewById(R.id.OpenN);
        BtnCloseN       =   (Button)findViewById(R.id.CloseN);
    }
}

(3)音量控制:

布局:三个按钮,当前音量,增大和减少:

<?xml version="1.0" encoding="utf-8"?>
<!--定义基本布局:LinearLayout-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <!--放置3个按钮:查看,增大,减少-->
    <Button
        android:id="@+id/CurrentV"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn12_second"/>
    <Button
        android:id="@+id/IncreaseV"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn13_second"/>
    <Button
        android:id="@+id/DeclineV"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn14_second"/>

</LinearLayout>
字符串:

    <string name="btn12_second">当前音量</string>
    <string name="btn13_second">增大音量</string>
    <string name="btn14_second">减少音量</string>

主类中:

先获取音量管理的服务:

audioManager    =   (AudioManager)getSystemService(Context.AUDIO_SERVICE);      //获取声音管理
然后再去调用相关方法,具体代码如下:

package testsdcard.com.maiyu.s07_01.activity;

import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import testsdcard.com.maiyu.s07_01.R;

public class SecondActivity extends Activity {
    private Button BtnCurrentV , BtnIncreaseV , BtnDeclineV;
    private AudioManager audioManager;      //声音管理对象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        audioManager    =   (AudioManager)getSystemService(Context.AUDIO_SERVICE);      //获取声音管理
        findView();     //为控件绑定id
        setListener();  //为控件设置监听
    }

    //为各个控件设置监听
    private void setListener() {
        //声音
        BtnCurrentV.setOnClickListener(mylistener);
        BtnIncreaseV.setOnClickListener(mylistener);
        BtnDeclineV.setOnClickListener(mylistener);
    }

    //自定义监听器
    View.OnClickListener    mylistener  =   new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.CurrentV :    //当前音量
                    //分别得到当前的:通话音量,系统音量,音乐音量,提示声音量
                    int   currentCall       =   audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
                    int   currentSystem     =   audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM);
                    int   currentMusic      =   audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
                    int   currentTip        =   audioManager.getStreamVolume(AudioManager.STREAM_ALARM);
                    Toast.makeText(SecondActivity.this , "当前通话音量:" + currentCall + "\n当前系统音量" + currentSystem
                            + "\n当前音乐音量:" + currentMusic + "\n当前提示音音量:" + currentTip ,Toast.LENGTH_SHORT).show();

                    break;
                case R.id.IncreaseV :
                    audioManager.adjustStreamVolume(AudioManager.STREAM_SYSTEM , AudioManager.ADJUST_RAISE ,
                            AudioManager.FX_FOCUS_NAVIGATION_UP);
                    break;
                case R.id.DeclineV :
                    audioManager.adjustStreamVolume(AudioManager.STREAM_SYSTEM ,AudioManager.ADJUST_LOWER ,
                            AudioManager.FX_FOCUS_NAVIGATION_UP);
                    break;
                default:
                    break;
            }
        }
    };
    
    //为控件绑定Id
    private void findView() {
        //声音管理
        BtnCurrentV     =   (Button)findViewById(R.id.CurrentV);
        BtnIncreaseV    =   (Button)findViewById(R.id.IncreaseV);
        BtnDeclineV     =   (Button)findViewById(R.id.DeclineV);
    }
}
这样就OK了,

这都只是简单的测试......

待续........

附注:

本文的大部分例子代码下载地址:http://download.csdn.net/detail/qq_28055429/9584895


本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。
1、图像坐标系 如图2.1所示,以图像左上角为原点建立以像素为单位的直接坐标系u-v。像素的横坐标u与纵坐标v分别是在其图像数组中所在的列数与所在行数。(在OpenCV中u对应 x,v对应y) 由于(u,v)只代表像素的列数与行数,而像素在图像中的位置并没有用物理单位表示出来,所以,我们还要建立以物理单位(如毫米)表示的图像坐标系x-y。将相机光轴 与图像平面的交点(一般位于图像平面的中心处,也称为图像的主点(principal point)定义为该坐标系的原点O1,且x轴与u轴平行,y轴与v轴平行,假
ART世界探险(6) - 流程控制指令 分支结构 Java分支结构 我们先来个最简单的,比较大小吧。 public static long bigger ( long a, long b){ if (a=b){ return a; } else { return b; } } public static int less ( int a, int b){ if (a=b){ return a; } else { return b; } } 看看Java字节码是个什么样子: public static lo
Handler机制算是我入门源码的第一节。看得比较仔细。体会较多。mark一下。 顺序:先科普一下Handler基本功,然后再细讲下源码 一、Handler目的: 目的:Handler机制来处理了子线程去更新UI线程控件问题。 二、handler,messagequeue,looper,message关系图: 其实各种书籍上都有这么一张图。但是主要是学习源码,所以还是自己手画一张“流程图”。 三、handler知识点总结: ( 若以下总结都能理解,那么可以不再看本文后续源码分析; ) 1)handler、

ART世界探险(5) - 计算指令 - 2016-07-25 18:07:28

ART世界探险(5) - 计算指令 整数运算 Java的整型运算 我们先看看JVM是如何处理这些基本整数运算的吧。 public static long add ( long a, long b){ return a+b; } public static long sub ( long a, long b){ return a-b; } public static long mul ( long a, long b){ return a*b; } public static long div ( long
大部分的软件, 但凡包含登录注册的, 基本都会有选择头像功能, 而其中做的比较有逼格的, 一般会有一个选择框可以裁剪照片。 本文所需要实现的就是这样一种有 逼格 的效果: 右上角加了个图片框,按下确定可以裁剪正方形区域里的图片并显示在右上角。 实现思路: 1:首先需要自定义一个ZoomImageView来显示我们需要的图片,这个View需要让图片能够以合适的位置展现在当前布局的图片展示区域内(合适的位置值的是:如果图片长度大于屏幕,则压缩图片长度至屏幕宽度,高度等比压缩并居中显示,如果图片高度大于屏幕,则

注解使用入门(一) - 2016-07-25 18:07:18

注解使用入门(一) 本篇博客要讲解主要分为以下几个问题 注解的相关知识点 基于运行时的注解的例子解析说明 至于关于编译时的注解,待下篇博客的时候会结合例子讲解一下,目前我也正在学习当中 注解的相关知识点 提到注解,大多数人应该都不默认,在我们程序中见到的@Override,@Deprected,@SupressWarnings等等,这些都是注解,只不过是系统自己封装好的,而我们平时比较少去深入理解是怎样实现的? 1)什么是注解(Annotation): Annotation(注解)就是Java提供了一种元

android-----我眼中的Binder - 2016-07-25 18:07:17

        Binder作为进程间通信方式(IPC)的一种,算Android中比较难理解的部分了,今天计划以自己所认识的framework层的Binder原理来做个总结,好了,我们开始吧!         Android中利用Binder通信,首先肯定需要获得Binder对象了,但是系统服务和我们自定义服务Binder对象的获取方式是不一样的,原因就在于系统服务是在系统启动的时候被注册到ServiceManegr的,我们只需要通过ServiceManager.getService(String nam
使用xml作为数据交互的载体是Android中非常重要的功能,比如天气预报数据、短信备份数据、通讯录数据都可以以xml的格式通过网络传输。 为了演示Xml数据的操作,我模拟了一个短信备份的案例。 需求:界面如图1-10所示。上面是三个Button,前两个分别对应两种不同方式生成xml,第三个Button点击后解析备份的xml文件,然后将数据展现在下面的ScrollView中。短信数据是模拟的假数据。 生成的xml格式如文件1-10。 【文件1-10】 xml文件格式 1. ?xml version="1.
这篇博客我们来介绍一下责任链模式(Chain-of-responsibility Pattern),责任联模式又称为职责链模式,是 行为型设计模式 之一。顾名思义,责任链模式中存在一个链式结构,多个节点首尾相连,每个节点都可以被拆开再连接,因此,链式结构具有很好的灵活性。将这样一种结构应用于编程领域,将每一个节点看作是一个对象,每一个对象拥有不同的处理逻辑,将一个请求从链式的首段发出,沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止,这就是责任链或者职责链的通俗定义。 转载请注明出处: h

GeekBand第十一周笔记 - 2016-07-25 17:07:19

本周的主要内容介绍Gradle,NDK,管理依赖和Git等 一、Gradle Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。 面向Java应用为主。当前其支持的语言限于Java、Groovy和Scala,计划未来将支持更多的语言。 Coding只是软件开发中的一个部分 编译源代码 运行单元测试和集成测试 执行静态代码分析,生成分析报告 创建分布版本 部署到目标环