How to pass data both ways between different andro

2019-03-27 17:02发布

What's the easiest way to pass string variables from one application to another and also return values back? I have access to the source code of both apps, but it has to be two different applications.

I tried with startActivityForResult, but this only seems to work between activies of the same application. When calling an activity from a different package, startActivityForResult returns immediately with RESULT_CANCELED. There seems to be the possibility to solve this with a Service, but isn't that a bit oversized for just some string vars?

Is there an easy and clean way to do this?

Here the code i tried to use for startActivityForResult:

//App A:
            Intent intent = new Intent();
            intent.setAction("com.example.testapp.MESSAGE");
            Bundle b = new Bundle();
            b.putString("loginToken", "263bhqw3jhf6as4yf8j0agtz8h2hj2z9j3hg3g3ggh34uzh2h2ui78h3i9wdnj89x");
            intent.putExtra("MyData", b);

            startActivityForResult(intent, TEST_REQUEST);

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("pairing", "onActivityResult called");
    // Check which request we're responding to
    if (requestCode == TEST_REQUEST) {
        // Make sure the request was successful
        Log.d("pairing", "got result, resultCode: " + resultCode);
        if (resultCode == RESULT_OK) {
            // The Intent's data Uri identifies which contact was selected.
            if (data.hasExtra("returnMessage")) {
                Toast.makeText(this, data.getExtras().getString("returnMessage"), Toast.LENGTH_LONG).show();
            }

        }
    }
}


            // App B:
        Intent result = new Intent();
        Bundle b = new Bundle();
        b.putString("returnValue", "this is the returned value");
        result.putExtra("MyData", b);
        setResult(Activity.RESULT_OK, result);
        Log.d("pairing", "RESULT_OK set");
        finish();


//App B Manifest
        <activity
        android:name="com.example.testapp"
        android:launchMode="singleTop"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustPan" >
        <intent-filter>
            <action android:name="com.example.testapp.MESSAGE" />

            <category android:name="android.intent.category.DEFAULT" />

            <data android:mimeType="text/plain" />
        </intent-filter></activity>

Anybody seeing the mistake? App B always returns immediately with RESULT_CANCELED

EDIT: Right now I'm getting a android.content.activitynotfoundexception no activity found to handle intent { act=com.example.testapp.MESSAGE (has extras) } error. What am I doing wrong?

6条回答
在下西门庆
2楼-- · 2019-03-27 17:29

SharedPreferences might help you in this regard.

查看更多
可以哭但决不认输i
3楼-- · 2019-03-27 17:34

You can exchange messengers between two services that belong to those apps (even if the apps are from two different packages) and communicate using those messengers.

查看更多
何必那么认真
4楼-- · 2019-03-27 17:43

AIDL is one means of communication between two different applications using Interfaces

http://developer.android.com/guide/components/aidl.html

You can find a working sample in the below tutorial http://manishkpr.webheavens.com/android-aidl-example/

查看更多
可以哭但决不认输i
5楼-- · 2019-03-27 17:46

you can use ContentProvider.This is a better way than others.

查看更多
贪生不怕死
6楼-- · 2019-03-27 17:48

I have two apps that i pass data to/from.

App1...
Intent i = new Intent("com.xxx.yyy.MESSAGE");
Bundle b = new Bundle();
b.putString("AAA", getAAA());
i.putExtra("MyData", b);
startActivityForResult(i, "myProcess");

nothing fancy there...

App2...in onResume()...

 Intent i = getIntent();
 if (i != null && i.getAction().equals("com.xxx.yyy.MESSAGE") {
    ...get the data from the bundle
 }

note that the AndroidManifest.xml (for App2) has the following entries for one of the activities

 <intent-filter>
    <action android:name="com.xxx.yyy.MESSAGE"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:mimeType="text/plain"/>
 </intent-filter>
查看更多
混吃等死
7楼-- · 2019-03-27 17:55
public class MyParcelable implements Parcelable {
    // You can include parcel data types
    private int mData;
    private String mName;

    // We can also include child Parcelable objects. Assume MySubParcel is such a Parcelable:
    private MySubParcelable mInfo;

    // This is where you write the values you want to save to the `Parcel`.  
    // The `Parcel` class has methods defined to help you save all of your values.  
    // Note that there are only methods defined for simple values, lists, and other Parcelable objects.  
    // You may need to make several classes Parcelable to send the data you want.
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mData);
        out.writeString(mName);
        out.writeParcelable(mInfo, flags)
    }

    // Using the `in` variable, we can retrieve the values that 
    // we originally wrote into the `Parcel`.  This constructor is usually 
    // private so that only the `CREATOR` field can access.
    private MyParcelable(Parcel in) {
        mData = in.readInt();
        mName = in.readString();
        mInfo = in.readParcelable(MySubParcelable.class.getClassLoader());
    }

    public MyParcelable() {
        // Normal actions performed by class, since this is still a normal object!
    }

    // In the vast majority of cases you can simply return 0 for this.  
    // There are cases where you need to use the constant `CONTENTS_FILE_DESCRIPTOR`
    // But this is out of scope of this tutorial
    @Override
    public int describeContents() {
        return 0;
    }

    // After implementing the `Parcelable` interface, we need to create the 
    // `Parcelable.Creator<MyParcelable> CREATOR` constant for our class; 
    // Notice how it has our class specified as its type.  
    public static final Parcelable.Creator<MyParcelable> CREATOR
            = new Parcelable.Creator<MyParcelable>() {

        // This simply calls our new constructor (typically private) and 
        // passes along the unmarshalled `Parcel`, and then returns the new object!
        @Override
        public MyParcelable createFromParcel(Parcel in) {
            return new MyParcelable(in);
        }

        // We just need to copy this and change the type to match our class.
        @Override
        public MyParcelable[] newArray(int size) {
            return new MyParcelable[size];
        }
    };
}

READ HERE

查看更多
登录 后发表回答