捕获 何种按键的方法:
boolean mBackPressed = false; @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN) { switch (keyCode) { case KeyEvent.KEYCODE_BACK: mBackPressed = true; break; case KeyEvent.KEYCODE_MENU: if (mBackPressed) unLock(); break; default: mBackPressed = false; showMessage(); break; } } return true; } private void showMessage() { Toast.makeText(getBaseContext(), "Back + Menu", Toast.LENGTH_SHORT) .show(); } private void unLock() { this.setResult(Activity.RESULT_OK); this.finish(); }
上面的方法是不能捕获home。back建的,但是可以捕获大多数建,对于特殊的建 有的是不能捕获的如 endCall
有的需要其他方法如back。
如果要写一个替代 Home Screen 使用 android.intent.category.HOME Intent.
在官方文档
docs
...not all activities have the behavior that they are destroyed when BACK is pressed. When the user starts playing music in the Music application and then presses BACK, the application overrides the normal back behavior, preventing the player activity from being destroyed, and continues playing music, even though its activity is no longer visible
通常back建会是程序进入死亡状态,如果你想使程序进入stop状态而不是死亡状态,那么最好使用一个service,因为即使back建之后他还是会继续执行。用你的activity控制service就好,通常你会用到下面的代码
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { moveTaskToBack(true); return true; } return super.onKeyDown(keyCode, event); }
红色的是要加入。或者你尅一参考
http://android-developers.blogspot.com/2009/12/back-and-other-hard-keys-three-stories.html使用
@Override
public void onBackPressed() {
// do something on back.
return;
}
捕获back建
styles.xml
<style name="NewBorderDialogTheme" parent="android:Theme.Dialog"> <item name="android:windowBackground">@drawable/your_drawable/item> </style>
import android.app.AlertDialog; import android.content.Context; import android.content.res.TypedArray; import android.content.res.Resources.Theme; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; public class MyColorDialog extends AlertDialog{ private static int NONE = -1; private int tint = NONE; /** * @param context * @param theme */ protected MyColorDialog(Context context) { super(context); init(); } /** * @param context * @param theme */ protected MyColorDialog(Context context, int theme) { super(context, theme); init(); } /** * */ private void init() { final Theme theme = getContext().getTheme(); final TypedArray attrs = theme.obtainStyledAttributes(new int[] { android.R.attr.tint }); tint = attrs.getColor(0, NONE); } @Override public void show() { // TODO Auto-generated method stub super.show(); setTint(tint); } public void setTint(int tint) { // TODO Auto-generated method stub this.tint = tint; android.graphics.PorterDuff.Mode mode = PorterDuff.Mode.SRC_ATOP; final Drawable d = this.getWindow().getDecorView().getBackground(); d.mutate().setColorFilter(tint, mode); } /** * @param button */ public void setCancelButton(Button button) { button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { cancel(); } }); } /** * @param button */ public void setPositiveButton(Button button) { button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismiss(); } }); } public static class Builder extends AlertDialog.Builder { private MyColorDialog dialog; public Builder(Context context) { super(context); dialog = new MyColorDialog(context); } public Builder(Context context, int theme) { super(context); dialog = new MyColorDialog(context, theme); } @Override public MyColorDialog create() { return dialog; } @Override public Builder setMessage(CharSequence message) { dialog.setMessage(message); return this; } @Override public Builder setTitle(CharSequence title) { dialog.setTitle(title); return this; } @Override public Builder setPositiveButton(CharSequence text, OnClickListener listener) { dialog.setButton(BUTTON_POSITIVE, text, listener); return this; } @Override public Builder setIcon(int iconId) { dialog.setIcon(iconId); return this; } } }
使用
new MyColorDialog.Builder(this, R.style.OrangeDialogTheme).setPositiveButton("Dismiss", null).setTitle("Warning").setMessage("adhuhfdu").create().show();
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="red_tint">#88FF0000</color> <color name="blue_tint">#880000FF</color> <color name="yellow_tint">#88FFFF00</color> <color name="purple_tint">#88995f86</color> <color name="orange_tint">#aaffbf00</color> <color name="magenta_tint">#88ff33cc</color> <color name="transparent">#0000</color> </resources>
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- Orange --> <style name="OrangeDialogTheme" parent="@android:style/Theme.Dialog"> <item name="android:tint">@color/orange_tint</item> <item name="android:windowBackground">@color/orange_tint</item> </style> <style name="OrangeAlertDialogTheme" parent="OrangeDialogTheme"> <item name="android:windowBackground">@color/transparent</item> </style> <!-- Red --> <style name="RedDialogTheme" parent="@android:style/Theme.Dialog"> <item name="android:tint">@color/red_tint</item> </style> <style name="RedAlertDialogTheme" parent="RedDialogTheme"> <item name="android:windowBackground">@color/magenta_tint</item> </style> </resources>
ve555代码解读之二:DESCRIBE请求消息处理过程
RTSP服务器收到客户端的DESCRIBE请求后,根据请求URL(rtsp://192.168.1.109/1.mpg),找到对应的流媒体资源,返回响应消息。live555中的ServerMediaSession类用来处理会话中描述,它包含多个(音频或视频)的子会话描述 (ServerMediaSubsession)。
上节我们谈到RTSP服务器收到客户端的连接请求,建立了RTSPClientSession类,处理单独的客户会话。在建立 RTSPClientSession的过程中,将新建立的socket句柄(clientSocket)和RTSP请求处理函数句柄 RTSPClientSession::incomingRequestHandler传给任务调度器,由任务调度器对两者进行一对一关联。当客户端发出 RTSP请求后,服务器主循环中的select调用返回,根据socket句柄找到对应的incomingRequestHandler,开始消息处理。先进行消息的解析,如果发现请求是DESCRIBE则进入handleCmd_DESCRIBE函数。根据客户端请求URL的后缀(例如是1.mpg), 调用成员函数DynamicRTSPServer::lookupServerMediaSession查找对应的流媒体信息 ServerMediaSession。如果ServerMediaSession不存在,但是本地存在1.mpg文件,则创建一个新的 ServerMediaSession。在创建ServerMediaSession过程中,根据文件后缀.mpg,创建媒体MPEG-1or2的解复用器(MPEG1or2FileServerDemux)。再由MPEG1or2FileServerDemux创建一个子会话描述 MPEG1or2DemuxedServerMediaSubsession。最后由ServerMediaSession完成组装响应消息中的SDP信息(SDP组装过程见下面的描述),然后将响应消息发给客户端,完成一次消息交互。
SDP消息组装过程:
ServerMediaSession负责产生会话公共描述信息,子会话描述由 MPEG1or2DemuxedServerMediaSubsession产生。 MPEG1or2DemuxedServerMediaSubsession在其父类成员函数 OnDemandServerMediaSubsession::sdpLines()中生成会话描述信息。在sdpLines()实现里面,创建一个虚构(dummy)的FramedSource(具体实现类为MPEG1or2AudioStreamFramer和 MPEG1or2VideoStreamFramer)和RTPSink(具体实现类为MPEG1or2AudioRTPSink和 MPEG1or2VideoRTPSink),最后调用setSDPLinesFromRTPSink(...)成员函数生成子会话描述。
以上涉及到的类以及继承关系:
Medium <- ServerMediaSession
Medium <- ServerMediaSubsession <- OnDemandServerMediaSubsession <- MPEG1or2DemuxedServerMediaSubsession
Medium <- MediaSource <- FramedSouse <- FramedFileSource <- ByteStreamFileSource
Medium <- MediaSource <- FramedSouse <- MPEG1or2DemuxedElementaryStream
Medium <- MPEG1or2FileServerDemux
Medium <- MPEG1or2Demux
Medium <- MediaSource <- FramedSouse <- MPEG1or2DemuxedElementaryStream
Medium <- MediaSource <- FramedSouse <- FramedFilter <- MPEGVideoStreamFramer <- MPEG1or2VideoStreamFramer
Medium <- MediaSink <- RTPSink <- MultiFramedRTPSink <- VideoRTPSink <- MPEG1or2VideoRTPSink