从url打开后如何清除Activity中的意图数据?

问题描述 投票:0回答:6

我有

Activity
,可以直接从浏览器启动,调用url。

活动代码:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Uri data = getIntent().getData();
        Log.d(getClass().getName(), "onCreate data=" + data);

        getIntent().replaceExtras(new Bundle());
        getIntent().setAction("");
        getIntent().setData(null);
        getIntent().setFlags(0);

        if (data != null && isValidUrl(data)) {
            // open some special fragment
        } else {
            // open main fragment
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(MainActivity.class.getName(), "onDestroy");
    }

    //...
}

应用程序清单代码:

    ...

    <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.VIEW"/>

            <category android:name="android.intent.category.DEFAULT"/>
            <category android:name="android.intent.category.BROWSABLE"/>

            <data
                android:host="example.com"
                android:pathPrefix="/"
                android:scheme="http"/>
        </intent-filter>
    </activity>

    ...

这段代码完美运行。当我使用链接 (

http://example.com/somepage.html
) 从浏览器打开应用程序时,我有以下输出:

D/com.package.MainActivity: onCreate data=http://example.com/somepage.html

但是,如果我离开应用程序(使用后退按钮)并再次打开应用程序,从最近的菜单中,我会得到相同的结果:

D/com.package.MainActivity: onDestroy
D/com.package.MainActivity: onCreate data=http://example.com/somepage.html

我想在方法

onCreate
中清除意图数据。或者有没有办法检测应用程序何时从最近的菜单启动?

更新: 我尝试这样做:

@Override
protected void onDestroy() {
    super.onDestroy();

    getIntent().replaceExtras(new Bundle());
    getIntent().setAction("");
    getIntent().setData(null);
    getIntent().setFlags(0);

    Log.d(MainActivity.class.getName(), "onDestroy");
}

但这并没有帮助。

android android-intent android-activity
6个回答
23
投票

这里很旧的线程,但万一其他人正在寻找这个:

您可以通过检查标志 FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY 来检查您的意图是否是由于应用程序从最近列表中启动而发送的

    if ((getIntent().getData() != null) && ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0)) {
            //Handle the url passed through the intent
        } else {
            //proceed as normal
        }

17
投票

通过以下代码删除intent.getData()

编辑1:

Uri data = getIntent().getData();
    Log.d(getClass().getName(), "onCreate data=" + data);

    if (data != null && isValidUrl(data)) {
        // open some special fragment
    } else {
        // open main fragment
    }

getIntent().setData(null);

编辑2:

getIntent().replaceExtras(new Bundle());
getIntent().setAction("");
getIntent().setData(null);
getIntent().setFlags(0);

希望这对您有帮助。


3
投票

你的做法违背了Android系统的原则。 Android 的设计是为了让

Intent
打开
Activity
,然后如果你想从“最近”菜单中打开这个
Activity
,它会收到相同的意图。

我只是猜测,如果您使用单活动多片段方法,那么您会看到它的缺点之一。 Android Intent 系统的设计方式是使用“One Screen - One Activity”方法,这是最佳实践。

如果我错了,而你还有其他案例,那么了解它会很有趣。然后你可能会想到如何重新设计应用程序来实现你的需求。


1
投票

您可以存储意图的哈希值,并在每次应用程序获得焦点时比较该哈希值,而不是更改意图数据。这样您就可以查看是否存在新意图。

示例:

int currentIntent = getIntent().hashCode();

if (lastIntent != currentIntent) {
    // do stuff
}

0
投票

我建议在

super.onCreate
:

之后立即运行此命令
if (intent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY != 0)
     intent.data = null

然后对意图数据的所有进一步检查都将返回 null,您将不必再为此烦恼。

如果你问我的话,从第一天起它就应该在 Android 上运行。如果有人知道为什么在从历史记录启动时一遍又一遍地重新触发相同意图是有意义的任何有效原因,请添加评论!


-1
投票

在你的 onCreate 方法中你有

if (data != null && isValidUrl(data)) {
// open some special fragment
} else {
// open main fragment
}

更改为

if (data != null && isValidUrl(data)) {
    // open some special fragment
    getIntent().setData(null);
    setIntent(getIntent()); //This will set the new intent to have no data,
    //so future launches won't relaunch the data url.
    } else {
    // open main fragment
    }
© www.soinside.com 2019 - 2024. All rights reserved.