Android基础之——startActivityForResult启动界面并返回数据,上传头像

简介:


在android应用的开发过程中,经常会出现启动一个界面后填写部分内容后带着数据返回启动前的界面,最典型的应用就是登录过程。在很多应用程序的模块中,都有“我的”这个模块,在未登录状态下点击其中的某一项,就会弹出登录界面,登录完成后回到我的界面,会显示一些登录后的数据,这个功能的实现就要用到startActivityForResult.

下面通过一个小demo来说明一下startActivityForResult的使用,以及在实际开发中的一些应用。

demo的效果图如下:

主界面布局:

三个按钮,一个textview

<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_a"   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:layout_marginLeft="20dip"   android:layout_marginTop="20dip"   android:text="启动A界面并返回数据" />  <Button   android:id="@+id/btn_b"   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:layout_marginLeft="20dip"   android:layout_marginTop="20dip"   android:text="启动B界面" />  <LinearLayout   android:layout_width="match_parent"   android:layout_height="wrap_content"   android:layout_margin="20dip"   android:orientation="horizontal" >   <Button    android:id="@+id/btn_login"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:text="登录" />     <Button    android:id="@+id/btn_logout"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:visibility="gone"    android:text="注销"    />  </LinearLayout>  <TextView   android:id="@+id/tv_content"   android:layout_width="match_parent"   android:layout_height="30dip"   android:layout_marginLeft="20dip"   android:layout_marginRight="20dip"   android:layout_marginTop="20dip" /> </LinearLayout>

主界面java代码

public void onClick(View v) {
    Intent intent ;
   // TODO Auto-generated method stub   switch (v.getId()) {   case R.id.btn_a:    intent = new Intent(MainActivity.this, ActivityA.class);    intent.putExtra("data", "传递给A的数据");    startActivityForResult(intent, A);    break;   case R.id.btn_b:    intent = new Intent(MainActivity.this, ActivityB.class);    intent.putExtra("data", "传递给B的数据");    startActivity(intent);    break;   case R.id.btn_login:    intent = new Intent(MainActivity.this,LoginActivity.class);    intent.putExtra("data", "传递给登录界面的数据");    startActivityForResult(intent, LOGIN);    break;   case R.id.btn_logout:    btnLogin.setClickable(true);    logout.setVisibility(View.GONE);    btnLogin.setText("登录");    break;   default:    break;   }  }  @Override  protected void onActivityResult(int requestCode, int resultCode, Intent data) {   // TODO Auto-generated method stub   super.onActivityResult(requestCode, resultCode, data);     if (resultCode == RESULT_OK) {    switch (requestCode) {    case A:     Bundle bundle = data.getExtras();     String back = bundle.getString("back");     Toast.makeText(getApplicationContext(), "A界面传回来的数据为:::::::"+back, 0).show();     content.setText("A界面传回来的数据"+back);     break;    case LOGIN:     Bundle loginBundle = data.getExtras();     String username = loginBundle.getString("username");     String passwrod = loginBundle.getString("password");     content.setText("登录界面传回来的数据"+username+":::::::"+passwrod);     btnLogin.setText("已登录");     btnLogin.setClickable(false);     logout.setVisibility(View.VISIBLE);     Toast.makeText(getApplicationContext(), username+"::::::::"+passwrod, 0).show();     break;    default:     break;    }   }    }

其中主要的地方有两个,一个是在启动activity时,如果要带结果返回,则需要使用startActivityForResult(intent, requestcode)这个方法,该方法两个参数一个是带数据的Intent,另一个就是请求码,这个请求码是用于给activity识别是哪个activity返回的数据,因为在一个activity中可能会出现多个startActivityForResult,因此返回的时候,activity为了识别是哪个activity返回的数据就要利用requestcode来进行区分。

上面还有一个很重要的方法onActivityResult(int requestCode, int resultCode, Intent data) 该方法在startActivityForResult启动的activity结束后返回数据时调用,其中第二个参数是结果码,结果码为RESULT_OK时,说明activity顺便结束并返回结果。

第一个参数requestcode就是被启动的activity的识别码,在startActivityForResult方法时传入。

第三个参数data 是Intent型的数据,该数据就是从activity返回回来的数据,可以使用data.getExtras()方法得到bundle,然后从bundle中取出一些基本数据。

通过不同的结果码,对不同的activity返回的数据进行相应的操作,就可以合理的完成一些特定的功能效果。

那么,是不是所有的startActivityForResult启动的activity都回返回数据呢?答案是否定的,要想要activity返回数据,在activity中也要进行响应的一些设置,请看activity的代码

ActivityA的代码如下:

protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);   LinearLayout ll = new LinearLayout(this);   LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,     LayoutParams.WRAP_CONTENT);   ll.setLayoutParams(params);   ll.setOrientation(LinearLayout.VERTICAL);   TextView tv = new TextView(this);   tv.setText("我是A界面");   ll.addView(tv);   Button close = new Button(this);   close.setText("关闭界面并返回");   close.setOnClickListener(new OnClickListener() {    @Override    public void onClick(View v) {     Intent intent = new Intent();     intent.putExtra("back", "我是A界面返回的数据");     setResult(RESULT_OK, intent);     finish();    }   });   ll.addView(close);   setContentView(ll);   Toast.makeText(getApplicationContext(),     getIntent().getExtras().getString("data"), 0).show();  }

注意其中有一段代码,是setResult(RESULT_OK, intent); 之后紧接着 finish();

activity要能成功返回数据,就必须在结束finish()之前调用setResult方法,该方法的两个参数,第一个为结果码,也就是onActivityResult方法中的第二个参数resultcode,一般情况下我们都设置该值为RESULT_OK

ActivityB由于使用的是startActivity 因此无需返回数据

ActivityB的代码如下:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  setContentView(R.layout.activityb);   Button close = (Button) findViewById(R.id.btn_close);   close.setOnClickListener(new OnClickListener() {    @Override    public void onClick(View v) {     // TODO Auto-generated method stub     finish();    }   });   Toast.makeText(getApplicationContext(),     getIntent().getExtras().getString("data"), 0).show();    }
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);   setContentView(R.layout.login);   etUsername = (EditText) findViewById(R.id.et_username);   etPassword = (EditText) findViewById(R.id.et_password);   Button login = (Button) findViewById(R.id.btn_login);   login.setOnClickListener(new OnClickListener() {    @Override    public void onClick(View v) {     // TODO Auto-generated method stub     String password = etPassword.getText().toString().trim();     String username = etUsername.getText().toString().trim();     Toast.makeText(getApplicationContext(), "登录成功,返回原来界面", 0)       .show();     Intent intent = new Intent();     intent.putExtra("username", username);     intent.putExtra("password", password);     setResult(RESULT_OK, intent);     finish();    }   });   Toast.makeText(getApplicationContext(),     getIntent().getExtras().getString("data"), 0).show();  }


该界面登录成功后,将用户名和密码返回到主页面,并显示,同时主页面不能再次登录,可以使用注销操作。

到这里,这个小demo就完成了。

主要演示二个功能,一个是启动activity并带结果返回,将结果显示在页面上。

一个是启动activity不带结果返回,这种操作比较常用和简单。

完整的代码: http://download.csdn.net/download/yanglfree/7503139

下面再来说下startActivityForResult另一个比较常用的应用场景:上传头像

效果图如下:

点击头像后,弹出选择对话框,选择相册或者拍照,完成后会出现裁剪界面,裁剪完成后,会将头像显示在界面上,如果有服务器的话,会将头像上传到服务器。

看下几段关键的代码:

头像的点击事件:

public void onClick(View v) {
       CharSequence[] items = { "查看头像", "手机相册", "手机拍照" };     new AlertDialog.Builder(MainActivity.this).setTitle("上传照片")       .setItems(items, new DialogInterface.OnClickListener() {        public void onClick(DialogInterface dialog,          int which) {         if (which == SELECT_PICTURE) {          Intent intent = new Intent(            Intent.ACTION_PICK);          intent.setType("image/*");          startActivityForResult(intent,            PHOTO_REQUEST_GALLERY);         } else if (which == SELECT_CAMERA) {          Intent intent = new Intent(            "android.media.action.IMAGE_CAPTURE");          // 判断存储卡是否可以用,可用进行存储          if (hasSdcard()) {           intent.putExtra(             MediaStore.EXTRA_OUTPUT,             Uri.fromFile(new File(               Environment                 .getExternalStorageDirectory(),               PHOTO_FILE_NAME)));          }          startActivityForResult(intent,            PHOTO_REQUEST_CAMERA);         } else if (which == SELECT_SCAN) {          // TODO 查看头像         }        }       }).create().show();    }   });

其中,启动相册和拍照都是采用的startAcitivityForResult方法,并且,由于相册和拍照都是系统应用,因此,intent使用指定的intent

拍照: "android.media.action.IMAGE_CAPTURE"

相册:Intent.ACTION_PICK

在activityResult方法中:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
   super.onActivityResult(requestCode, resultCode, data);   if (resultCode == Activity.RESULT_OK) {    if (requestCode == PHOTO_REQUEST_GALLERY) {// 图库     if (data == null) {      return;     }     Uri uri = data.getData();     crop(uri);    } else if (requestCode == PHOTO_REQUEST_CAMERA) {// 拍照     if (hasSdcard()) {      file = new File(Environment.getExternalStorageDirectory(),        PHOTO_FILE_NAME);      crop(Uri.fromFile(file));     } else {      Toast.makeText(this, "未找到存储卡,无法存储照片!", 0).show();     }    } else if (requestCode == PHOTO_REQUEST_CUT) {// 裁     try {      bmp = data.getParcelableExtra("data");      photo.setImageBitmap(bmp);      File tempFile = BitmapUtils.saveBitmapFile(bmp,        PHOTO_FILE_NAME);      upload(tempFile);//上传到服务器      pd = new ProgressDialog(this);      pd.setMessage("头像正在上传中请稍后");      pd.show();     } catch (Exception e) {      e.printStackTrace();     }    }   } 

}






本文转自 一点点征服 博客园博客,原文链接:http://www.cnblogs.com/ldq2016/p/5368062.html,如需转载请自行联系原作者




 
相关文章
|
3月前
|
开发工具 Android开发 开发者
Android平台如何不推RTMP|不发布RTSP流|不实时录像|不回传GB28181数据时实时快照?
本文介绍了一种在Android平台上实现实时截图快照的方法,尤其适用于无需依赖系统接口的情况,如在RTMP推送、RTSP服务或GB28181设备接入等场景下进行截图。通过底层模块(libSmartPublisher.so)实现了截图功能,封装了`SnapShotImpl.java`类来管理截图流程。此外,提供了关键代码片段展示初始化SDK实例、执行截图、以及在Activity销毁时释放资源的过程。此方案还考虑到了快照数据的灵活处理需求,符合GB/T28181-2022的技术规范。对于寻求更灵活快照机制的开发者来说,这是一个值得参考的设计思路。
|
5月前
|
XML 存储 JSON
51. 【Android教程】JSON 数据解析
51. 【Android教程】JSON 数据解析
152 2
|
1月前
|
存储 大数据 数据库
Android经典面试题之Intent传递数据大小为什么限制是1M?
在 Android 中,使用 Intent 传递数据时存在约 1MB 的大小限制,这是由于 Binder 机制的事务缓冲区限制、Intent 的设计初衷以及内存消耗和性能问题所致。推荐使用文件存储、SharedPreferences、数据库存储或 ContentProvider 等方式传递大数据。
76 0
|
3月前
|
JSON Java Android开发
Android 开发者必备秘籍:轻松攻克 JSON 格式数据解析难题,让你的应用更出色!
【8月更文挑战第18天】在Android开发中,解析JSON数据至关重要。JSON以其简洁和易读成为首选的数据交换格式。开发者可通过多种途径解析JSON,如使用内置的`JSONObject`和`JSONArray`类直接操作数据,或借助Google提供的Gson库将JSON自动映射为Java对象。无论哪种方法,正确解析JSON都是实现高效应用的关键,能帮助开发者处理网络请求返回的数据,并将其展示给用户,从而提升应用的功能性和用户体验。
96 1
|
3月前
|
缓存 API Android开发
Android经典实战之Kotlin Flow中的3个数据相关的操作符:debounce、buffer和conflate
本文介绍了Kotlin中`Flow`的`debounce`、`buffer`及`conflate`三个操作符。`debounce`过滤快速连续数据,仅保留指定时间内的最后一个;`buffer`引入缓存减轻背压;`conflate`仅保留最新数据。通过示例展示了如何在搜索输入和数据流处理中应用这些操作符以提高程序效率和用户体验。
52 6
|
3月前
|
编解码 网络协议 前端开发
如何实现Android平台GB28181设备接入模块按需打开摄像头并回传数据
后台采集摄像头,如果想再进一步扩展,可以把android平台gb28181的camera2 demo,都移植过来,实现功能更强大的国标设备侧,这里主要是展示,收到国标平台侧的回传请求后,才打开摄像头,才开始编码打包,最大限度的减少资源的占用
|
3月前
|
编解码 网络协议 Android开发
Android平台GB28181设备接入模块实现后台service按需回传摄像头数据到国标平台侧
我们在做Android平台GB28181设备对接模块的时候,遇到这样的技术需求,开发者希望能以后台服务的形式运行程序,国标平台侧没有视频回传请求的时候,仅保持信令链接,有发起视频回传请求或语音广播时,打开摄像头,并实时回传音视频数据或接收处理国标平台侧发过来的语音广播数据。
|
3月前
|
算法 数据处理 开发工具
Android平台RTSP|RTMP播放器如何回调YUV或RGB数据
在开发Android平台上的RTSP或RTMP播放器时,开发者不仅追求低延迟播放,还希望获取解码后的视频数据(如YUV或RGB格式),以便进行视觉算法分析。使用大牛直播SDK中的SmartPlayer,可在确保播放流畅的同时,通过设置外部渲染器(`SmartPlayerSetExternalRender`)来高效地回调原始视频数据。例如,对于RGBA数据,需实现`NTExternalRender`接口,并重写相关方法以处理数据和尺寸变化。同样地,对于I420(YUV)数据,也需要相应地实现接口以满足需求。这种方式使得开发者能在不影响常规播放功能的情况下,进行定制化的视频处理任务。
|
3月前
|
存储 缓存 Java
Android项目架构设计问题之优化业务接口数据的加载效率如何解决
Android项目架构设计问题之优化业务接口数据的加载效率如何解决
47 0
|
5月前
|
JSON 编解码 Apache
Android中使用HttpURLConnection实现GET POST JSON数据与下载图片
Android中使用HttpURLConnection实现GET POST JSON数据与下载图片
64 1