使用 Action.SEND 从另一个应用程序接收到隐式意图时显示错误的活动

Posted

技术标签:

【中文标题】使用 Action.SEND 从另一个应用程序接收到隐式意图时显示错误的活动【英文标题】:Wrong activity displayed when implicit intent received from another app with Action.SEND 【发布时间】:2019-03-12 05:52:39 【问题描述】:

我有一个包含两个活动的应用程序:MainActivity,其中包含一个 URL 输入字段,用户可以在其中输入 YouTube 视频 URL 并按下提交按钮,以启动第二个活动 VideoActivity,它显示有关此视频的一些信息 (从另一个 Web 服务器获取)。

该应用还具有通过 Youtube 应用接收意图的功能。当用户在 Youtube 应用程序中按下分享按钮时,我的应用程序会出现在分享列表中。在 Youtube 应用中按下分享后,MainActivity 应该被带到最前面,并且 URL 应该发布在 MainActivity 的 URL 字段中。

但是,这只会在第一次共享时正确发生。如果当用户从 Youtube 应用程序共享时应用程序在后台,他们将被带到最后可见的活动,无论是 MainActivity 还是 VideoActivity,(即使是 MainActivity,URL 也不会发布到 URL 字段中,但该字段仍处于应用上次可见时所处的任何状态)。

这是我当前的 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>

这是我的 MainActivity.java 代码:

    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();
    

我认为其他任何文件都不会有助于理解问题。尽管这似乎是许多应用程序创建者应该处理的问题,但我找不到这个问题的答案。如果您觉得我应该添加任何其他信息,请发表评论,并提前感谢您的帮助!

更新:测试表明,在首次使用 YouTube 上的“分享”后(并考虑到应用仍处于后台),MainActivity 不再收到任何关于进一步分享的新意图。但是,我的应用程序仍然以某种方式被带到了前台。这让我很困惑。

【问题讨论】:

【参考方案1】:

当您从另一个应用程序共享时,您的 MainActivity 会被带到最前面并调用 onNewIntent()。您不会覆盖 onNewIntent(),因此您永远不会看到共享 Intent

【讨论】:

感谢您的回答。只要 MainActivity 是最重要的活动,这有助于我使 MainActivity 正常运行:通过将 setIntent(intent) 放入 onNewIntent() 中,然后在 onResume() 中处理意图。但是,如果 VideoActivity 是最后一个可见 Activity,则在 either Activity 中调用 onNewIntent 并且行为仍然不正确(VideoActivity 仍然位于最前面)。我目前使用的解决方法是在 VideoActivity 的 onStop() 中调用 finish(),以便 MainActivity 在共享期间始终处于最前沿,但这不是最佳解决方案。

以上是关于使用 Action.SEND 从另一个应用程序接收到隐式意图时显示错误的活动的主要内容,如果未能解决你的问题,请参考以下文章

从另一个程序接收 JSON 编码信息到我的 GUI

iOS - 允许应用程序从另一个应用程序接收图像

让 Ionic 应用出现在“分享”列表中并接收数据

Android O 上的 android.intent.action.SEND - URI 包含 file:// 网址而不是 content://

php peepso→peepso_action_group_user_invitation_send

怎样将长整型(long int)通过单片机串口发送,从另一个单片机串口接收。