1

I've binded 2 android applications with an AIDL file. The Exchange between the A and B applications is like below:

  • The A application connects to the B application through AIDL interface
  • A application calls a method of the B service
  • B service returns a PendingIntent
  • A application starts the PendingIntent
  • When action is finished in the B application : back to the A application

However, if the B application was launched before the exchange, user will be redirected to the last activity of the B application after calling the "finish()" method , not in the A application.

In my A application :

@Override
protected void onCreate(Bundle savedInstanceState) {

    ...
    Intent i = new Intent();
    i.setClassName(Utils.BILLING_PACKAGE,Utils.BILLING_INTERFACE);

    try {
       Boolean ret = bindService(i, mConnection, Context.BIND_AUTO_CREATE);
    } catch (Exception e) {}

}

//ServiceConnection class    
private ServiceConnection mConnection = new ServiceConnection() {

       public void onServiceConnected(ComponentName name, IBinder boundService) {
          service = InBillingInterface.Stub.asInterface((IBinder) boundService);
          Utils.debug(mContext, "connection status : "+ service );
    }

       public void onServiceDisconnected(ComponentName name) {
          service = null;
       }

};

...
//launch the second application
Bundle response = service.prepareForBillingService(data);
PendingIntent pIntent = response.getParcelable(Utils.RESPONSE_P_INTENT);

        try {
            Intent in = new Intent();
            in.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
            pIntent.send(mContext, 0, in);
        } catch (PendingIntent.CanceledException e) {
            Utils.error("Sending contentIntent failed:" + e.getMessage());
        }

I've tried to set android:launchMode to singleTask or singleTop in the A application manifest file but problem remains same. As you can see, I also put a "FLAG_ACTIVITY_MULTIPLE_TASK" flag when sending activity.

Code in my B application:

Creating the PendingActivity

public class InBillingService extends Service {

    private static final String TAG = "my tag";

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "Welcome!");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "Byebye!");
    }

    /**
     * Method for AIDL interface
     */
    @Override
    public IBinder onBind(Intent arg0) {

       return new InBillingInterface.Stub() {

          //a method that return a pendingIntent
          @Override
          public Bundle prepareForBillingService(String appId,String encryptedData) throws RemoteException {

             Bundle bundle = new Bundle();
             Intent intent = new Intent();   
             intent.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
             intent.setClass(InBillingService.this, xx.xxx.activities.BilingActivity.class);
             intent.putExtra(Consts.PENDING_INTENT_INFO, result);

             PendingIntent pendingIntent = PendingIntent.getActivity(InBillingService.this, 0, intent, 0);                         

             bundle.putParcelable(Consts.PENDING_INTENT, pendingIntent);

             return bundle ;

}

    };

    }

In the BillingActivity

//if no problems
finish()

Thank you for reading !

---update

My manifest file for the B activity :

  <activity
        android:name=".activities.BillingActivity"
        android:configChanges="orientation|keyboardHidden"
        android:launchMode="singleTask"
        android:label="@string/title_activity_billing" >
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
        </intent-filter>
    </activity>
johann
  • 1,115
  • 8
  • 34
  • 60
  • No idea for solving my problem ? I am in a hurry and I will appreciate your help. Thank you – johann Mar 21 '13 at 01:17
  • Isn't the B application a service? AIDL is normally used as an IPC in a client/server model. So I assume application A is the client and application B is the server in the form of a service. Why does application B have an activity associated with it? – Luis Apr 01 '13 at 04:27
  • B application contains a service that returns a pendingIntent for an activity in the B application. Is my explanation clear ? – johann Apr 01 '13 at 04:46
  • OK, I think I understand now what's going on. I think what you need to do is separate the service from the activities in application B. Can you post the code for the Service in application B? Which application is Billing Activity in? Are there three applications involved here: App A (makes requests), App B (responds to request), App C (launched from App A after App B responds)? Or is Billing Activity part of App A? – Luis Apr 01 '13 at 04:59
  • I have updated my service code. BillingActivity is in the B application. Thank you ! – johann Apr 01 '13 at 07:40
  • Is application B singleTask? Since application B started before application A in its own task, when application A calls Billing Activity in application B the entire back stack for application B comes forward on top of the current task for application A. Therefore, when Billing Activity finishes, it goes through the back stack of application B first. See figure 4 here: http://developer.android.com/guide/components/tasks-and-back-stack.html – Luis Apr 02 '13 at 03:02
  • If the above is the case here are my recommendations: replace Intent.FLAG_ACTIVITY_MULTIPLE_TASK with FLAG_ACTIVITY_NEW_TASK. This will cause Billing Activity to start in a new task but the activity will be the only activity in that task and, hence, when it finishes it should go back to application A. – Luis Apr 02 '13 at 03:11
  • Changing the launchMode in application A to singleTask or singleTop won't make a difference as the issue is that when Billing Activity is called (which is part of Application B) its current back stack its brought to the top of the task for application A. – Luis Apr 02 '13 at 03:13
  • Correction. Don't use any activity flags. Make the launch mode for the Billing Activity in application B singleInstance in the manifest. – Luis Apr 02 '13 at 04:19
  • Following your advices, I first tried to change flags, and set launchMode to singleTask but the same error has happened. I've finally removed all flags and set launchMode as you've told me, and now it works perfectly ! You deserve your 50 points reputations ! Thank you – johann Apr 02 '13 at 04:42
  • Could you tell me how to set this question as "resolved" ? – johann Apr 02 '13 at 04:43
  • Great! Glad I was able to help. Good luck on your project! – Luis Apr 02 '13 at 04:46

1 Answers1

2

In order to return to Application A after BillingActivity finishes in Application B, do the following:

In the manifest file for Application B, make the BillingActivity launchMode singleInstance like this:

<activity
    android:name="xx.xxx.activities.BillingActivity"
    android:launchMode="singleInstance" >
</activity>

Per this link:

The "singleTask" and "singleInstance" modes also differ from each other in only one respect: A "singleTask" activity allows other activities to be part of its task. It's always at the root of its task, but other activities (necessarily "standard" and "singleTop" activities) can be launched into that task. A "singleInstance" activity, on the other hand, permits no other activities to be part of its task. It's the only activity in the task. If it starts another activity, that activity is assigned to a different task — as if FLAG_ACTIVITY_NEW_TASK was in the intent.

Luis
  • 3,451
  • 1
  • 27
  • 41