zoukankan      html  css  js  c++  java
  • Android Intent对象使用和Activity间数据的传递

    在应用中,可能会在当跳转到另外一个Activity的时候需要传递数据过去,这时就可能用Bundle对象;

    在MainActivity中,有一个导航至BActivity的Intent,

      Intent intent = new Intent(Context context, Class<?> class);
      //new一个Bundle对象,并将要传递的数据导入,Bunde相当于Map<Key,Value>结构    
      Bundle bundle = new Bundle();
      bundle.putString("name","Livingstone");
      bundle.putXXX(XXXKey, XXXValue);
      //将Bundle对象添加给Intent
      intent.putExtras(bundle);
      //调用intent对应的Activity
      startActivity(intent);

    在BActivity中,通过以下代码获取MainActivity所传过来的数据

      Bundle bundle = this.getIntent().getExtras();// 获取传递过来的封装了数据的Bundle
      String name = bundle.getString("name");// 获取name_Key对应的Value
      // 获取值时,添加进去的是什么类型的获取什么类型的值
         --> bundle.getXXX(XXXKey);
           return XXXValue

    上面讲述的都是一般的基本数据类型,当需要传递对象的时候,可以使该对象实现Parcelable或者是Serializable接口;

    通过Bundle.putParcelable(Key,Obj)及Bundle.putSerializable(Key,Obj)方法将对象添加到Bundle中,再将此Bundle对象添加到Intent中!

    在跳转的目标页面通过Intent.getParcelableExtra(Key)获取实现了Parcelable的对象;
    在跳转的目标页面通过Intent.getSerializableExtra(Key)获取实现了Serializable的对象;

    今天在研究的时候发现,Intent.putExtra(Key,Value);其实也可以传递数据,包括上面所讲的对象!

    下面描述实现Parcelable接口:

    public class Book implements Parcelable {
        private String bookName;
        private String author;
    
        public static final Parcelable.Creator CREATOR = new Creator() {// 此处必须定义一个CREATOR成员变量,要不然会报错!
            @Override
            public Book createFromParcel(Parcel source) {// 从Parcel中获取数据,在获取数据的时候需要通过此方法获取对象实例
                Book book = new Book();
                book.setAuthor(source.readString());// 从Parcel读取数据,读取数据与写入数据的顺序一致!
                book.setBookName(source.readString());
                return book;
            }
            @Override
            public Book[] newArray(int size) {
                return new Book[size];
            }
        };
        @Override
        public int describeContents() {
            return 0;
        }
        @Override// 写入Parcel
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(author);// 将数据写入Parcel,写入数据与读取数据的顺序一样!
            dest.writeString(bookName);
        }
    }

     关于Parcel,大概查阅了一下描述:
     一个final类,用于写或读各种数据,所有的方法不过就是writeValue(Object)和read(ClassLoader)!(个人翻译理解)

     注:如果在关闭打开的Activity的时候希望返回数据给前一个Activity,需要在打开Activity的时候使用startActivityForResult(Intent intent, int requestCode)方法;设置请求码用于在OtherActivity结束的时候告诉MainActivity本类在什么地方调用了这个方法;

    如一个添加和一个删除,设置不同的请求码,然后对些请求码进行判断,即可得到OtherActivity是哪一个业务;

    在OtherActivity在OtherActivity中,this.finsh()之前要调用setResult(int resultCode,Intent data),供MainActivity得到结果数据时知道结果数据是哪一个OtherActivity业务返回来的;
    OtherActivity关闭后结果数据经过操作系统传递给MainActivity,再调用onActivityResult(int requestCode,int resultCode,Intent data){需要重写此方法}方法,获取数据结果,三个参数分别是|在MainActivity中的什么地方发起的请求|结果数据是在OtherActivity的哪一个业务|结果数据实体对象|

    Android设计理念就是减少组件之间的耦合,因此提供了Intent,Intent提供了一种通用的消息系统,它通话用户在应用程序也其它的应用程序间间传递Intent来执行动作和产生事件,使用Intent可能激活三种类型的组件:活动,服务,广播接收者;
    Intent分为显示意图和隐式意图
    显示意图:调用intent.setComponent()\setClassName()\setClass()方法指定了组件名,明确要激活的组件名称;
    隐式意图:没有明确指定组件名称,Android系统会根据隐式意图中设置的动作(action)、类别(category)、数据(URI和数据类型)找到最合适的组件来处理这个意图。

    对于显式Intent,Android不需要去做解析,因为目标组件已经很明确,Android需要解析的是那些隐式Intent,通过解析,将 Intent映射给可以处理此Intent的Activity、IntentReceiver或Service。
    Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有IntentFilter及其中定义的Intent,最终找到匹配的Intent。在这个解析过程中,Android是通过Intent的action、type、category这三个属性来进行判断的,判断方法如下:

    1. 如果Intent指明定了action,则目标组件的IntentFilter的action列表中就必须包含有这个action,否则不能匹配;
    2. 如果Intent没有提供type,系统将从data中得到数据类型。和action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配。
    3. 如果Intent中的数据不是content: 类型的URI,而且Intent也没有明确指定它的type,将根据Intent中数据的scheme (比如 http: 或者mailto:) 进行匹配。同上,Intent 的scheme必须出现在目标组件的scheme列表中。
    4. 如果Intent指定了一个或多个category,这些类别必须全部出现在组建的类别列表中。比如Intent中包含了两个类别:LAUNCHER_CATEGORY 和 ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。
        public void openActivity() {
            /*
             * (没有数据参数的情况下)只要Intent中的Action和Category都出现在Activity的Intent-Filter中,就能与之匹配
             */
            Intent i = new Intent();
            i.setAction("livingstone.action");
            i.addCategory("livingstone.category");
            i.setDataAndType(Uri.parse("livingstone://www.sina.com/mypath"), "image/jpeg");
            startActivity(i);// 方法内部会自动为Intent添加android.intent.category.DEFAULT类别
        }

    我们知道Intent的应用,可以启动别一个Activity,那么是否可以启动别外的一个应用程序呢,答案是可以的。

            anotherPro = (Button) findViewById(R.id.startAnotherPro);
            calendar = (Button) findViewById(R.id.startCalendar);
            anotherPro.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    intent.setComponent(new ComponentName("com.anotherpro", "com.anotherpro.MainActivity"));
                    startActivity(intent);
                }
            });
            calendar.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    intent.setComponent(new ComponentName("com.android.calendar", "com.android.calendar.LaunchActivity"));
                    startActivity(intent);
                }
            });
    Intent.setComponent(new ComponentName(packageName, mainActivityName));// 第一个参数为应用程序包名,第二个参数为程序启动的Activity,也可以用setClassName();

    下面是一些常用的Intent实例

    显示网页
       1. Uri uri = Uri.parse("http://google.com");  
       2. Intent it = new Intent(Intent.ACTION_VIEW, uri);  
       3. startActivity(it);
    
    显示地图
       1. Uri uri = Uri.parse("geo:38.899533,-77.036476");  
       2. Intent it = new Intent(Intent.ACTION_VIEW, uri);   
       3. startActivity(it);   
       4. //其他 geo URI 
       5. //geo:latitude,longitude  
       6. //geo:latitude,longitude?z=zoom  
       7. //geo:0,0?q=my+street+address  
       8. //geo:0,0?q=business+near+city  
       9. //google.streetview:cbll=lat,lng&cbp=1,yaw,,pitch,zoom&mz=mapZoom
    
    路径规划
       1. Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en");  
       2. Intent it = new Intent(Intent.ACTION_VIEW, uri);  
       3. startActivity(it);  
       4. //where startLat, startLng, endLat, endLng are a long with 6 decimals like: 50.123456 
    
    打电话
       1. //叫出拨号程序 
       2. Uri uri = Uri.parse("tel:0800000123");  
       3. Intent it = new Intent(Intent.ACTION_DIAL, uri);  
       4. startActivity(it);  
       1. //直接打电话出去  
       2. Uri uri = Uri.parse("tel:0800000123");  
       3. Intent it = new Intent(Intent.ACTION_CALL, uri);  
       4. startActivity(it);  
       5. //用這個,要在 AndroidManifest.xml 中,加上  
       6. //<uses-permission id="android.permission.CALL_PHONE" /> 
    
    传送SMS/MMS
       1. //调用短信程序 
       2. Intent it = new Intent(Intent.ACTION_VIEW, uri);  
       3. it.putExtra("sms_body", "The SMS text");   
       4. it.setType("vnd.android-dir/mms-sms");  
       5. startActivity(it); 
       1. //传送消息 
       2. Uri uri = Uri.parse("smsto://0800000123");  
       3. Intent it = new Intent(Intent.ACTION_SENDTO, uri);  
       4. it.putExtra("sms_body", "The SMS text");  
       5. startActivity(it); 
       1. //传送 MMS  
       2. Uri uri = Uri.parse("content://media/external/images/media/23");  
       3. Intent it = new Intent(Intent.ACTION_SEND);   
       4. it.putExtra("sms_body", "some text");   
       5. it.putExtra(Intent.EXTRA_STREAM, uri);  
       6. it.setType("image/png");   
       7. startActivity(it); 
    
    传送 Email
       1. Uri uri = Uri.parse("mailto:xxx@abc.com");  
       2. Intent it = new Intent(Intent.ACTION_SENDTO, uri);  
       3. startActivity(it); 
    
    
       1. Intent it = new Intent(Intent.ACTION_SEND);  
       2. it.putExtra(Intent.EXTRA_EMAIL, "me@abc.com");  
       3. it.putExtra(Intent.EXTRA_TEXT, "The email body text");  
       4. it.setType("text/plain");  
       5. startActivity(Intent.createChooser(it, "Choose Email Client")); 
    
    
       1. Intent it=new Intent(Intent.ACTION_SEND);    
       2. String[] tos={"me@abc.com"};    
       3. String[] ccs={"you@abc.com"};    
       4. it.putExtra(Intent.EXTRA_EMAIL, tos);    
       5. it.putExtra(Intent.EXTRA_CC, ccs);    
       6. it.putExtra(Intent.EXTRA_TEXT, "The email body text");    
       7. it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");    
       8. it.setType("message/rfc822");    
       9. startActivity(Intent.createChooser(it, "Choose Email Client"));
    
    
       1. //传送附件
       2. Intent it = new Intent(Intent.ACTION_SEND);  
       3. it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");  
       4. it.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/mysong.mp3");  
       5. sendIntent.setType("audio/mp3");  
       6. startActivity(Intent.createChooser(it, "Choose Email Client"));
    
    播放多媒体
           Uri uri = Uri.parse("file:///sdcard/song.mp3");  
           Intent it = new Intent(Intent.ACTION_VIEW, uri);  
           it.setType("audio/mp3");  
           startActivity(it); 
           Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1");  
           Intent it = new Intent(Intent.ACTION_VIEW, uri);  
           startActivity(it);
    
    Uninstall 应用程序
    1.        Uri uri = Uri.fromParts("package", strPackageName, null); 
    2.        Intent it = new Intent(Intent.ACTION_DELETE, uri);   
    3.        startActivity(it); 
  • 相关阅读:
    Android Studio插件
    android漂亮的对话框项目sweet-alert-dialog
    Android中Context详解 ---- 你所不知道的Context
    Bundle对象的使用
    Android利用Http下载文件
    文件缓存(配合JSON数组)
    android studio sqlite操作代码片段
    Android中使用ListView实现分页刷新(线程休眠模拟)(滑动加载列表)
    Android Studio 配置使用百度api (附带简单样例)
    9套Android实战经典项目资料分享给大家
  • 原文地址:https://www.cnblogs.com/a284628487/p/3021128.html
Copyright © 2011-2022 走看看