摘要
我正在尝试通过“共享”菜单从用户发送数据。在这种情况下,我将使用基本的Android网络浏览器选择文本,然后将其分享到我的应用程序。
问题
用户第一次共享文本我的应用程序按预期获取文本并通过 Log.d()显示它 - 请参阅 handleSendText()方法下面的代码。
但是,每次此后,即使用户在Web浏览器中选择了新文本并与我的应用程序共享,我仍然可以获得用户选择的原始文本(之前的值)。
问题
你如何重置意图 - 或者它是什么 - 以便我可以获得用户在第一次选择之后选择的新文本?
详情
我的应用程序有一个MainActivity,我跟着Google文档: http://developer.android.com/training/sharing/receive.html
使用我的MainActivity中的以下代码
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("text/plain".equals(type)) {
handleSendText(intent, "onCreate"); // Handle text being sent
}
}
}
@Override
public void onResume(){
super.onResume();
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("text/plain".equals(type)) {
handleSendText(intent, "onResume"); // Handle text being sent
}
}
}
void handleSendText(Intent intent, String callingMethodName) {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
if (sharedText != null) {
Log.d("MainActivity", "sharedText : " + sharedText + " called from : " + callingMethodName);
}
}
}
我的AndroidManifest活动部分添加了过滤器,如:
<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="text/plain" />
</intent-filter>
</activity>
使用屏幕和日志进行直播
注意:请注意我已经在我的应用中实现了onResume(),以确保在调用onCreate()时我不会只获取Intent(仅限)一次应用程序启动时。)
启动浏览器并抓取文字&#34;飓风&#34;。
选择要与之分享的应用(我们的测试应用)。
查看日志并注意调用onCreate()和onResume()并且值为&#39;飓风&#39;
再次返回浏览器以分享更多文字...
选择要分享的新单词Atlantic。
额外注意:当我们点击此分享链接时,Android MenuChooser不会显示,而是会再次自动打开GrabText。我发现这种行为有点奇怪。
请注意,Intent文本仍然具有飓风的值。您可以看到logcat中现在有两个新条目。
尝试的解决方法解决方案
我发现我可以通过覆盖 onPause()并在我的Activity上调用 finish()来完全破坏应用程序(从而关闭整个应用程序)工作,但是有没有其他方法来重置Intent或相关文本或什么?
您是否知道有任何其他方法可以确保检索到新数据? 我感谢任何帮助。
更新 注意:我正在更新,因为没有很好的方式来展示尝试的其他代码,但是,如果没有来自其他SO用户的输入,我也不会知道这样做, CommonsWare 。
我收到的第一个答案是我应该添加 @Override onNewIntent(),所以我将以下代码添加到我的MainActivity中:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.d("MainActivity", "onNewIntent()...");
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("text/plain".equals(type)) {
handleSendText(intent, "onNewIntent"); // Handle text being sent
}
}
}
在添加该代码并运行并尝试复制然后第二次复制新单词后,我仍然在logcat中看到以下内容:
它甚至看起来好像甚至没有调用 onNewItent()方法。
编辑2
我更改了模拟器设置...开发人员选项...并关闭了“不要保持活动”#34;设置。之前已打开(已选中)。
之后,我运行了包含 onNewIntent()覆盖的应用程序,但现在它只显示了一个 onCreate()消失了(这是有意义的,因为活动是仍然加载)但仍然没有显示onNewIntent()调用。 在这个示例中,我捕获了“#n残余&#34;”这个词。
编辑3
我构建了应用程序并创建了一个APK并将其部署到我的三星Galaxy Core Prime,我得到了相同的结果。 onNewIntent() 从不被调用。
我只是查看了Google文档中的NewIntent,并声明:
onNewIntent(意图意图)这是调用设置的活动 在他们的包中启动模式到&#34; singleTop&#34; ,或者如果客户端使用了 调用startActivity(Intent)时的FLAG_ACTIVITY_SINGLE_TOP标志。
我还没有设置singleTop,所以我现在就试试吧。嗯...
编辑4
我现在尝试过singleTop变体。我之前在模拟器上测试API 15(v4.0.4),所以我切换到API 21(v5.0),看看是否有任何不同。
以下是singleTop添加到我的AndroidManifest.xml中的内容:
<activity android:name=".MainActivity" android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
注意我还将两个intent-filter节点折叠成一个。
所选文字已更改
在Android API Level 21上,每当我在浏览器中选择文本时,Intent文本现在都会有所不同。
onNewIntent永远不会被调用
然而,onNewIntent永远不会被调用。我永远不会看到它。
每次都显示共享菜单
此外,现在(在API 21上)每次选择文本时都会看到“共享”菜单。 但是,当我切换到浏览器时,我也看到了一件有趣的事情。您可以在列表中看到活动的多个副本。什么?!
另请注意,我将MainActivity实现为ListView(可滚动),因此我甚至可以在没有logcat的情况下看到条目(用于在真实设备上运行)。这使得其他方面显而易见:ListView正在每个新显示的Activity上更新。但实际上,它应该是附加到的原始活动。
创建大量GrabText活动 是的,现在每次选择文本时它都会创建一个新的GrabText Activity窗口。我想也许是因为我有singleTop设置所以我删除了它,但即使在API LEVEL 21上删除singleTop后它们仍然出现。
现在我看到它工作了 - 每次在API 21上提供不同的文本我决定切换回API Level 15模拟器并尝试它。
在我再次尝试API级别15后,我会报告回来。
API级别15:再次测试
我启动了另一个运行API Level 15的模拟器并运行了应用程序,即使使用singleTop设置,该值也永远不会更新。
您可以在logcat和更新的ListView上看到这一点:
您还可以看到代码的行为完全不同,但我没有更改任何内容,因为它附加到api级别15上运行的Activity的ListView。
我已经写了一本关于这个记录非常严重的事情的书。我希望这可以帮助某人和谷歌Android开发人员看到并解释它。
答案 0 :(得分:0)
如果您的活动已经存在,系统会使用onNewIntent()
而不是onCreate()
来调用它。 onNewIntent()
将通过您需要用于邮件的Intent
。
答案 1 :(得分:0)
尝试将manifest.xml中的android:launchMode活动更改为 的 singleTop 强>
这样,如果活动已经启动,将在 onNewIntent ()方法中收到新的意图
答案 2 :(得分:0)
实际上只有一个答案可行,但它可能会导致其他问题。
只要Activity进入onPause(),你就必须决定调用finish()。
这是我实施的确切代码,适用于所有API级别。
@Override
public void onPause(){
super.onPause();
finish();
}
销毁活动
当您添加该代码时,每次切换回您正在共享的应用程序(在我们的示例中为Web浏览器),然后onPause将触发您的MainActivity,而finish()方法将设置Activity以进行销毁。
此后每次显示共享菜单
每次从共享应用程序(Web浏览器)中选择文本时都会使用此解决方案,然后将显示“共享”菜单,并将GrabText显示为其中一个选项(而不是自动强制GrabText再次显示在前面)。
共享文字始终是新文字
由于MainActivity被完全销毁,因此必须再次完全加载(onCreate()),因此它会收到已发送的新Intent文本。
不是一个好的解决方法
然而,这并不是一个很好的解决方法,因为我相信你的应用中的对话框也会创建onPause()来调用你的Activity会被销毁。显然,破坏你的Activity onPause()并不是因为你开始管理&#34;记忆&#34;以一种真正应该留给操作系统的方式。但是,在这种情况下,它似乎是解决问题的唯一方法。