protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { super.onActivityResult(requestCode, resultCode, imageReturnedIntent); switch(requestCode) { case REQ_CODE_PICK_IMAGE: if(resultCode == RESULT_OK){ Uri selectedImage = imageReturnedIntent.getData(); String[] filePathColumn = {MediaStore.Images.Media.DATA}; Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String filePath = cursor.getString(columnIndex); cursor.close(); Bitmap yourSelectedImage = BitmapFactory.decodeFile(filePath); } } }
RunningTaskInfo
范例说明
Android操作系统并没有提供任务管理器程序,无从得知后台有哪些程序正在运行。本范例是通过ActivityManager.getRunningTasks方法来取得正在运行中的工作程序,并使用ListView将之罗列出来。
这里说的"正在运行"是指单击"按钮"时所获取到的信息,如果放在ListView里的工作已经结束,或者被操作系统回收(Garbage Collection,GC),此时是不会更新运行列表的,而由于没有其他运行中工作的访问权限,因此也不能通过本程序关闭。
在以下范例的Layout里,设计一个TextView、一个ListView以及一个按钮,通过按钮单击的事件,同时向系统ActivityManager取出正在运行的Activity Tasks。
运行结果(见图5-23)
图5-23 任务管理器正在运行的程序,包含了正在运行的Activity范例程序
在访问系统Activity的运行工作时,必须指定要取得的工作数量,因为资源有限,所以在类成员中设置了最多取出30笔的Activity运行工作。
单击按钮之后,便会使得私有类成员mActivityManager重新向系统取得ACTIVITY_SERVICE服务(getSystemService(ACTIVITY_SERVICE);),接着创建List<ActivityManager.RunningTaskInfo>对象,并在构建时,使用getRunningTasks()方法获取正在后台运行中的Activity。
由于取出的对象为List对象,因此程序通过for循环的方式,取出其ActivityManager. RunningTaskInfo里的属性,如Activity的名称(baseActivity.getClassName())及ID(Activity- Manager.RunningTaskInfo.id)。
/* import程序略 */ import android.app.ActivityManager; import android.widget.ListView; public class EX05_21 extends Activity { private Button mButton01; private ListView mListView01; private ArrayAdapter<String> aryAdapter1; private ArrayList<String> arylistTask; /* 类成员设置取回最多几笔的Task数量 */ private int intGetTastCounter = 30; /* 类成员ActivityManager对象 */ private ActivityManager mActivityManager; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mButton01 = (Button) findViewById(R.id.myButton1); mListView01 = (ListView) findViewById(R.id.myListView1); /* 单击按钮取得正在后台运行的任务程序 */ mButton01.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub try { /* ActivityManager对象向系统取得ACTIVITY_SERVICE */ mActivityManager = (ActivityManager) EX05_21.this .getSystemService(ACTIVITY_SERVICE); arylistTask = new ArrayList<String>(); /* 以getRunningTasks方法取回正在运行中的程序TaskInfo */ List<ActivityManager.RunningTaskInfo> mRunningTasks = mActivityManager .getRunningTasks(intGetTastCounter); int i = 1; /* 以循环及baseActivity方式取得任务名称与ID */ for (ActivityManager.RunningTaskInfo amTask : mRunningTasks) { /* baseActivity.getClassName取出运行任务名称 */ arylistTask.add("" + (i++) + ": " + amTask.baseActivity.getClassName() + "(ID=" + amTask.id + ")"); } aryAdapter1 = new ArrayAdapter<String>(EX05_21.this, R.layout.simple_list_item_1, arylistTask); if (aryAdapter1.getCount() == 0) { /* 当没有任何运行的任务,则提示信息 */ mMakeTextToast(getResources().getText( R.string.str_err_no_running_task).toString(), true); } else { /* 发现后台运行的任务程序,以ListView Widget条列呈现 */ mListView01.setAdapter(aryAdapter1); } } catch (SecurityException e) { /* 当无GET_TASKS权限时(SecurityException异常)提示信息 */ mMakeTextToast(getResources().getText( R.string.str_err_permission).toString(), true); } } }); /* 当User在运行任务选择时的事件处理 */ mListView01 .setOnItemSelectedListener(new ListView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View v, int id, long arg3) { // TODO Auto-generated method stub /* 由于将运行任务以数组存放,故以id取出数组元素名称 */ mMakeTextToast(arylistTask.get(id).toString(), false); } @Override public void onNothingSelected(AdapterView<?> arg0) { // TODO Auto-generated method stub } }); /* 当User在运行任务上单击时的事件处理 */ mListView01.setOnItemClickListener(new ListView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View v, int id, long arg3) { // TODO Auto-generated method stub /* 由于将运行任务以数组存放,故以id取出数组元素名称 */ mMakeTextToast(arylistTask.get(id).toString(), false); } }); } public void mMakeTextToast(String str, boolean isLong) { if (isLong == true) { Toast.makeText(EX05_21.this, str, Toast.LENGTH_LONG).show(); } else { Toast.makeText(EX05_21.this, str, Toast.LENGTH_SHORT).show(); } } }
来自:http://book.51cto.com/art/201007/212202.htm
源地址:http://blogold.chinaunix.net/u2/61880/showart_2339481.html
1引言
Android froyo版本多媒体引擎做了变动,新添加了stagefright框架,并且默认情况android选择stagefright,弃用之前的opencore,仅仅对opencore中的omx-component部分做了引用。
Stagefright
自android2.0后才添加,其稳定性有待商榷,是否存在bug也未知,opencore自android诞生起便存在,稳定性有保障。不过,从目前
android代码看,opencore有被stagefright取代的趋势,所以在opencore上所作工作也许会无法沿用。Opencore上的
开发较stagefright上要复杂耗时些。
2框架变动
以MediaPlayer为例,我们先看一下多媒体的简单框架。
上图可知,stagefright是在MediaPlayerService这一层加入的,和opencore是并列的,在选用opencore还是stagefright的代码切换上也非常容易。
具
体stagefright的内部变动,可见下图概述。Stagefright并没有完全抛弃opencore,主要是做了一个OMX层,用来引用
opencore的omx-component部分。而stagefright内部而言,与opencore是完全不同的设计。
3具体差异
3.1所支持的文件格式
Opencore所支持的格式。
Stagefright所支持的格式。
3.2 Parser和codec部分开发有差异
Opencore与stagefright
两套机制,对于我们的开发而言,主要体现在parser和codec部分。Opencore方面,必须按照其规范完成相应的parser-
node,codec则要按照omx规范实现相应的component。Stagefright方面,则要按照其规范实现相应的extractor和
decoder。
最基本的实现,二者是相同的,可以共用,差别在封装上,opencore难度和工作量要大。
3.3 数据处理机制不同
Opencore处理流程如下图示。
engine分别创建audio/video datapath,parser/dec/sink作为node节点由各自datapath连接起来,后续node节点由统一调度器调度。
Stagefright处理流程如下图示。
Audioplayer
为AwesomePlayer的成员,audioplayer通过callback来驱动数据的获取,awesomeplayer则是通过
videoevent来驱动。二者有个共性,就是数据的获取都抽象成mSource->Read()来完成,且read内部把parser和dec
绑在一起。
Opencore和stagefright处理机制对比:
(1)Opencore的parser与dec是分离的,各行其职;stagefright则是绑在一起作为一个独立的原子操作。
(2)Stagefright通过callback和videoevent来驱动数据输出;opencore是通过sink-node节点控制输出。
(3)Opencore中parser/dec/sink是并行处理的;stagefright中为串行处理。
3.4 AV同步
Opencore有一个主clock,audio/video分别与该主clock同步,作为输出的判定依据,且audio会不断校准主clock。
Stagefright部分,audio完全是callback驱动数据流,video部分在onVideoEvent里会获取audio的时间戳,是传统的AV时间戳做同步。
3.5 稳定性
客观来讲,opencore存在时间长,相对稳定;stagefright刚推出,肯定会有未预知的bug存在。
4 总结
1.Opencore相对成熟稳定,作为框架采用,风险小;parser/codec集成相对复杂,如果android后续版本弃用opencore转用stagefright,那多媒体引擎的选择是个问题。
2.Stagefright新推出,肯定有未预知的bug,直接采用有潜在风险;parser/codec集成相对容易,架构较opencore做了极大简化,通俗易懂。
3.目前来看opencore支持的文件格式多些。
4.Opencore与stagefright在数据处理机制及AV同步上有很大差异,需要在实际板子上评估性能差异。
5.如果在android froyo版本开发多媒体相关产品,建议采用opencore框架,这样旧版本opencore上的成果可以沿用,且节省项目时间。
6.Opencore支持的文件格式较stagefright丰富。
7.
如果项目研发中android出现新版本,或stagefright做了更新,仍然维持opencore不变,多媒体引擎变更问题待ipad后再议。一种
选择是一直延续采用opencore,或者在适当时候(认为stagefright足够稳定)切换到stagefright。
Stagefright阅读笔记附录
两套方案对比过程中,基本上把stagefright的代码阅读过一遍,摘录如下,以图为主。
Stagefright整体框图。
Stagefrightplayer里awesomeplayer初始化流程
Awesomeplayer框图,其中涵盖主要节点元素。
Stagefrightrecorder部分
MediaPlayer框图。
MediaRecorder框图。
Libstagefright草图,涵盖了主要节点元素。