Wrong activity displayed when implicit intent received from another app with Action.SEND

144 Views Asked by At

I have an app with two activities: MainActivity, which contains a URL entry field where the user can enter a YouTube video URL and press a submit button, to start the second activity, VideoActivity, which displays some information about this video (fetched from another web server).

The app also has a feature to receive intent via the Youtube application. When user presses the share button within the Youtube app, my app appears in the share list. Upon pressing share from the Youtube app, MainActivity should be brought to the front, and the URL should be posted within the MainActivity's URL field.

However, this only happens correctly on the first share. If the app is in the background when user shares from Youtube app, they are taken to whatever the last visible activity was, whether it is MainActivity or VideoActivity, (and even if it is MainActivity, the URL is not posted into the URL field, but the field is left in whatever state it was in when the app was last visible).

Here is my current AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.youcmt.youdmcapp">
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity"
                  android:launchMode="singleTop">
            <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="text/plain"/>
            </intent-filter>
        </activity>
        <activity
            android:name=".VideoActivity"
            android:parentActivityName=".MainActivity"/>
        <service
            android:name=".FetchVideoService"
            android:exported="false"/>
    </application>

</manifest>

Here is my MainActivity.java code:

    public class MainActivity extends AppCompatActivity {
        private ResponseReceiver mReceiver;
        private EditText mUrlEditText;
        private Button mSearchButton;
        private ProgressBar mProgressBar;

        @Override
        protected void onCreate(Bundle savedInstanceState) {

            setContentView(R.layout.activity_main);
            super.onCreate(savedInstanceState);
            mUrlEditText = findViewById(R.id.url_search_et);
            Intent intent = getIntent();
            if (intent.getType()!=null &&
                    intent.getType().equals("text/plain")) {
                Bundle extras = getIntent().getExtras();
                String value = extras.getString(Intent.EXTRA_TEXT);
                if(value!=null)
                {
                    mUrlEditText.setText(value);
                }
            }
            mProgressBar = findViewById(R.id.progress_bar);
            mSearchButton = findViewById(R.id.search_button);
            mSearchButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    try {
                        askForVideo(mUrlEditText.getText().toString());
                        mSearchButton.setVisibility(View.INVISIBLE);
                        mProgressBar.setVisibility(View.VISIBLE);
                    } catch (Exception e) {
                        mUrlEditText.setText("");
                        mUrlEditText.setHint(e.getMessage());
                        e.printStackTrace();
                    }
                }
            });
        }

        @Override
        protected void onResume() {
            super.onResume();
            //register the ResponseReceiver
            mReceiver = new ResponseReceiver();
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(FETCH_VIDEO_INFO);
            registerReceiver(mReceiver, intentFilter);
        }

        private void askForVideo (String url) throws Exception {

            try {
                Intent intent = FetchVideoService.newIntent(this, url);
                startService(intent);
            } catch (Exception e) {
                mUrlEditText.setText(e.getMessage());
            }
        }

    public class ResponseReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            int status = intent.getIntExtra(EXTRA_VIDEO_STATUS, FAIL);
            mProgressBar.setVisibility(View.INVISIBLE);
            mSearchButton.setVisibility(View.VISIBLE);
            if(status==FAIL)
            {
                mUrlEditText.setText("");
                mUrlEditText.setHint("Error retrieving video!");
            }
            else if(status==SUCCESS) {
                Video video = intent.getParcelableExtra(EXTRA_VIDEO);
                Intent videoActivityIntent = 
 VideoActivity.newIntent(getApplicationContext(), video);
                startActivity(videoActivityIntent);
            }
        }
    }

    @Override
    protected void onPause() {
        unregisterReceiver(mReceiver);
        super.onPause();
    }
}

I do not think any of the other files will be useful in understanding the problem. Although this seems like something many app creators should have to deal with, I can find no answers to this problem. Please comment if you feel I should add any additional information and thank you in advance for any help!

Update: testing demonstrates that after the first use of "Share" from YouTube (and considering app remains in the background), the MainActivity no longer receives any new intent on further shares. However, my app is still brought to the foreground somehow. This is very confusing to me.

1

There are 1 best solutions below

1
On

When you share from another app, your MainActivity is brought to the front and onNewIntent() is called on it. You don't override onNewIntent() so you never see the share Intent.