异常:不支持此操作,请使用MenuItemCompat.getActionProvider()。

18

我正在尝试在Android应用程序的操作栏中创建“分享”按钮。

这是我的代码:

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ShareActionProvider;
import android.widget.TextView;

和片段部分:

{
private String mForecastText;

public PlaceholderFragment() {
    setHasOptionsMenu(true);
}

private Intent sharedIntentMaker(){
    Intent shareIntent = new Intent(Intent.ACTION_SEND);
    shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
    shareIntent.setType("text/plain");
    shareIntent.putExtra(Intent.EXTRA_TEXT, mForecastText + "#SunshineApp");
    return shareIntent;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.menu_detail, menu);
    MenuItem menuItem = menu.findItem(R.id.menu_action_share);
    ShareActionProvider mShareActionProvider = (ShareActionProvider) menuItem.getActionProvider();
    mShareActionProvider.setShareIntent(sharedIntentMaker());

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_detail, container, false);

    TextView textIntent = (TextView) rootView.findViewById(R.id.textIntent);
    Intent intent = getActivity().getIntent();
    mForecastText = intent.getStringExtra("INT_PS");
    textIntent.setText(mForecastText);
    return rootView;
}

当我在模拟器或实际设备上运行我的应用程序时,我会遇到异常:

AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.UnsupportedOperationException: This is not supported, use MenuItemCompat.getActionProvider()

它链接到onCreateOptionsMenu()的字符串:

ShareActionProvider mShareActionProvider = (ShareActionProvider) menuItem.getActionProvider();
mShareActionProvider.setShareIntent(sharedIntentMaker());
我做错了什么?
附带错误的堆栈跟踪日志:

01-11 13:03:17.490 2331-2331/com.*****.*****.***** E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.*****.*****.*****, PID: 2331

java.lang.UnsupportedOperationException: This is not supported, use MenuItemCompat.getActionProvider()

        at android.support.v7.internal.view.menu.MenuItemImpl.getActionProvider(MenuItemImpl.java:645)
        at com.project.malina.sunsine.DetailActivity$PlaceholderFragment.onCreateOptionsMenu(DetailActivity.java:70)
        at android.support.v4.app.Fragment.performCreateOptionsMenu(Fragment.java:1868)
        at android.support.v4.app.FragmentManagerImpl.dispatchCreateOptionsMenu(FragmentManager.java:1989)
        at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:276)
        at android.support.v7.app.ActionBarActivity.superOnCreatePanelMenu(ActionBarActivity.java:276)
        at android.support.v7.app.ActionBarActivityDelegate$1.onCreatePanelMenu(ActionBarActivityDelegate.java:79)
        at android.support.v7.app.ActionBarActivityDelegateBase.preparePanel(ActionBarActivityDelegateBase.java:979)
        at android.support.v7.app.ActionBarActivityDelegateBase.doInvalidatePanelMenu(ActionBarActivityDelegateBase.java:1182)
        at android.support.v7.app.ActionBarActivityDelegateBase.access$100(ActionBarActivityDelegateBase.java:79)
        at android.support.v7.app.ActionBarActivityDelegateBase$1.run(ActionBarActivityDelegateBase.java:115)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 

请包含错误的堆栈跟踪。 - EWit
请查看页面底部的“此注释的差异”部分。它明确说明要使用“android.support.v7.widget.ShareActionProvider”。 - Moshi
3个回答

68

首先,您不能将android.widget.ShareActionProviderappcompat-v7操作栏后向兼容(如ActionBarActivity)一起使用。要么使用appcompat-v7版本的ShareActionProvider,要么将所有内容移动到本机操作栏。

其次,如果您坚持使用appcompat-v7,则不能安全地使用getActionProvider(),因为该方法在API级别10及以下不存在。请将menuItem.getActionProvider()替换为MenuItemCompat.getActionProvider(menuItem)

顺便提一下,这里有一个示例项目,实现了appcompat-v7版的ShareActionProvider


是的,你说得对!我错过了官方Android开发者网站上的信息,即在API >=14中使用android.widget.ShareActionProvider。谢谢! - micsha123
1
这个示例项目非常有帮助。请确保您查看菜单xml文件 - https://github.com/commonsguy/cw-omnibus/blob/master/AppCompat/Share/app/src/main/res/menu/actions.xml - 以及活动代码 - https://github.com/commonsguy/cw-omnibus/blob/master/AppCompat/Share/app/src/main/java/com/commonsware/android/sap/MainActivity.java - 否则您可能会遇到新问题。 - ban-geoengineering

11
你可以在下面的链接中找到Google的代码示例,按照这个模式进行操作。 https://github.com/googlesamples/android-ActionBarCompat-ShareActionProvider 最简单的方法是进入Android Studio => 文件,导入示例。然后输入“分享操作提供程序”。

enter image description here

以下是创建具有ShareActionProvider的共享操作菜单项所涉及的代码,使用ActionBarCompat进行向后兼容到API v7。

MainActivity.java

// BEGIN_INCLUDE(get_sap)
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu resource
    getMenuInflater().inflate(R.menu.main_menu, menu);

    // Retrieve the share menu item
    MenuItem shareItem = menu.findItem(R.id.menu_share);

    // Now get the ShareActionProvider from the item
    mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareItem);

    // Get the ViewPager's current item position and set its ShareIntent.
    int currentViewPagerItem = ((ViewPager) findViewById(R.id.viewpager)).getCurrentItem();
    setShareIntent(currentViewPagerItem);

    return super.onCreateOptionsMenu(menu);
}
// END_INCLUDE(get_sap

private void setShareIntent(int position) {
    // BEGIN_INCLUDE(update_sap)
    if (mShareActionProvider != null) {
        // Get the currently selected item, and retrieve it's share intent
        ContentItem item = mItems.get(position);
        Intent shareIntent = item.getShareIntent(MainActivity.this);

        // Now update the ShareActionProvider with the new share intent
        mShareActionProvider.setShareIntent(shareIntent);
    }
    // END_INCLUDE(update_sap)
}

main_menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:support="http://schemas.android.com/apk/res-auto">

<!--
  To use ShareActionProvider provided by ActionBarCompat, we reference the class by set the
  support:actionProviderClass attribute with the full class name of ShareActionProvider.
-->
<item
    android:id="@+id/menu_share"
    android:title="@string/menu_share"
    support:actionProviderClass="android.support.v7.widget.ShareActionProvider"
    support:showAsAction="always" />


这很有帮助。请注意在 main_menu.xml 中,actionProviderClass 也要使用支持 v7 版本。 - Bundeeteddee

1

请按照以下步骤操作:

步骤1)要在您的活动中添加“分享”操作,请在应用程序栏的菜单资源中放置ShareActionProvider。像这样:

<item android:id="@+id/action_share"
      android:title="@string/share"
      app:showAsAction="ifRoom"
      app:actionProviderClass="android.support.v7.widget.ShareActionProvider"/>

请注意actionProviderClass步骤2)现在,请确保在您的Activity Java类中导入相同的ShareActionProvider
import android.support.v7.widget.ShareActionProvider;

第三步)
以下部分是onCreate方法。
        MenuInflater inflater = getMenuInflater();

        inflater.inflate(R.menu.main_activity_bar, menu);

        ShareActionProvider shareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(menu.findItem(R.id.actionbar_share));
        shareActionProvider.setShareIntent(shareIt());

意图方法
    private Intent shareIt() {
        Intent intent= new Intent(Intent.ACTION_SEND);
        intent.setType("text/plain");

        String shareMsgBody = "Hello, Share this with world !!";

        intent.putExtra(Intent.EXTRA_TEXT, shareAndPromotionBody);
        startActivity(Intent.createChooser(intent, "Spread the message!!"));
        return intent;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接