10

i've tried to sending data between App1 to App2 via Intent in Android

i used this code but i couldn't resolve my problem.

App1 MainActivity :

        Intent i2 = new Intent("com.appstore.MainActivity");
        i2.setPackage("com.appstore");//the destination packageName
        i2.putExtra("Id", "100");
        startActivity(i2);

App2 MainActivity :

Bundle data = getIntent().getExtras;
if(data!=null){
    String myString = b.getString("Id");

}

Manfiest App2 MainActivity:

   <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="image/*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.SEND_MULTIPLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="image/*" />
            </intent-filter>

        </activity>
Farzad
  • 199
  • 1
  • 1
  • 5
  • 2
    Make use of [Content Providers](https://developer.android.com/guide/topics/providers/content-providers.html) for sending data between application. – Arshak Jul 27 '16 at 09:10
  • 3
    @Arshak content provider is probably overkill to send a `String` from one `Activity` to another. – David Wasser Jul 27 '16 at 10:08

6 Answers6

8

Final code:

App 1 :

        Intent intent = new Intent();
        intent.setClassName("com.appstore", "com.appstore.MyBroadcastReceiver");
        intent.setAction("com.appstore.MyBroadcastReceiver");
        intent.putExtra("KeyName","code1id");
        sendBroadcast(intent);

App 2:

Reciver:
public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Data Received from External App", Toast.LENGTH_SHORT).show();

    }
}

Manifest :

        <receiver
            android:name=".MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="first_app_packagename" />
            </intent-filter>
        </receiver>

MainActivity :

  MyBroadcastReceiver mReceiver = new MyBroadcastReceiver();
        registerReceiver(mReceiver,
                new IntentFilter("first_app_packagename"));
Gueorgui Obregon
  • 5,077
  • 3
  • 33
  • 57
Farzad
  • 199
  • 1
  • 1
  • 5
  • 5
    This may work for you, but you have way too much stuff in here and you probably don't understand why your code works. First of all, if you have an `` declared in the manifest, you do not need to specify `exported="true"` because that is the default, you do not need to specify `enabled="true"` because by default all components are enabled. Secondly, if you specify an `` in the manifest, you do not need to register the `BroadcastReceiver` by calling `registerReceiver()`. You do **either the one or the other, not both**. – David Wasser Jul 28 '16 at 07:50
  • 4
    Thirdly, both your `` declaration in the manifest and your use of `IntentFilter` in `registerReceiver()` are useless, because you never actually send a broadcast `Intent` that contains the ACTION "first_app_packagename". Fourthly, since you explicitly set the COMPONENT on the broadcast `Intent` using `setClassName()`, you do not need to set the ACTION in the broadcast `Intent`. That is also useless. – David Wasser Jul 28 '16 at 07:53
4

My requirement was to send the "user id" from App1 to App2 and get "username" back to App1.

I needed to launch my app directly without any chooser. I was able to achieve this using implicit intent and startActivityForResult.

App1 > MainActivity.java

private void launchOtherApp() {
    Intent sendIntent = new Intent();
    //Need to register your intent filter in App2 in manifest file with same action.
    sendIntent.setAction("com.example.sender.login"); // <packagename.login>
    Bundle bundle = new Bundle();
    bundle.putString("user_id", "1111");
    sendIntent.putExtra("data", bundle);
    sendIntent.setType("text/plain");
    if (sendIntent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(sendIntent, REQUEST_CODE);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_CODE) {
        if (resultCode == Activity.RESULT_OK) {
            Bundle bundle = data.getBundleExtra("data");
            String username = bundle.getString("user_name");
            result.success(username);
        }
    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }
}

I had two activity in App2 ie. MainActivity and LoginActivity.

App2 > AndroidManifest.xml

<activity android:name=".LoginActivity">
    <intent-filter>
        <!--The action has to be same as App1-->
        <action android:name="com.example.sender.login" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
</activity>

Sorry for this I had a little mix up with Java and Kotlin. My second app was in Kotlin, not that it will effect in any way.

App2 > LoginActivity.java

override fun onResume() {
    super.onResume()
    var userId = "No data received"
    val intent = intent
    if (intent != null
        && intent.action != null
        && intent.action.equals("com.example.sender.login")
    ) {
        val bundle = intent.getBundleExtra("data")
        if (bundle != null) {
            userId = bundle.getString("user_id")
            userId = " User id is $userId"
        }
    }
    tvMessage.text = "Data Received: $userId"
}

fun onClickBack(view: View) {
    val intent = intent
    val bundle = Bundle()
    bundle.putString("sesion_id", "2222")
    intent.putExtra("data", bundle)
    setResult(Activity.RESULT_OK, intent)
    finish()
}
adiga
  • 34,372
  • 9
  • 61
  • 83
Rana Ranvijay Singh
  • 6,055
  • 3
  • 38
  • 54
3

When you do this:

    Intent i2 = new Intent("com.appstore.MainActivity");
    i2.setPackage("com.appstore");//the destination packageName
    i2.putExtra("Id", "100");
    startActivity(i2);

you are calling the single-argument constructor of Intent. In this constructor, the argument is interpreted as the Intent ACTION. You then set the package name in the Intent.

When you call startActivity() with this Intent, Android will look for an Activity that contains an <intent-filter> with the specified ACTION. There are no installed applications that have an Activity defined like this in the manifest:

<activity>
    <intent-filter>
        <action android:name="com.appstore.MainActivity"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

So Android will not be able to find and launch the Activity that you want.

As you want to specify explicitly the component that you want to use, instead of using the 1-argument Intent constructor, you should do this instead:

    Intent i2 = new Intent();
    i2.setClassName("com.appstore", "com.appstore.MainActivity");
    i2.putExtra("Id", "100");
    startActivity(i2);

Using setClassName() you provide the package name and the class name of the component that you want to launch.

David Wasser
  • 93,459
  • 16
  • 209
  • 274
1

This should work:

APP1

    Intent i2 = new Intent();
    i2.setComponent(new ComponentName(PACKAGE,ACTIVITY));//the destination packageName
    i2.putExtra("Id", "100");
    startActivity(i2);
    

APP2

    String myString = getIntent().getStringExtra("Id");
DiLDoST
  • 335
  • 3
  • 12
0

Using Bundle.putSerializable(Key,Object); and Bundle.putParcelable(Key, Object); the former object must implement Serializable, and the latter object must implement Parcelable.

samm
  • 620
  • 10
  • 22
  • how to put bundle Bundle.putSerializable(Key,Object); inside intent? – Farzad Jul 27 '16 at 09:19
  • Because `String` has implemented `Serializable`, `i2.putExtra("Id", "100");` is ok. But, to start a explicit Activity, use `i2.setClassName("com.appstore" "com.appstore.MainActivity"); instead. – samm Jul 27 '16 at 09:45
0

Content providers:

Content providers are the standard interface that connects data in one process with code running in another process.

See Android Docs.

Content provider working demo here.

Sohail Zahid
  • 8,099
  • 2
  • 25
  • 41
  • i find this example. http://infobloggall.com/2015/04/14/communication-between-two-applications-in-android-using-messenger/ – Farzad Jul 27 '16 at 10:01