如何添加自定义代码以共享意图

时间:2016-01-19 13:33:53

标签: android android-actionbar

我在我正在试验的测试应用程序中实现了相当开箱即用的ShareActionProvider设置(使用support.v7.widget版本)。虽然它工作正常,我想运行一个小的自定义代码 - 在这种情况下只是一个内部统计计数器类型的功能来记录在特定项目上点击“共享”的次数。 (我从其他答案中了解到,没有一种可靠的方法来确定共享意图的成功,更不用说分享它的位置了,所以这似乎已经是最后的手段。)onOptionsItemSelected方法似乎没有在此运行情况。

这是我菜单的相关部分:

<item
    android:id="@+id/action_share"
    android:icon="@android:drawable/ic_menu_share"
    android:title="Share via"
    app:actionProviderClass="android.support.v7.widget.ShareActionProvider"
    app:showAsAction="ifRoom" />

完整的onCreateOptionsMenu:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);

    MenuItem shareItem = menu.findItem(R.id.action_share);
    mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareItem);
    Intent shareIntent = new Intent(Intent.ACTION_SEND);
    shareIntent.setType("text/plain");
    shareIntent.putExtra(Intent.EXTRA_SUBJECT, "FOO");
    shareIntent.putExtra(Intent.EXTRA_TEXT, "FOO");

    mShareActionProvider.setShareIntent(shareIntent);

    return true;
}

在其他操作栏项目中,我通常会在onOptionsItemSelected中执行类似的操作,但在这种情况下它不会被调用...

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    Integer id = item.getItemId();
    Log.d("MainActivity", "id = " + id);
    Log.d("MainActivity", "shareid = " + R.id.action_share);
    Log.d("MainActivity", "Why won't this happen?");

    if (id.equals(R.id.action_share)) {
        Log.d("MainActivity", "Why won't this happen? 2");
    }

    return super.onOptionsItemSelected(item);
}

编辑:我认为到目前为止的对话正在咆哮错误的树,就像我点击上面(修订版)onOptionsItemSelected中的共享图标 nothing 一样(日志级别详细),虽然弹出了共享列表,这似乎证实了我的理论,即ShareActionProvider根本没有调用此方法。

编辑2:我现在修改了onCreateMenuOptions以使其与here完全一样,但使用MenuItemCompat除外 - 您可以看到活动的完整来源{{3 }}。但是,onOptionsItemSelected中没有记录任何内容。我进一步尝试在同一个菜单中添加另一个项目,除了在选择时记录消息之外什么都不做,这样就可以了。

2 个答案:

答案 0 :(得分:0)

如果你的问题是那个

Log.wtf("MainActivity", "Why won't this happen?");

未在控制台上打印,请注意the "wtf" are logged at level ASSERT,因此请检查控制台日志级别。另一个提示是记录id

int id = item.getItemId();

并检查它是否与:

匹配
R.id.action_share 

整数值。

如果您的代码根本没有获得onOptionsItemSelected,则可能是

Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "FOO");
shareIntent.putExtra(Intent.EXTRA_TEXT, "FOO");

mShareActionProvider.setShareIntent(shareIntent);

位于错误的位置(onCreateOptionsMenu)。尝试删除它并查看onOptionsItemSelected是否被调用,如果是,则将代码添加到if语句中的onOptionsItemSelected。请在ShareProvider

上查看http://developer.android.com示例

编辑2: 好吧,如果使用ActionProvider(在您的情况下是ShareActionProvider)设置了menuItem,则不会调用此menuItem的onOptionsItemSelected。如果从menu.xml中删除以下行,则可以对此进行测试:

app:actionProviderClass="android.support.v7.widget.ShareActionProvider"

(请记住删除引用类中的ShareActionProvider的任何代码,否则null对象异常会上升。

据说可以通过阅读ActionProvider来覆盖此行为,但我无法编写示例来显示此行为。

答案 1 :(得分:0)

我已确认完全确定onMenuItemSelected永远不会在ShareActionProvider菜单项上调用:

  • ShareActionProvider的googlesamples example甚至没有实现方法
  • 这个 question (不是答案) - 显然本身并不具有权威性,但这里的答案使我进一步了解了我需要做的事情。

我最终通过在onCreateOptionsMenu中向我的ShareActionProvider添加OnShareTargetSelectedListener来解决我的问题:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate menu resource file.
    getMenuInflater().inflate(R.menu.menu_main, menu);

    // Locate MenuItem with ShareActionProvider
    MenuItem item = menu.findItem(R.id.action_share);

    // Fetch and store ShareActionProvider
    mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(item);
    setShareIntent(getShareIntent());

    // THESE ARE THE ANSWER BITS
    mShareActionProvider.setOnShareTargetSelectedListener(
            new ShareActionProvider.OnShareTargetSelectedListener() {

                @Override
                public boolean onShareTargetSelected(ShareActionProvider shareActionProvider, Intent intent) {
                    // report the share event
                    Log.d("MainActivity", "Shared!");

                    // return value is ignored, so false is fine
                    return false;
                }
            });

    // Return true to display menu
    return true;
}