康洪涛博客实盘操作广播收藏打印如何操作

18921人阅读
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 转载请注明出处:
&&&&&&&&&& &在Android中并没有定义MediaButtonReceive这个广播类,MediaButtonReceive只是作为一种通俗的命名方式来响应
&& 插入耳机后,点击耳机上的按钮()接受该广播事件的类。所有该MEDIA_BUTTON的按下我们就简称
&& 为MEDIA_BUTTON广播吧。
&&&&&&&&&&&
&&&&&&&&&& 顾名思义:它显然是一个广播接收器类(BroadbcastReceiver),那么它就具备了BroadbcastReceiver类的使用方式,
&& 但是,因为它需要通过AudioManager对象注册,所以它有着自己的独特之处(否则我也不会单独拿出来分析,- -),后面我们
&&&会慢慢的讲解。
&&&&&&& 点击MEDIA_BUTTON发送的Intent Action 为:
&&&&&&&&&&&&&&&&&&&& & &ACTION_MEDIA_BUTTON& =&&
&&&&&&&&Intent 附加值为(Extra)点击MEDIA_BUTTON的按键码&:&&&&
&&&&&&&&&&&&&&&&&&&&&&& //获得KeyEvent对象
&&&&&&&&&&&&&&&&&&&&&&&
KeyEvent keyEvent = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
&&&&&&&&&&&&&&&&&&&&& & //获得Action
&&&&&&&&&&&&&&&&&&& &&&
String intentAction = intent.getAction() ;
AudioManager对象注册MEDIA_BUTTON广播的方法原型为:
&&&public voidregisterMediaButtonEventReceiver(r)
&&&&&&&&& Register a component to be the sole receiverof MEDIA_BUTTON intents
&&&&&&&&&&Parameters:&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
eventReceiver& : identifier of a BroadcastReceiver that will receive the media button intent. This broadcast receiver
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& must be
declared in the application manifest.
&& 从注释可知以下两点:
&&&&&&1、&在AudioManager对象注册一个MediaoButtonRecevie,使它成为MEDIA_BUTTON的唯一接收器(这很重要,
&&&&&&&&&&我们会放在后面讲解)&& 也就是说只有我能收到,其他的都收不到这个广播了,否则的话大家都收到会照成一定的混乱;
&&&&& 2、& &该广播必须在AndroidManifest.xml文件中进行声明,否则就监听不到该MEDIA_BUTTON广播了。
下面我们就简单的写一个MediaButtonReceiver类,并且在AndroidManifest.xml定义
1、& 自定义的MediaButtonReceiver 广播类
package com.qin.
import android.content.BroadcastR
import android.content.C
import android.content.I
import android.util.L
import android.view.KeyE
public class MediaButtonReceiver extends BroadcastReceiver {
private static String TAG = &MediaButtonReceiver&;
public void onReceive(Context context, Intent intent) {
// 获得Action
String intentAction = intent.getAction();
// 获得KeyEvent对象
KeyEvent keyEvent = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
Log.i(TAG, &Action ----&& + intentAction + &
KeyEvent-----&&+ keyEvent.toString());
if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
// 获得按键字节码
int keyCode = keyEvent.getKeyCode();
// 按下 / 松开 按钮
int keyAction = keyEvent.getAction();
// 获得事件的时间
long downtime = keyEvent.getEventTime();
// 获取按键码 keyCode
StringBuilder sb = new StringBuilder();
// 这些都是可能的按键码 , 打印出来用户按下的键
if (KeyEvent.KEYCODE_MEDIA_NEXT == keyCode) {
sb.append(&KEYCODE_MEDIA_NEXT&);
// 说明:当我们按下MEDIA_BUTTON中间按钮时,实际出发的是 KEYCODE_HEADSETHOOK 而不是
// KEYCODE_MEDIA_PLAY_PAUSE
if (KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE == keyCode) {
sb.append(&KEYCODE_MEDIA_PLAY_PAUSE&);
if (KeyEvent.KEYCODE_HEADSETHOOK == keyCode) {
sb.append(&KEYCODE_HEADSETHOOK&);
if (KeyEvent.KEYCODE_MEDIA_PREVIOUS == keyCode) {
sb.append(&KEYCODE_MEDIA_PREVIOUS&);
if (KeyEvent.KEYCODE_MEDIA_STOP == keyCode) {
sb.append(&KEYCODE_MEDIA_STOP&);
// 输出点击的按键码
Log.i(TAG, sb.toString());
& 2、& 在AndroidManifest.xml声明我们定义的广播类。
&receiver android:name=&MediaButtonReceiver&&
&intent-filter &
&action android:name=&android.intent.action.MEDIA_BUTTON&&&/action&
&/intent-filter&
&/receiver&
&&&&&&& &在模拟器上,我们可以手动构造MEDA_BUTTON的广播,并且将它发送出去(后面会介绍)。
&&&&& && 如果有真机测试的话,按下MEDIA_BUTTON是可以接受到MEDIA_BUTTON广播的,如果没有接受到,请关闭所有应用
&& 程序,在观察效果。
& 继续我们的下一步分析:
&&&&&& & 前面我们说明通过registerMediaButtonEventReceiver(eventReceiver)方法注册时,使它成为MEDIA_BUTTON的
&&&& 唯一&接收器。这个唯一是怎么实现的呢?
我们在源码中,一步步追本溯源,相信一定可以找到答案,知道这“唯一“是
&&& 怎么来的。
第一步、&& 为AudioManager注册一个MediaButtonReceiver() ;
//获得AudioManager对象
AudioManager mAudioManager =(AudioManager)getSystemService(Context.AUDIO_SERVICE);
//构造一个ComponentName,指向MediaoButtonReceiver类
//下面为了叙述方便,我直接使用ComponentName类来替代MediaoButtonReceiver类
ComponentName
mbCN = new ComponentName(getPackageName(),MediaButtonReceiver.class.getName());
//注册一个MedioButtonReceiver广播监听
mAudioManager.registerMediaButtonEventReceiver(mbCN);
//取消注册的方法
mAudioManager.unregisterMediaButtonEventReceiver(mbCN);
&&&&&& &MediaButtonReceiver就是我们用来接收MEDIA_BUTTON的广播类,下面为了叙述方便和直观上得体验,我直接使用
&&& ComponentName类来替代真正的MediaoButtonReceiver广播类。
&& 说明 接下来分析的文件路径全部在&& frameworks/base/media/java/android/media/ 下
&第二步、&进入AudioManager.java进行查看 ,发现如下方法:
//注册的方法为:
public void registerMediaButtonEventReceiver(ComponentName eventReceiver) {
//TODO enforce the rule about the receiver being declared in the manifest
//我们继续查看getService()方法,看看IAudioService类到底是什么?
IAudioService service = getService();
//只是简单的调用了service的方法来完成注册,继续跟踪
service.registerMediaButtonEventReceiver(eventReceiver);
} catch (RemoteException e) {
Log.e(TAG, &Dead object in registerMediaButtonEventReceiver&+e);
//取消注册的方法为
public void unregisterMediaButtonEventReceiver(ComponentName eventReceiver) {
IAudioService service = getService();
//只是简单的调用了service的方法来取消注册,,继续跟踪
service.unregisterMediaButtonEventReceiver(eventReceiver);
} catch (RemoteException e) {
Log.e(TAG, &Dead object in unregisterMediaButtonEventReceiver&+e);
& 找到getService()方法,其实现为:
//看看它到底是什么
private static IAudioService getService()
// 单例模式,大家懂得
if (sService != null) {
//了解Binder机制 以及AIDL文件的使用,就明白了这不过是通过AIDL文件定义的Java层Binder机制
//b为IBinder基类接口
IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
//强制转换后,sService不过是一个客户端对象,IAudioService就是aidl文件定义的接口了
sService = IAudioService.Stub.asInterface(b);
//sService对象的声明
private static IAudioService sS //单例模式,不足为奇了
&&&&&&&& 我们知道了AudiaoManager只不过是一个傀儡,所有的方法都是由IAudioService 对象去实现的,通过它的构造方式,
&&可以知道它应该是有AIDL文件形成的Binder机制,&sService只是客户端对象,那么它的服务端对象在什么地方呢?
&&也就是继承了IAudioService.Stub桩的类。
第三步、接下来我们需要找到该IAudioService.aidl文件和真正的服务端对象&&
&& IAudioService.aidl定义如下:
package android.
import ponentN
import android.media.IAudioFocusD
interface IAudioService {
void adjustVolume(int direction, int flags);
void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags);
void adjustStreamVolume(int streamType, int direction, int flags);
void setStreamVolume(int streamType, int index, int flags);
void setStreamSolo(int streamType, boolean state, IBinder cb);
void setStreamMute(int streamType, boolean state, IBinder cb);
int getStreamVolume(int streamType);
int getStreamMaxVolume(int streamType);
void setRingerMode(int ringerMode);
int getRingerMode();
void setVibrateSetting(int vibrateType, int vibrateSetting);
int getVibrateSetting(int vibrateType);
boolean shouldVibrate(int vibrateType);
void setMode(int mode, IBinder cb);
int getMode();
oneway void playSoundEffect(int effectType);
oneway void playSoundEffectVolume(int effectType, float volume);
boolean loadSoundEffects();
oneway void unloadSoundEffects();
oneway void reloadAudioSettings();
void setSpeakerphoneOn(boolean on);
boolean isSpeakerphoneOn();
void setBluetoothScoOn(boolean on);
boolean isBluetoothScoOn();
int requestAudioFocus(int mainStreamType, int durationHint, IBinder cb, IAudioFocusDispatcher l, String clientId);
int abandonAudioFocus(IAudioFocusDispatcher l, String clientId);
void unregisterAudioFocusClient(String clientId);
void registerMediaButtonEventReceiver(in ComponentName eventReceiver);
//这个方法是我们需要弄懂的
void unregisterMediaButtonEventReceiver(in ComponentName eventReceiver);
//这个方法也是是我们需要弄懂的
void startBluetoothSco(IBinder cb);
void stopBluetoothSco(IBinder cb);
&&&& & 真正的服务端对象就是继承了 IAudioService.Stub 桩的类,AudioService就是该服务端对象,其实AudioManager的
&&所有操作都是由AudioService来实现的,它才是真正的老大。
第五步、&& AudioService.java
//AudioService类
public class AudioService extends IAudioService.Stub {
//仅仅列出我们需要的方法
//这儿才是真正的注册MediaButtonReceiver的方法
public void registerMediaButtonEventReceiver(ComponentName eventReceiver) {
Log.i(TAG, &
Remote Control
registerMediaButtonEventReceiver() for & + eventReceiver);
synchronized(mRCStack) {
//调用它去实现注册ComponentName
pushMediaButtonReceiver(eventReceiver);
//在查看pushMediaButtonReceiver()方法
先理解一下两个知识点,很重要的。
//RemoteControlStackEntry内部类不过是对ComponentName类的进一步封装(感觉没必要在加一层进行封装了)
private static class RemoteControlStackEntry {
public ComponentName mReceiverC// 属性
//TODO implement registration expiration?
//public int mRegistrationT
public RemoteControlStackEntry() {
public RemoteControlStackEntry(ComponentName r) {
mReceiverComponent =// 构造函数赋值给mReceiverComponent对象
//采用了栈存储结构(先进后出)来保存所有RemoteControlStackEntry对象,也就是保存了ComponentName对象
private Stack&RemoteControlStackEntry& mRCStack = new Stack&RemoteControlStackEntry&();
//回到pushMediaButtonReceiver()查看,这下该拨开云雾了吧,继续学习
private void pushMediaButtonReceiver(ComponentName newReceiver) {
// already at top of stack?
//采用了一个栈(前面我们介绍的知识点)来保存所有注册的ComponentName对象
//如果当前栈不为空并且栈顶的对象与新注册的ComponentName对象一样,不做任何事,直接返回
if (!mRCStack.empty() && mRCStack.peek().mReceiverComponent.equals(newReceiver)) {
//获得mRCStack栈的迭代器
Iterator&RemoteControlStackEntry& stackIterator = mRCStack.iterator();
while(stackIterator.hasNext()) {
RemoteControlStackEntry rcse = (RemoteControlStackEntry)stackIterator.next();
//如果当前栈内保存该新注册的ComponentName对象,将它移除,跳出循环
if(rcse.mReceiverComponent.equals(newReceiver)) {
mRCStack.remove(rcse);
//将新注册的ComponentName对象放入栈顶
mRCStack.push(new RemoteControlStackEntry(newReceiver));
小结一下:&
&&&&&&&& 栈(mRCStack)维护了所有CompoentName对象,对每个CompoentName对象,保证它有且仅有一个,
&&&& 新注册的CompoentName对象永远处于栈顶&&&&
&我们看下取消注册的方法:
//我们看下取消注册的方法
/** see AudioManager.unregisterMediaButtonEventReceiver(ComponentName eventReceiver) */
public void unregisterMediaButtonEventReceiver(ComponentName eventReceiver) {
Log.i(TAG, &
Remote Control
unregisterMediaButtonEventReceiver() for & + eventReceiver);
synchronized(mRCStack) {
//调用removeMediaButtonReceiver方法去实现
removeMediaButtonReceiver(eventReceiver);
private void removeMediaButtonReceiver(ComponentName newReceiver) {
Iterator&RemoteControlStackEntry& stackIterator = mRCStack.iterator();
while(stackIterator.hasNext()) {
//获得mRCStack栈的迭代器
RemoteControlStackEntry rcse = (RemoteControlStackEntry)stackIterator.next();
//如果存在该对象,则移除,跳出循环
if(rcse.mReceiverComponent.equals(newReceiver)) {
mRCStack.remove(rcse);
&& &&&& &&通过对前面的学习,我们知道了AudioManager内部利用一个栈来管理包括加入和移除ComponentName对象,
&&& 新的疑问来了?这个MEDIA_BUTTON广播是如何分发的呢 ?
&&&&&&&& 其实,AudioService.java文件中也存在这么一个MediaoButtonReceiver的广播类,它为系统广播接收器,即用来接收
& 系统的MEDIA_BUTTON广播,当它接收到了这个MEDIA_BUTTON广播&&&,它会对这个广播进行进一步处理,这个处理过程
&& 就是我们需要的弄清楚。
MediaButtonBroadcastReceiver 内部类如下:
private class MediaButtonBroadcastReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
//获得action ,系统MEDIA_BUTTON广播来了
String action = intent.getAction();
//action不正确 直接返回
if (!Intent.ACTION_MEDIA_BUTTON.equals(action)) {
//获得KeyEvent对象
KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (event != null) {
// if in a call or ringing, do not break the current phone app behavior
// TODO modify this to let the phone app specifically get the RC focus
add modify the phone app to take advantage of the new API
//来电或通话中,不做处理直接返回
if ((getMode() == AudioSystem.MODE_IN_CALL) ||(getMode() == AudioSystem.MODE_RINGTONE)) {
synchronized(mRCStack) {
//栈不为空
if (!mRCStack.empty()) {
// create a new intent specifically aimed at the current registered listener
//构造一个Intent对象 ,并且赋予Action和KeyEvent
Intent targetedIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
targetedIntent.putExtras(intent.getExtras());
//指定该处理Intent的对象为栈顶ComponentName对象的广播类
targetedIntent.setComponent(mRCStack.peek().mReceiverComponent);
// trap the current broadcast
// 终止系统广播
abortBroadcast();
//Log.v(TAG, & Sending intent& + targetedIntent);
//手动发送该广播至目标对象去处理,该广播不再是系统发送的了
context.sendBroadcast(targetedIntent, null);
//假设栈为空,那么所有定义在AndroidManifest.xml的监听MEDIA_BUTTON的广播都会处理,
//在此过程中如果有任何应用程注册了registerMediaButton 该广播也会立即终止
&总结一下MEDIA_BUTTON广播:&
&&&&& &&&AudioManager也就是AudioService服务端对象内部会利用一个栈来管理所有ComponentName对象,所有对象有且仅有一个,
&& 新注册的ComponentName总是会位于栈顶。
&&&&&&&& 当系统发送MEDIA_BUTTON,系统MediaButtonBroadcastReceiver 监听到系统广播,它会做如下处理:
&&&&&&&&&&&&&&&&&1、&如果栈为空,则所有注册了该Action的广播都会接受到,因为它是由系统发送的。
&&&&&&&&&&&&&&&&&2、&如果栈不为空,那么只有栈顶的那个广播能接受到MEDIA_BUTTON的广播,手动发送了MEDIA_BUTTON
&&&&&&&&&&&&&&&&&&&&&&广播,并且指定了目标对象(栈顶对象)去处理该MEDIA_BUTTON 。
&下面分析一下KeyEvent对象里的KeyCode按键,可能的按键码有:
&&&&&& 1、KeyEvent.KEYCODE_MEDIA_NEXT
&&&&&& 2、KeyEvent.KEYCODE_HEADSETHOOK
&&&&&& 3、KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE(已废除,等同于KEYCODE_HEADSETHOOK)
&&&&&& 4、KeyEvent.KEYCODE_MEDIA_PREVIOUS
&&&&&& 5、KeyEvent.KEYCODE_MEDIA_STOP
&&& PS : 在我的真机测试中,按下MEDIA_BUTTON只有KEYCODE_HEADSETHOOK可以打印出来了。
下面给出一个小DEMO检验一下我们之前所做的一切,看看MEDIA_BUTTON是如何处理分发广播的。
&& 编写两个MediaButtonReceiver类用来监听MEDIA_BUTTON广播:
& 1 、China_MBReceiver.java
package com.qin.
import android.content.BroadcastR
import android.content.C
import android.content.I
import android.util.L
import android.view.KeyE
public class China_MBReceiver extends BroadcastReceiver
private static String TAG = &China_MBReceiver& ;
public void onReceive(Context context, Intent intent) {
//获得Action
String intentAction = intent.getAction() ;
//获得KeyEvent对象
KeyEvent keyEvent = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
Log.i(TAG, &Action ----&&+intentAction + &
KeyEvent-----&&+keyEvent.toString());
if(Intent.ACTION_MEDIA_BUTTON.equals(intentAction)){
//获得按键字节码
int keyCode = keyEvent.getKeyCode() ;
//按下 / 松开 按钮
int keyAction = keyEvent.getAction() ;
//获得事件的时间
long downtime = keyEvent.getEventTime();
//获取按键码 keyCode
StringBuilder sb = new StringBuilder();
//这些都是可能的按键码 , 打印出来用户按下的键
if(KeyEvent.KEYCODE_MEDIA_NEXT == keyCode){
sb.append(&KEYCODE_MEDIA_NEXT&);
//说明:当我们按下MEDIA_BUTTON中间按钮时,实际出发的是 KEYCODE_HEADSETHOOK 而不是 KEYCODE_MEDIA_PLAY_PAUSE
if(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE ==keyCode){
sb.append(&KEYCODE_MEDIA_PLAY_PAUSE&);
if(KeyEvent.KEYCODE_HEADSETHOOK == keyCode){
sb.append(&KEYCODE_HEADSETHOOK&);
if(KeyEvent.KEYCODE_MEDIA_PREVIOUS ==keyCode){
sb.append(&KEYCODE_MEDIA_PREVIOUS&);
if(KeyEvent.KEYCODE_MEDIA_STOP ==keyCode){
sb.append(&KEYCODE_MEDIA_STOP&);
//输出点击的按键码
Log.i(TAG, sb.toString());
&& 2 、England_MBReceiver.java同于China_MBRreceiver ,打印Log TAG= &England_MBReceiver&
&& 3、在AndroidManifest.xml文件定义:
&receiver android:name=&.China_MBReceiver&&
&intent-filter &
&action android:name=&android.intent.action.MEDIA_BUTTON&&&/action&
&/intent-filter&
&/receiver&
&receiver android:name=&.Enaland_MBReceiver&&
&intent-filter &
&action android:name=&android.intent.action.MEDIA_BUTTON&&&/action&
&/intent-filter&
&/receiver&
4、MainActivity .java 我们通过手动构造一个MEDIA_BUTTON广播去查看我们的MediaButtonReceiver类的打印信息。
package com.qin.
import android.app.A
import ponentN
import android.content.C
import android.content.I
import android.media.AudioM
import android.os.B
import android.view.KeyE
public class MainActivity extends Activity {
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//由于在模拟器上测试,我们手动发送一个MEDIA_BUTTON的广播,有真机更好处理了
Intent mbIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
//构造一个KeyEvent对象
KeyEvent keyEvent = new KeyEvent (KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_HEADSETHOOK) ;
//作为附加值添加至mbIntent对象中
mbIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
//此时China_MBReceiver和England_MBReceiver都会接收到该广播
sendBroadcast(mbIntent);
AudioManager mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
//AudioManager注册一个MediaButton对象
ComponentName chinaCN = new ComponentName(getPackageName(),China_MBReceiver.class.getName());
//只有China_MBReceiver能够接收到了,它是出于栈顶的。
//不过,在模拟上检测不到这个效果,因为这个广播是我们发送的,流程不是我们在上面介绍的。
mAudioManager.registerMediaButtonEventReceiver(chinaCN);
//sendBroadcast(mbIntent,null);
//当一个Activity/Service死去时,我们需要取消这个MediaoButtonReceiver的注册,如下
protected void onDestroy(){
super.onDestroy() ;
AudioManager mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
ComponentName chinaCN = new ComponentName(getPackageName(),China_MBReceiver.class.getName());
//取消注册
mAudioManager.unregisterMediaButtonEventReceiver(chinaCN);
& &&&& 值得注意的一点时,当我们为一个应用程序注册了MediaoButtonReceiver时,在程序离开时,我们需要取消该
& MediaoButtonReceiver的注册,在onDestroy()调用unregisterMediaButtonEventReceiver()方法就OK,这样应用程序之间
& 的交互就更具逻辑性了。
版权声明:本文为博主原创文章,未经博主允许不得转载。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1352637次
积分:9208
积分:9208
排名:第874名
原创:43篇
评论:1006条
本文博客欢迎转载, 请保留出处。谢谢合作
Android爱好者QQ群: , 希望热爱武汉Android同胞能够加入。
文章:10篇
阅读:566288
文章:17篇
阅读:470070
(1)(1)(1)(1)(1)(2)(4)(1)(4)(3)(4)(4)(2)(4)(6)(2)(2)(3)国内 (74篇)
国外 (354篇)
[澳大利亚]
[澳大利亚]
[澳大利亚]
[澳大利亚]
[澳大利亚]
(157)(125)(21)(51)(52)(27)(118)(11)(20)(12)(8)(2)(2)
3CW澳大利亚中文广播电台中波AM1341,澳大利亚东部时间晚上八点至九点,周一的夜晚,我们将彼此陪伴,在电波中共同度过一个美好的夜晚。
这个周末的时候我收到这样的一则小故事。
我不知道该怎么表达此刻的心情!我没想到我无意中对老人的一次帮助却使我的内心有了很大的震撼!我有一个小职业,就是卖一些电脑小配件。而我想要表达的这件事情的起因是一位80多岁的老人买了我出售的配件而在她把东西买回家之后,她却在使用中遇到了问题,之后她不能让她的打印机正常工作,她来向我寻求上门帮助。说实在的,我的时间其实也排得很满,但是我看着老人颤颤巍巍的身影,充满期待的眼神和满头的银发,我实在不忍拒绝。于是我答应了找时间去她家帮助她调试她的打印机。去了她家,我看到的是一个安安静静整整齐齐的澳洲老人家庭。不知为什么,在我走进她的家之后,我突然仿佛看到了我自己老了以后在澳洲的生活。接下来我检查了她的打印机,一切正常,测试页打印色彩也正常。我得出结论,问题是出在她和她丈夫不会正确使用这些多功能的打印机。老人跟我说,她女儿送给她这台打印机的时候跟她说过这是一台很方便使用的打印机,而女儿和她的孩子们却没有耐心教
生活中每时每刻都会有意想不到的事情发生,这些意想不到的事情很多时候让人生气,也让人措手不及。在今天节目之前,我收到这样一个邮件,就在昨天,一个普通的家庭,发生了一件普通的事情,也引起了普通的结果。这封邮件陈述的事情是这样的:
&昨天我和老公为了简单的一件事情吵了起来,事情非常简单,就是因为我找一个杯子找不到,而我老公说他前两天看见朋友带孩子来家玩的时候,朋友的两个孩子抢着我的杯子到处跑,我就随口说了一句,孩子真讨厌。原想老公会顺着我,或者至少不
打完激烈的怪物猎人,打开一听青岛,点开电脑里的QQ音乐,heartbreak小提琴曲幽幽的响起。瞬间,灵魂震颤了一下,赶紧用铃木常吉温暖的大叔声来缓解。Heartbreak是我在母亲丧礼期间我用来把耳朵从无限循环的哀乐里拯救出来的神曲,在杭州这个半陌生的城市的夜里听来竞有些不堪承受之轻。
杭州是父母一直想旧地重游的城市。
想当年,大学毕业,意气风发,在杭州,年轻的父母约定终身。是以杭州对他们有着特殊的意义。之前有次长假我们曾计划杭州之行,终因畏惧拥挤的人潮而作罢。现在想起,那是母亲最后的一次机会了。不过我从不觉得多年后的旧地重游会有多好,这多半只会摧毁美好的回忆而已。物不似,人亦非,不是商业化覆盖了过去就是破败的景象毁灭了经年的美好回忆,连伤感的味道都无法诗意。
其实脑海中对过去的补完更好一些。现在我就可以想象着多年之前,父亲怀揣着太湖饼干,在西湖边轻奏一曲莫斯科郊外的晚上。母亲一定是满足的吧,带着一些的惶恐。
是的,惶恐。自幼失去父母使得母亲对一切的幸福都极不自信。也许,巨蟹座的危机感也是个内因吧。她总是小心翼翼地守护着身边微小的幸福,比如我们。生养我们四个孩子对他们是巨大的
我的妈妈很爱写字,可是在她有生之年,一直默默无闻,她并没能得到时间和机会,来向世人展示她的才华,直到她去世前的那一年,她才在我们的鼓励下,写下七篇文字,妈妈说,这些文字属于有感而发。
在妈妈陆陆续续写出那七篇文字之后,爸爸总是那些文字的第一个读者,而我,则是极力推崇并积极制作的那一个。感谢我的职业,因为我是一个广播人,使得我在发现和得到妈妈的文学创作之后,有机会和能力,把这些文字用情朗读,并用心配上精美的背景音乐和相得益彰的歌曲,在电台的节目中播放。
去年的这个月 我失去了我生命里最重要的人
她给了我生命 如果没有她 就不会有我
小的时候 日子不宽裕 但是每一年到了这个月 我都特别期盼
期盼我可以从她手中 拿到一个象征我特殊意义的鸡蛋
在我有了一些能力之后 每一年的这个月 我还是很期盼
期盼能在这一天送她一束花 为她做些什么
一直到去年 这个月的到来 让我悲痛欲绝
一切太突然 让我来不及反应 我失去了她
我觉得从那以后一年中的这个月对我不再有意义了
我给自己很多理由 不断地逃避
其实今天 我真的不知道该怎样去面对
直到无意中听到上课前一个孩子跟我说 今天是她生日
我随口说了一句 你的生日 和我一样
于是 世界在孩子们单纯的眼神里 变了
在孩子们拍着手唱生日歌的时候 我感觉幸福和美好
收到的来自家长的鲜花 和孩子可爱至极的小礼物
一切的一切 大面积在修补我的穿了孔的心
我想 也许这是我的妈妈在用一种特别的方式帮助我
她一定是想告诉我 其实 任何一个妈妈 都只会在一种状态下才有可能获得快乐
此刻 坐在午后温暖的阳光下
我对着蔚蓝的 没有一丝杂质的天空
呼喊这个在
是年龄的增长,在新年过后,突然很多感悟,感悟人生,感悟心情,感悟每一首听到的歌曲,并且,对于从前那些熟悉的歌曲,如今重新再来听过的时候,有了很多新的感悟。无意之中,发现自己开始真正从现在我们对待事物越来越从容的态度中,感悟到了青春的逝去,于是,不免为那些从前的风风雨雨,从前的心碎迷离而感伤。原来,青春真的留不住。
最近大家都沉浸在各种活动和节日的气氛中,当然欢喜的日子里,肯定也会有很多新的婚姻诞生。上周,我的一个朋友要嫁人了,婚礼前,我们聚了一次,和她聊天時聊到婚后的生活,她说,结婚后,因为种种原因,她必须離開原本的生活環境及工作单位,她觉得很不舍,爱情虽然美好,但是为了爱情,必须离开父母,离开朋友,离开熟悉的环境,离开自己好不容易得到的原来的工作岗位,因为住得太远,她说,每次自己想到这些,都很难过,感觉选择了婚姻,就需要放弃很多,牺牲很多,也许以后为了家庭为了孩子,还需要不断地牺牲和放弃,然后她问我,你觉得我这样的情况,为了婚姻而做出的牺牲,到底值不值得。
我想了一下,我對这件事的想法是,一定不可以把它仅仅看做是牺牲。其实,婚后会面对和发生的很多变化,它可以說是犧牲,也可以說是一種選擇。
祥马结束奔忙,吉羊粉墨登场。转眼又是新春,祝福的话还是要送上:愿您羊年精彩开场,一年幸福安康;月月收入增长,天天心情舒畅;时时喜气洋洋,分秒如意吉祥!&
今天是中国新年的第二天 大年初二,首先要给大家拜个年,祝您羊年开门大吉 羊年万事如意!
开开心心羊年到,句句话儿吉祥绕,身体健康疾病跑,能吃能喝又能跳。夫妻和睦开颜笑,家庭美满无烦恼。事业顺利步步高,带领全家走上阳关道。祝大家羊年快乐欢笑!
今天是中国新年之前的最后一天俗称大年夜,在今晚的节目开始之前,首先要和大家说一声羊年快乐!
和往常一样的片花,在今晚却那么强烈地勾起一种浓浓的思乡情绪,让我的眼前似乎能看到大家在不同的心情和状态中非常相似的心情,此刻您是否已经做好丰盛的年夜饭,准备和家人朋友们一起分享呢?此刻您是否手里拿着电话,准备给远在中国的父母家人打个拜年电话送出您的祝福呢?也或许,此刻您是孤身一人,虽然感受着新年的气氛,却同时从心底升起许
席慕容说,
同样的时间,感谢您的守候,感谢您在今晚的这个时间和我一起,分享一天,或者是一周,也抑或是一年的感受。又是一个周一,又是一周的开始,回顾一下这个周末,大家过}

我要回帖

更多关于 uv打印机 新浪博客 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信