Подтвердить что ты не робот

Почему MenuItemCompat.getActionProvider возвращает значение null?

Я попытался использовать android.support.v7.widget.ShareActionProvider на панели действий в своем приложении. Поэтому я последовал примеру из документа Android, но получил некоторые проблемы.

Здесь мое меню xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:myapp="http://schemas.android.com/apk/res-auto" >

    <item
        android:id="@+id/action_share"
        android:orderInCategory="100"
        android:icon="@drawable/ic_action_share"
        android:title="@string/action_share"
        myapp:showAsAction="ifRoom"
        myapp:actionProviderClass="android.support.v7.widget.ShareActionProvider" />

</menu>

здесь мой код для создания кнопки действия с общим ресурсом:

@Override
public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.share, menu);
    MenuItem shareItem = menu.findItem(R.id.action_share);
    ShareActionProvider mShareActionProvider = (ShareActionProvider)MenuItemCompat.getActionProvider(shareItem);
    mShareActionProvider.setShareIntent(getDefaultIntent());
    super.onCreateOptionsMenu(menu, inflater);
}

Мой вопрос:

  • MenuItemCompat.getActionProvider(shareItem) всегда возвращает null для меня, почему это?
  • Когда я прокомментирую эти строки, кнопка совместного доступа появляется на панели, но ничего не делает, щелкая, как ее исправить (если вопрос 1 не может быть разрешен)

btw, я проверил коды MenuItemCompat.getActionProvider, похоже, что этот метод проверяет, реализует ли пункт меню интерфейс SupportMenuItem и возвращает сбой, если это не так. Как я могу справиться с этим?

4b9b3361

Ответ 1

В моем случае это неправильное пространство имен в menu.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
  <item android:id="@+id/menu_item_share"
        app:actionProviderClass="android.support.v7.widget.ShareActionProvider"/>

Обратите внимание на app:actionProviderClass="android.support.v7.widget.ShareActionProvider": он должен иметь

  • правильный пакет ( android.widget android.support.v7.widget)
  • правильное пространство имен (приложение android).

Несчастливо, компилятор компилирует его без ошибок, только Android Studio делает уведомление с подчеркиванием.

Ответ 2

Вот это единственное решение, которое работает, чтобы сделать ShareActionProvider не null... я использую вместо этого ActionProvider... см. код ниже:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.messages_activity_menu, menu);
    MenuItem menuItem = menu.findItem(R.id.menu_item_share);
    shareActionProvider = new ShareActionProvider(this);
    MenuItemCompat.setActionProvider(menuItem, shareActionProvider);

    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    if(item.getItemId() == R.id.menu_item_share){
        onShareAction();
    }

    return super.onOptionsItemSelected(item);
}

private void onShareAction(){
    // Create the share Intent
    String playStoreLink = "https://play.google.com/store/apps/details?id=" + getPackageName();
    String yourShareText = getResources().getString(R.string.share_text) + playStoreLink;
    Intent shareIntent = ShareCompat.IntentBuilder.from(this).setType("text/plain").setText(yourShareText).getIntent();
    // Set the share Intent
    if (shareActionProvider != null) {
        shareActionProvider.setShareIntent(shareIntent);
    }
}

и... XML

 <?xml version="1.0" encoding="utf-8"?>
 <menu xmlns:android="http://schemas.android.com/apk/res/android" >
     <item
    android:id="@+id/menu_item_share"
    android:icon="@drawable/ic_action_share"
    android:showAsAction="ifRoom|withText"
    android:title="@string/menu_item_share" />
 </menu>

и другие вещи, которые можно проверить:

активность должна расширять ActionBarActivity:

MyActivity extends ActionBarActivity

проверить и использовать этот импорт:

import android.support.v4.app.ShareCompat;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.OnNavigationListener;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.ShareActionProvider;

В AndroidManifest.xml поместите эту строку в атрибуты тега активности:

android:theme="@style/Theme.AppCompat.Light"

Если вы не знаете, как импортировать библиотеки совместимости v7 и v4, см. ниже: http://developer.android.com/tools/support-library/setup.html

Ответ 3

Если кто-то хочет сохранить progaurd и все еще использовать код:

ShareActionProvider mShareActionProvider = (ShareActionProvider)MenuItemCompat.getActionProvider(shareItem);

Просто добавьте в proguard:

-keep class android.support.v7.widget.ShareActionProvider { *; }

Ответ 4

Убедитесь, что ваш класс расширяет AppCompatActivity, а не только Activity.

Примечание. Отредактировано с учетом обновленной библиотеки совместимых приложений.

Ответ 5

После некоторого чтения, который включает, вероятно, некоторые из ваших ответов, наконец, это разрешено:

  • Share_Menu.xml. Убедитесь, что у вас есть пользовательское пространство имен, а класс actionProvider - из этого пользовательского пространства имен, а также правильное значение: android.support.v7.widget.ShareActionProvider

    <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:myapp="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_share" android:title="@string/action_detail_share" myapp:showAsAction="always" myapp:actionProviderClass="android.support.v7.widget.ShareActionProvider"></item> </menu>

  • Detail_Activity.java
    2.1. Наследовать от ActionBarActivity вместо Activity
    2.2. Добавьте правильный импорт

    import android.support.v4.app.Fragment; import android.support.v4.view.MenuItemCompat; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.ShareActionProvider;

  • AndroidManifest.xml Добавьте android: theme = " @style/Theme.AppCompat.Light"

    <activity android:name=".detail_activity" android:label="@string/title_activity_detail_activity" android:theme="@style/Theme.AppCompat.Light" android:parentActivityName=".main_activity" >

  • build.gradle
    4.1. В моем случае, чтобы остаться в безопасной стороне, я превратил ProGuard в Debug.

    debug { runProguard false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' }

4,2. Убедитесь, что у вас есть следующий раздел компиляции в зависимостях

`compile 'com.android.support:appcompat-v7:20.0.+'` 

Ответ 6

У меня была такая же проблема с nullPointer в моем приложении. Как заявил @josh527, я забыл определить собственное пространство имен xml для моего приложения. Я знаю, что это не твоя проблема, но некоторые люди могут дойти до твоего поста, подобного мне, и не вижу этого, поэтому я просто хотел его заметить;)

Ответ 7

У меня был такой же тип ошибки. MenuItemCompat.getActionProvider возвращает null.

Моя проблема была в ProGuard. Повернув ProGuard, я решил это для меня.

Ответ 8

Попробуйте добавить в блок действий

import android.support.v4.view.MenuItemCompat;

У меня была та же проблема, и это было решение.

Ответ 9

переменная: Android.Support.V7.Widget.ShareActionProvider shareActionProvider;

this.MenuInflater.Inflate(Resource.Menu.share_action_provider, menu);
var shareItem = menu.FindItem(Resource.Id.menu_item_share_action_provider_action_bar);
MenuItemCompat.SetShowAsAction (shareItem,  MenuItemCompat.ShowAsActionIfRoom);
var actionprov = new Android.Support.V7.Widget.ShareActionProvider (this);
MenuItemCompat.SetActionProvider (shareItem, actionprov);
var test =  MenuItemCompat.GetActionProvider (shareItem);
shareActionProvider = test.JavaCast<Android.Support.V7.Widget.ShareActionProvider>();
var intent = new Intent(Intent.ActionSend);
intent.SetType("text/plain");
intent.PutExtra(Intent.ExtraText, "ActionBarCompat is Awesome! Support Lib v7 #Xamarin");
shareActionProvider.SetShareIntent (intent);
return base.OnCreateOptionsMenu(menu); 

это сошло с меня... я просто создал свой собственный shareactionprovider! и я сам его установил, а потом заработал... и, может быть, какой-то код даже этого не нужен.. но его много кастинга И УБЕДИТЕСЬ, что вы используете правильные все время, если вы просто наберете "ShareActionProvider", вы фактически используя V4..! вместо V7

Ответ 10

Вы должны изменить объявление и определение функции onCreateOptionsMenu. вы изменили объявление функции с базового класса. это означает, что метод не переопределяется.

Попробуйте следующее:

@Override
public boolean onCreateOptionsMenu (Menu menu) {

    inflater.inflate(R.menu.share, menu);// declare a local layout inflater
    MenuItem shareItem = menu.findItem(R.id.action_share);
    ShareActionProvider mShareActionProvider = (ShareActionProvider)MenuItemCompat.getActionProvider(shareItem);
    mShareActionProvider.setShareIntent(getDefaultIntent());
//    super.onCreateOptionsMenu(menu, inflater);   <--- Remove this line or put in the first line because base class constructor should be called in the first line of the method.

return super.onCreateOptionsMenu(menu);//<-- Add this line to set the menu after adding menu items
}

Ответ 11

Ни одно из решений здесь не решило мою проблему с ShareActionProvider, не приводя/не возвращая null. В итоге я заменил ShareActionProvider на Intent.SEND_ACTION, чтобы делиться изображениями в моем приложении, как показано в учебнике по Android для разработчиков: https://developer.android.com/training/sharing/send

Хотя Google упоминает в этом руководстве, что: Note: The best way to add a share action item to an ActionBar is to use ShareActionProvider, which became available in API level 14. ShareActionProvider is discussed in the lesson about Adding an Easy Share Action. Я нашел гораздо проще реализовать только Intention.SEND_ACTION. Не уверен, есть ли другие причины для реализации ShareActionProvider...

Ответ 12

Для Android Pie класс провайдера действий снова изменился:

app:actionProviderClass="androidx.appcompat.widget.ShareActionProvider"

Ответ 13

Есть еще одна потенциальная проблема. Если ваш MenuItem всегда присутствует в ActionBar, используйте следующий код:

menuItem?.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS) 

Полученный пункт меню не будет работать (он будет виден, но не включен). Есть два варианта: либо изменить тип ShowAsAction, либо вызвать setShareIntent непосредственно в функции onCreateOptionsMenu():

[email protected](java.lang.Runnable {
     actionProvider.setShareIntent(shareIntent)
})