启动其他应用

来源:互联网 发布:淘宝最低折扣0.7是什么 编辑:程序博客网 时间:2024/05/16 11:52

 和其他平台的应用不一样,安卓的应用不一定需要从主函数启动,一个应用可以启动其他应用。这是因为每个应用都能响应不同的动作,比如相机能相应照相这个动作,很多社交软件都能相应分享动作,视频播放器能响应播放视屏的动作。发送一个动作,系统会查询能够响应相应动作的应用,然后显示出可以响应这个动作的应用。这就应用启动其他应用的原理。常见的场景有,你的应用要拍一张照片,你当然可以自己写一个相机程序,但是你可以调用系统自带的相机,发送一个拍照的动作,然后请求返回照片,就能从相机得到一张照片了,当你的用户需要分享东西时,只需要发送一个Send的动作就可以将内容分享到其他应用中。
 在一个应用程序内,Activity通过Intent 启动其他Activity ,启动其他应用也是使用Intent,其本质还是启动Activity,不过不是本应用内的Activity,而是其他其他应用的Activity。当启动本应用内的Activity,应用是你自己写的,你知道应用内所有Activity以及他们的功能,所以你可以指定启动哪个Activity,这样的Intent叫显示 Intent(explicit intent),在Intent 中指定要启动的组件(包括Activity,Service,Broad Cast)。但是如果要其他应用的Activity,你并不知道其他应用内有什么Activity,有什么功能,所以不能直接启动。这就需要使用隐式intent(implicit intent),在Intent中指定要执行的动作,系统会从安装的程序中查询能够响应这个动作的组件,如果有应用能响应这个动作,就会显示这些应用,如果没有,会出现错误(要避免这种情况)。

使用隐式Intent

使用隐式Intent,只需要在Intent中声明你想要执行的动作,你想让其他应用做的事情。比如说分享,查看,编辑或者从其他应用获取数据。在传递动作的时候,你也可以传递一些数据,例如你有个地址,想通过地图来查看这个地址。
比如你的用户需要将东西分享到其他应用中,下面是一个简单的用法

Intent intent = new Intent(Intent.ACTION_SEND);startActivity(intent);

这里只指定了一个发送的动作,但是没有指定发送的内容,要发送内容的类型,这个动作可能执行,有可能出错,这取决于用户设备守丧安装的应用。为了确保至少有一个应用能响应这个动作,可以使用如下代码

/**     * 确定设备上是否有能够响应给定Intent的应用,如果有返回true,否则返回false     * @param intent 要检查的intent     * @return true如果有应用可以响应这个Intent,否则返回false     */    public boolean matchIntent(Intent  intent){        PackageManager manager = getPackageManager();        List activities = manager.queryIntentActivities(intent,PackageManager.MATCH_DEFAULT_ONLY);        return activities.size() > 0;    }

继续上面的分享动作,当用户要分享或查看什么东西时,肯定已经有内容,可能时Uri数据或者其他数据。
 假设你的应用内有个网址,需要系统的浏览器打开
 

Uri webPage = Uri.parse("http://www.baidu.com");        Intent intent = new Intent(Intent.ACTION_VIEW,webPage);        if (matchIntent(intent))            startActivity(intent);

Intent中还可以存放额外的数据,能够存储不同的数据类型,通过Intent将这些数据传递到能启动它的组件,然后这个组件会接受处理这些额外的数据。通过putExtra()来存放额外的数据。
 假设用户要分享一段文本,可以使用如下代码
 

String share = "hello!";        Intent intent = new Intent(Intent.ACTION_SEND);        intent.setType("text/plain");        intent.putExtra(Intent.EXTRA_TEXT,share);        if (matchIntent(intent))            startActivity(intent);

当使用putExtra时,第一个参数要用Intent类里的Standard extra data keys.如果你自己定义键,别的应用并不知道你的键,就无法从Intent中取出你要分享的数据。你的应用如果要响应其他应用的动作,也要使用Intent类中提供的键来获取Intetn传递过来的额外的数据。如果大家都遵守这个标准,就能保证传递正确的数据,取出正确的数据。

从其他Activity返回结果

 有时候启动其他Activity只是借用它的功能来获取信息,比如使用照相机拍照,并获取拍照的结果。从系统图库中选取图片,从通讯录中选取某个联系人的信息。
 要从启动的Activity中返回结果,要用startActivityForResult()来启动Activity,该方法接受两个参数,第一个是你想要执行的动作,第二个是一个整数(requestCode),接受返回的结果时,将返回的requestCode和你启动这个Activity时的requestCode进行比较,如果相等,说明确实是你启动了这个Activity,它也返回了数据。
 然后在重写onActivityResult(int requestCode,int resultCode,Intent data),处理返回过来的数据。这个方法接受三个参数,前两个都是整数,第三个是Intent,它携带返回的数据。前两个参数用来验证是否返回了数据。requestCode和启动Activity传递的参数进行比较,如果相等,说明确实是你启动了这个Activity,它也返回了数据。resultCode代表是否成功返回数据,如果resultCode 和Activity.REULT_OK相等,说明成功返回了数据。
 下面代码展示启动系统自带的相机程序拍照,返回照片,并将照片显示在屏幕上。
 

private void takePhoto() {  Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);  if (matchIntent(intent)   startActivityForResult(intent,REQUEST_IAMGE_CAPTURE);}@Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        if (requestCode == REQUEST_IAMGE_CAPTURE && resultCode == RESULT_OK){            Bundle extra = data.getExtras();            Bitmap imageBitmap = (Bitmap) extra.get("data");            mImage.setImageBitmap(imageBitmap);        }    }

允许他应用启动你的应用

 你可以用户手机安装的其他应用程序。你也可以让其他应用启动你的应用。如果你的应用是一款社交类应用,用户可以将其他应用中的信息分享到你的应用中,当然你需要处理这些传递过来的信息,让它们以正确的方式呈现在你的应用中。
 添加Intent Filter
 如果允许其他应用启动你的应用,首先要添加Intent Filter。决定让哪个组件处理动作,然后在这个组件下添加Intent Filter.Intent 下包含的内容有
 

  • Action 你的应用能响应的动作。例如ACTION_SENDACTION_VIEW,但是intent filter中不能只写ACTION_SEND,需要写完整名字,android.intent.action.SEND
  • Data,你的应用能够处理的数据类型。可以指定MIME或者URI前缀,比如text/plain
  • category 组件的类别,如下代码,将activity作为应用启动后显示的第一屏。
 <category android:name="android.intent.category.LAUNCHER" />

 你要接受的intent 只有一个动作和一种数据类型,但是你可以在intent filter中定义多个action和Data标签。
 当一个应用使用隐式Intent时,系统检索系统上所有应用的manifest file,检索逐一检索它们的Intent Filter,比较action ,data ,catogery,如果这三个项都匹配,则该应用能想用这个Intent,否则不能响应这个Intent.

在Acitivity中处理接收到的Intent
通过getIntent获取接收到的Intent,然后获取相关数据。
假设应用能响应ACTION_SEND,数据类型为text/plain的Intent。
Intent Filter如下

<activity android:name=".Main2Activity">   <intent-filter>       <action android:name="android.intent.action.SEND"/>       <data android:mimeType="text/plain"/>       <category android:name="android.intent.category.DEFAULT"/>      </intent-filter></activity>

处理Intent的Activity如下
Main2Activity.java

package com.example.test.testshare;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.TextView;public class Main2Activity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);        Intent intent = getIntent();        String text = intent.getStringExtra(Intent.EXTRA_TEXT);        TextView show = new TextView(this);        show.setText(text);        setContentView(show);    }}
0 0
原创粉丝点击