一、访问其他应用程序的Activity
Activity的跨进程访问与进程内访问略有不同。虽然它们都需要Intent对象,但跨进程访问并不需要指定Context对象和Activity的 Class对象。
而需要指定的是要访问的Activity所对应的Action(一个字符串),有些Activity还需要传递一个Uri数据。在android系统中有很多应用程序提供了可以跨进程访问的Activity。
例如,下面的代码可以直接调用拨打电话的Activity。
-
- String phoneNum = phoneNumEdit.getText().toString().trim();
-
- Intent callIntent = new Intent(Intent.ACTION_CALL);
- callIntent.setData(Uri.parse("tel:"+phoneNum));
- startActivity(callIntent);
有些应用程序中的Activity有时还会返回数据。
例如调用系统相机时,可以将拍照结果返回。可以在调用拍照的Activity中onActivityResult回调方法中获取到拍到的照片数据。代码如下:
-
- Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- startActivityForResult(takePhotoIntent, REQUEST_TAKE_PHOTO);
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-
-
- if (requestCode == REQUEST_TAKE_PHOTO) {
-
-
- if (resultCode == RESULT_OK) {
-
- Bitmap bmp = (Bitmap) data.getExtras().get("data");
- takeResultImg.setImageBitmap(bmp);
- }
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
二、将Activity共享给其他应用程序访问
在调用拨号程序的代码中使用了一个Intent.ACTION_CALL常量,常量定义如下:
- public static final String ACTION_CALL = "android.intent.action.CALL";
在调用相机程序的代码中使用了一个MediaStore.ACTION_IMAGE_CAPTURE常量,常量定义如下:
- public final static String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
这些常量是一个字符串常量,也是跨进程调用Activity的关键。如果在应用程序中要共享某个Activity,需要为这个 Activity指定一个标识ID,即Action。在其他的应用程序中只要通过这个 Action就可以找到与Action对应的Activity,并通过startActivity方法来启动这个Activity。
下面先看一下如何将应用程序的Activity共享出来,读者可按以下步骤共享Activity:
1、在AndroidManifest.xml文件中给要共享的Activity指定Action和访问协议
Action要使用<action>标签的android:name属性中指定,访问协议需要使用<data>标签的android:scheme属性来指定。前面拨打电话时的Intent.ACTION_CALL常量就是Action,“tel”就是访问协议。实例代码如下:
- <activity android:name="com.sarnasea.interprocess.ShareActivity">
- <intent-filter>
- <action android:name="com.sarnasea.interprocess.MYACTION"/>
- <data android:scheme="message"/>
- <category android:name="android.intent.category.DEFAULT"/>
- </intent-filter>
- </activity>
在配置AndroidManifest.xml时要注意,不能在同一个<activity>中配置多个动作,否则会覆盖MAIN动作以使该程序无法正常启动(虽然其他应用程序调用是正常的)。
从上面的代码可以看出,<action>标签的android:name属性值是 com.sarnasea.interprocess.MYACTION,这就是该Activity自定义的动作。<data>标签指定了Url的协议message(可选)。
2. 获得其他应用程序传递过来的数据
在要共享的Activity中通过getIntent().getData().getHost()方法可获得访问协议后的Uri的主体部分(任意的字符串)。
也可以从getIntent()中获得其他应用程序传递过来的数据(Bundle)。实例代码如下:
-
- Uri data = getIntent().getData();
- if (data != null) {
-
-
- String host = data.getHost();
- Toast.makeText(this, host, Toast.LENGTH_SHORT).show();
- }
-
- Bundle bundle = getIntent().getExtras();
- if(bundle != null){
-
-
- String value = bundle.getString("value");
- Toast.makeText(this, value, Toast.LENGTH_SHORT).show();
- }
到这步该Activity就对外共享成功了,在其他应用程序中可以这样来访问这个Activity(类似上边调用拨号程序一样)。实例代码如下:
- Intent intent = new Intent();
- intent.setAction("com.sarnasea.interprocess.MYACTION");
- intent.setData(Uri.parse("message://Hello World!"));
- intent.putExtra("value", "yanglu");
- startActivity(intent);
同样,也可以和调用相机一样,采用startActivityForResult(Intent intent, int requestCode)获取共享Activity关闭时返回的数据。这点和同一进程中是一致的,只需要在该共享Activity finish之前调用setResult(int resultCode, Intent data)即可,示例代码如下:
- Intent data = new Intent();
-
- data.putExtra("result", "关闭Activity时返回的数据");
-
- setResult(Activity.RESULT_OK, data);
-
- finish();