8

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?

qefzec
  • 1,360
  • 1
  • 13
  • 13
  • 1
    can you post the code of the two activities? – Ariel Magbanua Sep 23 '13 at 18:26
  • startActivityForResult should work... Problem seems to be within your code – Selvin Sep 23 '13 at 18:35
  • It seems for me this is not possible with startActivityForResult(). It works between Activities of the same app, even with different packages, but not with two different Applications. See [link](http://stackoverflow.com/questions/11919259/how-to-get-startactivityforresult-on-external-activity-to-work) – qefzec Sep 25 '13 at 08:37
  • remove `` part from manifest – Selvin Sep 26 '13 at 08:28

6 Answers6

2

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/

Code_Yoga
  • 2,968
  • 6
  • 30
  • 49
1

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

Ranjit
  • 5,130
  • 3
  • 30
  • 66
  • For me it seems kinda sad, that I have to set up a ContentProvider to send two or three Strings back. However, this appears to be the most elegant solution. – qefzec Sep 25 '13 at 08:40
  • Its just a suggesting way for you. you can try other answers also. sharedpreference is a good way also. it depends on your requirements that what and how you are going to use. thank you – Ranjit Sep 25 '13 at 08:50
0

SharedPreferences might help you in this regard.

Sash_KP
  • 5,551
  • 2
  • 25
  • 34
  • Hmm would that be a clean way to pass (no need to store) data? So just declare a SharedPreference in one app and use it for both applications? – qefzec Sep 23 '13 at 18:35
  • The data will be _stored_ locally if you use [SharedPreferences](http://developer.android.com/reference/android/content/SharedPreferences.html).For any particular set of preferences, there is a single instance of this class that all clients share.So modified once,the modified value reflects everywhere.That way data is accessed.I prefer this one than data passing(using intent,putExtra etc). – Sash_KP Sep 24 '13 at 12:14
0

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>
David M
  • 2,511
  • 1
  • 15
  • 18
  • That works when you pass data to App2, but you can't pass something back can you? When I tried that, a RESULT_CANCELED event at onActivityResult returned immediately – qefzec Sep 23 '13 at 18:44
  • yes...i act on the data (in App2) and pass it back to App1. again, in a bundle...i've turned off my dev machine so i cannot remember the exact way i did it...but it's `standard` (in the docs). App1 picks up in `onActivityResult(xxx, yyy, data)` – David M Sep 23 '13 at 18:46
  • app1 and app2 are not on the same package? I tried your way but it doesn't work for me. I will provide my code above – qefzec Sep 24 '13 at 07:50
  • in App2's `onFinish()` i create another Intent that has the data i'm passing back. to return to the calling app (App1) i then call `setResult(RESULT_OK, returnIntent);` unless, of course, i came across an error then i return to App1 with `setResult(RESULT_CANCELED);` – David M Sep 24 '13 at 14:12
  • I'm not sure what I am doing wrong ... could you maybe provide all the relevant excerpts with Manifests? I would really like to know, what I'm doing wrong ... – qefzec Sep 24 '13 at 14:41
  • sorry, my development machine is not on a network...are you setting the return code? i.e. `setResult(RESULT_OK, returnIntent);`? i'm not sure what the default is if you leave that out. – David M Sep 24 '13 at 14:45
  • Also, a minor difference from my code to yours is that you call `finish();` after setting the return code. I have overridden `finish()`...set the return code in there...then call `super.finish();` dunno if that makes a difference, though. – David M Sep 24 '13 at 14:49
  • When I try your code @DavidM I am unable to run successfully, I get an error stating no such Activity ... Intent i = new Intent("com.xxx.yyy.MESSAGE");<-- does this mean: package name.ActivityName ? I do this and keep getting same error. – LizG Apr 02 '18 at 23:31
0

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.

MikeL
  • 5,385
  • 42
  • 41
0
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

  • The question was pretty clear. How to pass data between two different applications. Your case will work for two different activities. – vgokul129 Dec 08 '17 at 21:31