android学习笔记----隐式意图和显式意图

目录

隐式意图和显式意图:

使用意图在activity之间传递数据(人品计算器):


隐式意图和显式意图:

显式意图:显式意图明确指明了启动活动的上下文和想要启动的目标活动,显式意图明确指定了Intent应该传递给哪个组件。
隐式意图:没有明确指定组件名的Intent为隐式意图。 Android系统会根据隐式意图中设置的动作(action)、类别(category)、数据(URI和数据类型)找到最合适的组件来处理这个意图。

开启自己应用的界面用显式意图,开启其他应用(一般指系统应用)的时候用隐式意图(比如拨打电话)。

显式意图安全一些,隐式意图可以通过匹配intent-filter里面的标签对应来跳转到相应的页面 。

Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testactivity">

    <uses-permission android:name="android.permission.CALL_PHONE" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/kakaxi"
        android:label="@string/app_name"
        android:roundIcon="@drawable/mingren"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="第一个activity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".TestActivity"
            android:label="第二个activity">
            <intent-filter>
                <action android:name="mytestAction" />
                <category android:name="android.intent.category.DEFAULT" />
                <data
                    android:mimeType="aa/bb"
                    android:scheme="mytestscheme" />
            </intent-filter>
        </activity>
        <activity android:name=".Test3" />
    </application>

</manifest>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/id_btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onclick"
        android:text="拨打电话" />

    <Button
        android:id="@+id/id_btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onclick"
        android:text="隐式意图跳转到TestActivity" />
    <Button
        android:id="@+id/id_btn3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onclick"
        android:text="显式意图跳转到TestActivity" />
</LinearLayout>

MainActivity.java

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void onclick(View view) {
        switch (view.getId()) {
            case R.id.id_btn1:
                if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE)
                        != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE}, 1);
                } else {
                    call();
                }
                break;
            case R.id.id_btn2:
                // 创建意图对象
                Intent intent = new Intent();
                // 以下隐式意图都可以自定义
                // 设置拨打的动作
                intent.setAction("mytestAction");
                // 设置category
                intent.addCategory("android.intent.category.DEFAULT");
                // 设置数据和基本类型
                intent.setDataAndType(Uri.parse("mytestscheme:"), "aa/bb");// 一定要有冒号:可以后面随便加个数,和tel:类似
                // 主要是为了匹配清单文件的约束
                // 开启Activity,记得加上权限
                startActivity(intent);
                break;
            case R.id.id_btn3:
                Intent intent1 = new Intent(MainActivity.this, Test3.class);
                // 如果是构造的空参intent,则设置包名和类名,或者构造2个参数intent
                //intent1.setClassName("com.example.testactivity", "com.example.testactivity.Test3");
                startActivity(intent1);
                break;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case 1:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    call();
                } else {
                    Toast.makeText(this, "you denied the permision", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

    private void call() {
        // 创建意图对象
        Intent intent = new Intent();
        // 设置拨打的动作
        intent.setAction(Intent.ACTION_CALL);
        // 设置拨打的数据
        intent.setData(Uri.parse("tel:" + 119));
        // 开启Activity,记得加上权限
        startActivity(intent);
    }
}

批注:

按钮1,2为了演示隐式意图,按钮3演示显式意图

关于隐式意图:

在case R.id.id_btn2:中

intent.setData(data)和intent.setType(type)注意这两个方法会互相清除,意思就是:如果先设置setData(data)后设置setType(type),那么后设置的setType(type)会把前面setData(data)设置的内容清除掉,而且会报错,反之一样,所以如果既要设置类型与数据,那么使用public Intent setDataAndType(Uri data, String type) 这个方法。

可以配置多个意图过滤器,只要能够完整的匹配任何一个意图过滤器intent-filter,就可以跳转到那个activity

如果intent-filter里面只有<action>和<category>标签,那么只有<action>和<category>中的内容同时能够匹配上Intent中指定的action和category时,这个活动才能响应这个Intent。如果还有data标签,也要一一对应才行。

每个Intent中只能指定一个action,却能指定多个category。

关于data标签:

为什么设置数据和基本类型时intent.setDataAndType(Uri.parse("mytestscheme:"), "aa/bb");

这里一定要有冒号:后面可以随便加个数,或者不加,和tel:类似,这里不是拨打电话,所以可以不加,主要为了符合约束条件

关于显式意图:

在case R.id.id_btn3:中

Intent intent1 = new Intent(MainActivity.this, Test3.class);

startActivity(intent1);

等价于<===========>

Intent intent1 = new Intent();

intent1.setClassName("com.example.testactivity", "com.example.testactivity.Test3");

startActivity(intent1);

一般写上面那一种就可以了。

TestActivity.java

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

public class TestActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout2);
    }
}

Test3.java

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;

public class Test3 extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout3);
    }
}

layout2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="第二个activity"/>
</LinearLayout>

layout3.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="第三个activity"/>
</LinearLayout>

使用意图在activity之间传递数据(人品计算器):

MainActivity.java

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private EditText et_name;
    private RadioGroup rg_group;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_name = (EditText) findViewById(R.id.et_name);
        rg_group = (RadioGroup) findViewById(R.id.radioGroup);
    }


    public void click(View view) {
        // 获取用户名
        String name = et_name.getText().toString().trim();
        if (TextUtils.isEmpty(name)) {
            Toast.makeText(this, "亲,请输入姓名", Toast.LENGTH_SHORT).show();
            return;
        }
        // 判断用户性别
        int id = rg_group.getCheckedRadioButtonId();
        int sex = 0;
        switch (id) {
            case R.id.rb_male:
                sex = 1;
                break;
            case R.id.rb_female:
                sex = 2;
                break;
            case R.id.rb_other:
                sex = 3;
                break;
        }
        if (sex == 0) {
            Toast.makeText(this, "请选择性别", Toast.LENGTH_SHORT).show();
            return;
        }
        // 跳转到ResultActivity页面,用显式意图跳转
        Intent intent = new Intent(this, ResultActivity.class);
        // 传递姓名
        intent.putExtra("name", name);
        // 传递性别
        intent.putExtra("sex", sex);
        // 如果希望在活动销毁的时候能够返回一个结果给上一个活动,就用startActivityForResult
        startActivityForResult(intent, 1); // 请求码为1
    }
    // 在活动销毁后返回上一个活动的onActivityResult
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case 1:
                if (resultCode == RESULT_OK){
                    int returnedData = data.getIntExtra("score", 0); // 默认为0
                    Toast.makeText(this, "您的测试分数为:" + returnedData, Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                break;
        }
    }
}

批注:

public void startActivityForResult (Intent intent, int requestCode)

和打电话一样startActivityForResult(Intent, int, Bundle)没有选择。

参数
intent Intent:开始的意图。
requestCode int:如果>=0,则当活动退出时,此代码将在onActivityResult()中返回。
抛出
  android.content.ActivityNotFoundException

protected void onActivityResult (int requestCode, int resultCode, Intent data)

当您启动的活动退出时调用,为您提供requestCode,启动它,返回resultCode,以及来自它的任何其他数据。如果活动显式返回,则不会返回任何结果,或者在操作期间崩溃,resultCode将为RESULT_CANCELED。

当您的活动重新启动时,您将在onResume()之前立即收到此调用。

如果您的活动将noHistory设置为true,则永远不会调用此方法。

参数
requestCode int:最初提供给startActivityForResult()的整数请求代码,允许您识别此结果的来源。
resultCode int子活动通过其setResult()返回的整数结果代码。
data Intent:一个Intent,它可以将结果数据返回给调用者(各种数据可以附加到Intent“extras”)。

由于在一个活动中有可能调用startActivityForResult()方法去启动很多不同的活动,每一个活动返回的数据都会回调到onActivityResult()这个方法中,因此我们首先要做的就是通过resultCode的值来判断数据来源,确定这个是由哪一个活动返回的数据。

ResultActivity.java

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;

public class ResultActivity extends AppCompatActivity {

    private TextView tv_sex;
    private TextView tv_name;
    private TextView tv_result;
    private int score;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_result);
        tv_name = (TextView) findViewById(R.id.tv_name);
        tv_sex = (TextView) findViewById(R.id.tv_sex);
        tv_result = (TextView) findViewById(R.id.tv_result);
        // 获取MainActivity窜地过来的数据
        Intent intent = getIntent();// 获取开启此activity的意图对象
        // 获取name和sex的值
        // 小技巧:传递的是什么数据类型,这边就按照传递的数据类型取
        String name = intent.getStringExtra("name");
        int sex = intent.getIntExtra("sex", 0);
        // 根据name和sex显示数据
        tv_name.setText(name);
        byte[] bytes = null;
        try {
            // 显示性别
            switch (sex) {
                case 1:
                    tv_sex.setText("男");
                    bytes = name.getBytes("gbk");
                    break;
                case 2:
                    tv_sex.setText("女");
                    bytes = name.getBytes("utf-8");
                    break;
                case 3:
                    tv_sex.setText("人妖");
                    bytes = name.getBytes("iso8859-1");
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        int total = 0;
        for (byte b : bytes) {
            int number = b & 0xff;
            total += number;
        }
        // 获取得分
        score = Math.abs(total) % 100;
        if (score > 90) {
            tv_result.setText("你是世人的榜样!");
        } else if (score > 80) {
            tv_result.setText("你的人品不错..应该一表人才吧?");
        } else if (score > 60) {
            tv_result.setText("你有较好的人品..继续保持..");
        } else if (score > 50) {
            tv_result.setText("老实交待..那些论坛上面经常出现的偷拍照是不是你的杰作?");
        } else if (score > 30) {
            tv_result.setText("你的人品太差了。你应该有干坏事的嗜好吧?");
        } else if (score > 20) {
            tv_result.setText("杀过人没有?放过火没有?你应该无恶不做吧?");
        } else if (score > 10) {
            tv_result.setText("是我不好...不应该跟你谈人品问题的...");
        } else {
            tv_result.setText("不好意思,无法识别人品二字");
        }
    }

    @Override
    public void onBackPressed() {
        Intent intent = new Intent();
        intent.putExtra("score", score);
        setResult(RESULT_OK, intent);
        finish();
    }
}

批注:

当用户按下Back后退键,就回去执行onBackPressed()方法中的代码,我们重写这个方法再添加逻辑就行了。

这个activity接着在Manifest中添加<activity android:name=".ResultActivity" />就行了

activity_result.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
        android:id="@+id/tv_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="张三"/>
    <TextView
        android:id="@+id/tv_sex"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="男"/>
    <TextView
        android:id="@+id/tv_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="人品好"/>
</LinearLayout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <EditText
        android:id="@+id/et_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName"
        android:hint="请输入姓名"/>

    <RadioGroup
        android:id="@+id/radioGroup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/rb_male"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="男" />

        <RadioButton
            android:id="@+id/rb_female"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="女" />

        <RadioButton
            android:id="@+id/rb_other"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="人妖" />
    </RadioGroup>
    <Button
        android:onClick="click"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="计算"/>
</LinearLayout>

===========================Talk is cheap, show me the code===========================

猜你喜欢

转载自blog.csdn.net/qq_34115899/article/details/81633077
今日推荐