Intent

Intents are small messages that can be passed around the Android system. These messages hold information about our intention to perform some task.

From Android developers: It is basically a passive data structure holding an abstract description of an action to be performed.

Getting a result from another Activity

By using startActivityForResult(Intent intent, int requestCode)you can start another Activity and then receive a result from that Activity in the onActivityResult(int requestCode, int resultCode, Intent data) method. The result will be returned as an Intent.


In this example MainActivity will start a DetailActivity and then expect a result from it. Each request type should have its own int request code, so that in the overridden onActivityResult(int requestCode, int resultCode, Intent data) method in MainActivity , it can be determined which request to process by comparing values of requestCode and REQUEST_CODE_EXAMPLE (though in this example, there is only one).

MainActivity:

public class MainActivity extends Activity {

// Use a unique request code for each use case private static final int REQUEST_CODE_EXAMPLE = 0x9345; @Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    // Create a new instance of Intent to start DetailActivity    final Intent intent = new Intent(this, DetailActivity.class);    // Start DetailActivity with the request code    startActivityForResult(intent, REQUEST_CODE_EXAMPLE);}// onActivityResult only get called // when the other Activity previously started using startActivityForResult@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) {    super.onActivityResult(requestCode, resultCode, data);    // First we need to check if the requestCode matches the one we used.    if(requestCode == REQUEST_CODE_EXAMPLE) {        // The resultCode is set by the DetailActivity        // By convention RESULT_OK means that whatever        // DetailActivity did was executed successfully        if(resultCode == Activity.RESULT_OK) {            // Get the result from the returned Intent            final String result = data.getStringExtra(DetailActivity.EXTRA_DATA);            // Use the data - in this case, display it in a Toast.            Toast.makeText(this, "Result: " + result, Toast.LENGTH_LONG).show();        } else {            // setResult wasn't successfully executed by DetailActivity             // Due to some error or flow of control. No data to retrieve.        }    }}}

A few things you need to be aware of:

  • Data is only returned once you call finish(). You need to call setResult() before calling finish(), otherwise, no result will be returned.

  • Make sure your Activity is not using android:launchMode=”singleTask”, or it will cause the Activity to run in a separate task and therefore you will not receive a result from it. If your Activity uses singleTask as launch mode, it will call onActivityResult() immediately with a result code of Activity.RESULT_CANCELED.

  • Be careful when using android:launchMode=”singleInstance”. On devices before Lollipop (Android 5.0, API Level 21), Activities will not return a result.

  • You can use explicit or implicit intents when you call startActivityForResult(). When starting one of your own activities to receive a result, you should use an explicit intent to ensure that you receive the expected result. An explicit intent is always delivered to its target, no matter what it contains; the filter is not consulted. But an implicit intent is delivered to a component only if it can pass through one of the component’s filters.

Passing data between Activites

This example illustrates sending a String with value as “Some data!” from OriginActivity to DestinationActivity.


OriginActivity

public class OriginActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_origin);    // Create a new Intent object, containing DestinationActivity as target Activity.    final Intent intent = new Intent(this, DestinationActivity.class);    // Add data in the form of key/value pairs to the intent object by using putExtra()    intent.putExtra(DestinationActivity.EXTRA_DATA, "Some data!");    // Start the target Activity with the intent object    startActivity(intent);}} 

DestinationActivity
public class DestinationActivity extends AppCompatActivity {

public static final String EXTRA_DATA = "EXTRA_DATA";@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_destination);    // getIntent() returns the Intent object which was used to start this Activity    final Intent intent = getIntent();    // Retrieve the data from the intent object by using the same key that    // was previously used to add data to the intent object in OriginActivity.    final String data = intent.getStringExtra(EXTRA_DATA);}}

It is also possible to pass other primitive data types as well as arrays, Bundle and Parcelable data. Passing Serializable is also possible, but should be avoided as it is more than three times slower than Parcelable.

Serializable is a standard Java interface. You simply mark a class as Serializable by implementing the Serializable interface and Java will automatically serialize it during required situations.

Parcelable is an Android specific interface which can be implemented on custom data types (i.e. your own objects / POJO objects ), it allows your object to be flattened and reconstruct itself without the destination needing to do anything.

Once you have a parcelable object you can send it like a primitive type , With an intent object:

intent.putExtra(DestinationActivity.EXTRA_DATA, myParcelableObject);

Or in a bundle / as an argument for a fragment

bundle.putParcelable(DestinationActivity.EXTRA_DATA, myParcelableObject);

and then also read it from the intent at the destination using getParcelableExtra :

final MyParcelableType data = intent.getParcelableExtra(EXTRA_DATA); 

Or when reading in a fragment from a bundle :

final MyParcelableType data = bundle.getParcelable(EXTRA_DATA);

Once you have a Serializable object you can put it in an intent object :

bundle.putSerializable(DestinationActivity.EXTRA_DATA, mySerializableObject);

and then also read it from the intent object at the destination as shown below:

final SerializableType data = (SerializableType)bundle.getSerializable(EXTRA_DATA); 

Open a URL in a browser

Opening with the default browser

public void onBrowseClick(View v) {String url = "http://www.google.com";Uri uri = Uri.parse(url);Intent intent = new Intent(Intent.ACTION_VIEW, uri);// Verify that the intent will resolve to an activityif (intent.resolveActivity(getPackageManager()) != null) {    // Here we use an intent without a Chooser unlike the next example    startActivity(intent);} }   

Prompting the user to select a browser

Note that this example uses the Intent.createChooser() method:

public void onBrowseClick(View v) {String url = "http://www.google.com";Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));// Note the Chooser below. If no applications match, // Android displays a system message.So here there is no need for try-catch.startActivity(Intent.createChooser(intent, "Browse with"));}

In some cases, the URL may start with “www”. If that is the case you will get this exception:

android.content.ActivityNotFoundException : No Activity found to handle Intent

The URL must always start with “http://” or “https://”. Your code should therefore check for it, as shown in the following code snippet:

if (!url.startsWith("https://") && !url.startsWith("http://")){url = "http://" + url;}Intent openUrlIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));if (openUrlIntent.resolveActivity(getPackageManager()) != null) {startActivity(openUrlIntent);} 

Best Practices

Check if there are no apps on the device that can receive the implicit intent. Otherwise, your app will crash when it calls startActivity(). To first verify that an app exists to receive the intent, call resolveActivity() on your Intent object. If the result is non-null, there is at least one app that can handle the intent and it’s safe to call startActivity(). If the result is null, you should not use the intent and, if possible, you should disable the feature that invokes the intent.

Making a custom object Parcelable

public class Foo implements Parcelable

{
private final int myFirstVariable;
private final String mySecondVariable;
private final long myThirdVariable;

public Foo(int myFirstVariable, String mySecondVariable, long myThirdVariable){    this.myFirstVariable = myFirstVariable;    this.mySecondVariable = mySecondVariable;    this.myThirdVariable = myThirdVariable;}// Note that you MUST read values from the parcel IN THE SAME ORDER that// values were WRITTEN to the parcel! This method is our own custom method// to instantiate our object from a Parcel. It is used in the Parcelable.Creator variable we declare below.public Foo(Parcel in){    this.myFirstVariable = in.readInt();    this.mySecondVariable = in.readString();    this.myThirdVariable = in.readLong();}// The describe contents method can normally return 0. It's used when// the parceled object includes a file descriptor.@Overridepublic int describeContents(){    return 0;}@Overridepublic void writeToParcel(Parcel dest, int flags){    dest.writeInt(myFirstVariable);    dest.writeString(mySecondVariable);    dest.writeLong(myThirdVariable);}// Note that this seemingly random field IS NOT OPTIONAL. The system will// look for this variable using reflection in order to instantiate your// parceled object when read from an Intent.public static final Parcelable.Creator CREATOR = new Parcelable.Creator(){    // This method is used to actually instantiate our custom object    // from the Parcel. Convention dictates we make a new constructor that    // takes the parcel in as its only argument.    public Foo createFromParcel(Parcel in)    {        return new Foo(in);    }    // This method is used to make an array of your custom object.    // Declaring a new array with the provided size is usually enough.    public Foo[] newArray(int size)    {        return new Foo[size];    }};}

更多相关文章

  1. 代码中设置drawableleft
  2. android 3.0 隐藏 系统标题栏
  3. Android开发中activity切换动画的实现
  4. Android(安卓)学习 笔记_05. 文件下载
  5. Android中直播视频技术探究之—摄像头Camera视频源数据采集解析
  6. 技术博客汇总
  7. android 2.3 wifi (一)
  8. AndRoid Notification的清空和修改
  9. Android中的Chronometer

随机推荐

  1. 为菜鸟量身定制0基础android逆袭课程(颠覆
  2. 一分钟帮你提升Android(安卓)studio 编译
  3. 高效android编程
  4. 34、Android编写应用-从模板添加代码
  5. Android手机硬件信息的查看和软件安装方
  6. 自己实现的android树控件,android TreeVie
  7. Android(安卓)三种常用实现自定义圆形进
  8. [置顶] Android(安卓)动画:你真的会使用插
  9. unbuntu 14.04下NDK环境的搭建以及无法设
  10. android 视频和图片切换并进行自动轮播