当前位置: 移动技术网 > IT编程>移动开发>Android > 详解Android Activity之间切换传递数据的方法

详解Android Activity之间切换传递数据的方法

2019年07月24日  | 移动技术网IT编程  | 我要评论

前面照着android系统的裁剪图片的功能自己写了一个相似的工具。功能是大体上实现了,但留下了一个调用的问题:如何从我的程序调用这个裁剪工具,并且获得裁剪后的图片呢?

其实这个也很简单了,就是intent的基础用法。

先上个图(界面依旧没优化,难看就难看吧):

起始activity,打开图片选择窗口,随便选择一张图片

下面是跳转到裁剪界面

按下crop按钮,退出activity,回到原来界面,并显示裁剪后的图

流程就是这样,也算模拟了系统裁剪功能的整体过程。下面就是实现功能的关键代码和说明了。

这里先称主程序为a,调用的子程序为b。

b是自己写的程序,调用他就需要定制自己的activity action。系统的action都对应一个action字符串,比如在intent类中定义的一些action常量:

public static final string action_main = "android.intent.action.main";
public static final string action_view = "android.intent.action.view";
public static final string action_edit = "android.intent.action.edit";
public static final string action_call = "android.intent.action.call";
public static final string action_call_emergency = "android.intent.action.call_emergency"; 

intent的构造方法中,会有一些如:intent.setclass(activity.this, x.class);的方法。但我不太喜欢这种方式。
除此之外常用的构造方法就是

public intent(string action);
public intent(string action, uri uri);

使用string,uri这种参数类型的intent对象称为隐式intent对象,即,通过intent类的构造方法并未指定intent的目标是哪一个activity,这些目标要依靠在androidmanifest.xml文件中的配置信息才能确定。也就是说,action所指的目标可能不止一个,或者说再androidmanifest.xml文件中可以配置多个接收同一个action的activity action。

在androidmanifest.xml中一般文件格式如下:

<application
android:allowbackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/apptheme" >
<activity
android:name="com.example.crop_image_my.mainactivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.main" />
<category android:name="android.intent.category.launcher" />
</intent-filter>
</activity>
</application> 

其中<action>标签指定一个系统定义的activity action。该action表示在应用程序启动时第一个启动的activity需要接收这个action。也就是说这个动作是android应用程序启动主窗口的动作。

因为需要自己的action启动裁剪程序,所以我在上面的xml中另外加了下面一段:

<intent-filter>
   <action android:name="com.example.crop_image_my.copper" />
<data android:scheme="crop" />
<category android:name="android.intent.category.default" />
</intent-filter> 

保留.main是我需要程序单独运行也可以(不知道删掉的话会怎样,没测试)

上面<data>标签定义一个scheme,所以后面的uri可以写作 crop://something

哦对,上面的是b的配置文件,a要启动b嘛。

下面在a中就可以调用b的intent了:

private void startmycropintent(string path) throws filenotfoundexception {
intent intent = new intent("com.example.crop_image_my.copper", uri.parse("crop://" + path));
startactivityforresult(intent, );
} 

上面构造intent就不说了,参数是前面配置文件里的。要想启动新的activity,使用startactivity()就可以,但为了能获取到返回值,就要用startactivityforresult()方法,在onactivityresult()进行处理。

第二个参数12是请求代码,对应onactivityresult(int requestcode,int resultcode, intent data)中第一个参数。这个数字可以随便写,但建议用资源写,比如某个按钮触发startactivityforresult(),就可以把这个按钮的r.id.button1当请求码(其实用什么都行了,只要方便识别)。

好,启动activity后,注意参数有一个uri,这个uri就是我选择的图片的路径,在裁剪的方法b中里要获取这个uri:

if (getintent().getdata() != null) {
imgpath = getintent().getdata().getpath(); // 参见uri的组成形式资料
log.v("<dbw>", imgpath);
mycropview.setbmppath(imgpath);
} 

写在oncreate里,在构造的时候就取得这个值并使用。

下面是关闭activity。在b里面写。直接放代码吧

@override
public void onclick(view v) {
// todo auto-generated method stub
switch (v.getid()) {
case r.id.btn_crop:
bitmap croppedimage = mycropview.getcroppedimage();
croppedimageview.setimagebitmap(croppedimage);
savecroppedimage(croppedimage);
// return to the last activity
log.v("<dbw>", newfilepath);
getintent().putextra("newpath", newfilepath);
setresult(, getintent());
break;
case r.id.btn_cancel:
setresult();
break;
default:
break;
}
finish();
} 

裁剪之后先保存图片,然后通过getintent().putextra()方法把图片路径存在intent里。“newpath”是随便起的名,作为取数据的标识。finish()是关闭这个activity。参数20是onactivityresult(int requestcode,int resultcode, intent data)的第二个参数。

最后获取截到的图片,在a写:

@override
protected void onactivityresult(int requestcode, int resultcode, intent data) {
super.onactivityresult(requestcode, resultcode, data);
switch (requestcode) {
case :
if (resultcode == ) {
string path = data.getextras().getstring("newpath");
log.v("<dbw>", "get------" + path);
bitmap bmp = bitmapfactory.decodefile(path);
iv.setimagebitmap(bmp);
} else if (resultcode == ) {
toast toast = toast.maketext(this, "您取消了操作", toast.length_long);
toast.show();
}
break;
default:
break;
}
} 

switch是针对不同的activity(当前只启动一个,标识码是12)。再对不同的resultcode做不同处理。

前面用了putextra设置数据,这里就用data.getextra方法获取bundle对象,在根据需要用getxxx方法获得不同的数据。

就是这么个过程。

4.28.2015

另一个简单方法:

同一个项目里建2个activity,eclipse 项目右击->new->others->android->android activity

manifest.xml:

<application
android:allowbackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/apptheme" >
<activity   启动显示的
android:name=".mainactivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.main" />
<category android:name="android.intent.category.launcher" />
</intent-filter>
</activity>
<activity                        切换的
android:name=".showmessage"
android:label="@string/title_activity_display_message"
android:parentactivityname=".mainactivity" >
<meta-data
android:name="android.support.parent_activity"
android:value="com.example.android_switchactivity.mainactivity" />
</activity>
</application> 

在mainactivity中添加:

public final static string extra_message = "com.example.android_switchactivity.message"; 这个string可以任意赋值,但要保证唯一intent intent = new intent(this, showmessage.class);
edittext met = (edittext)findviewbyid(r.id.edit_message);
string message = met.gettext().tostring();
intent.putextra(extra_message, message);
startactivity(intent); 

在第2个activity添加:

intent intent = getintent();
string message = intent.getstringextra(mainactivity.extra_message);
textview mtv = new textview(this);
mtv.settextsize(40);
mtv.settext(message); 


如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网