【问题标题】:How do you turn off share history when using ShareActionProvider?使用 ShareActionProvider 时如何关闭共享历史记录?
【发布时间】:2012-05-22 16:57:18
【问题描述】:

Android 4.0 中提供的新 ShareActionProvider(如果您使用的是 ActionBarSherlock,则在更早的版本中)具有一项功能,即最后使用的项目显示在操作栏中。有什么办法可以关掉吗?

【问题讨论】:

    标签: android android-actionbar actionbarsherlock shareactionprovider


    【解决方案1】:

    对我来说,避免历史图标的最佳解决方案是不要使用 ShareActionProvider,而是将其创建为任何其他操作:

     <item 
        android:id="@+id/menu_action_share"
        android:showAsAction="ifRoom" 
        android:icon="@drawable/ic_action_share"
        android:title="@string/share"/>   
    

    在 menu/activity_actions.xml 中放置一个带有 ic_action_share 图标的项目...

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_actions, menu);
        return super.onCreateOptionsMenu(menu);
     }
    

    正常膨胀菜单...

    private void actionShare(){
         Intent i = new Intent(Intent.ACTION_SEND);
         i.setType("text/plain");
         i.putExtra(Intent.EXTRA_SUBJECT, "my string");
         i.putExtra(Intent.EXTRA_TEXT, "another string");
         startActivity(i); 
         //Or like above will always display the chooser
         //startActivity(Intent.createChooser(i, getResources().getText(R.string.share))); 
     }
    

    创建一个带有 ACTION_SEND 意图的方法

    @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
            case R.id.menu_item_share:
                actionShare();
                return true;
            default:
                return super.onOptionsItemSelected(item);
            }
        }
    

    最后从 onOptionsItemSelected 调用这个方法

    更多信息 ->Sending Simple Data to Other Apps

    【讨论】:

    • 这比传统的ActionProvider还要好。
    • 比原生的ShareActionProvider更好,因为它不显示历史记录,而是所有可以共享的应用程序。
    【解决方案2】:

    自己发起分享活动:

    shareActionProvider.setShareIntent(intent);
    shareActionProvider.setOnShareTargetSelectedListener(this);
    
    @Override
    public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
        // start activity ourself to prevent search history
        context.startActivity(intent);
        return true;
    }
    

    那么 ShareActionProvider 将不会将所选活动添加到共享历史记录中。

    【讨论】:

    • 我不确定这对其他人有什么作用。使用 v7 兼容库时,它仍然会因java.lang.IllegalStateException: No preceding call to #readHistoricalData 而崩溃。此外,文档明确指出onShareTargetSelected:“注意:您不应在此处处理意图。此回调旨在通知客户端正在执行共享,因此客户端可以在必要时更新 UI。返回结果被忽略。始终返回 false 以保持一致性。"
    • 记得清理你的应用在测试设备中的数据。
    • @Felix 的评论有效。医生说不应该这样做。我最终触发了 2 个意图。
    【解决方案3】:

    我创建了自己版本的 ShareActionProvider(和支持类),您可以将它们复制到您的项目中 (https://gist.github.com/saulpower/10557956)。这不仅增加了关闭历史记录的功能,还可以过滤您想要共享的应用程序(如果您知道包名称)。

    private final String[] INTENT_FILTER = new String[] {
            "com.twitter.android",
            "com.facebook.katana"
    };
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.journal_entry_menu, menu);
    
        // Set up ShareActionProvider's default share intent
        MenuItem shareItem = menu.findItem(R.id.action_share);
    
        if (shareItem instanceof SupportMenuItem) {
            mShareActionProvider = new ShareActionProvider(this);
            mShareActionProvider.setShareIntent(ShareUtils.share(mJournalEntry));
            mShareActionProvider.setIntentFilter(Arrays.asList(INTENT_FILTER));
            mShareActionProvider.setShowHistory(false);
            ((SupportMenuItem) shareItem).setSupportActionProvider(mShareActionProvider);
        }
    
        return super.onCreateOptionsMenu(menu);
    }
    

    【讨论】:

      【解决方案4】:

      没有 API 可以做到这一点。但是,该类非常简单,您可以非常轻松地创建自己的不保留历史记录的ShareActionProvider 版本。您只需要使用其他排序方式(例如,按字母顺序)确定可能目标的排序顺序。

      【讨论】:

      • 问题是,我想保留历史记录,但只能在下拉菜单中。添加额外的图标很烦人,它不再适合在栏中。
      • @phreakhead 看看我的回答 - stackoverflow.com/a/17290249/1446466。它将满足您的需求。
      【解决方案5】:

      澄清点:它不是“最后使用”,而是“最常使用”,跨越滑动窗口时间段。

      如果您不想使用历史记录,那么在创建视图之前,请调用

      yourShareActionProvider.setShareHistoryFileName(null);
      

      此方法的描述,来自official docs(重点是我的):

      设置用于保存共享历史的文件的文件名,该历史将用于排序共享目标。该文件将用于由 onCreateActionView() 创建的所有视图。默认为 DEFAULT_SHARE_HISTORY_FILE_NAME。 如果不应在会话之间保留共享历史记录,则设置为 null

      编辑:我应该澄清一下——如果没有历史记录,“最常用”的项目将不会显示,所以这是目前删除该按钮的唯一方法。

      【讨论】:

      • 你能说得更具体一点,你所说的“没用”吗?
      • 我也有同样的行为。共享仍在工作..这应该是不可能的。
      • 当我调用 setShareHistoryFileName(null) 时,共享操作不再执行任何操作 :(
      • 当我在运行 4.2.1 的 Nexus 7 上将文件名设置为 null 时,默认操作按钮会正确消失。但是,尝试从共享菜单中选择操作会导致崩溃并显示 java.lang.IllegalStateException: No preceding call to #readHistoricalData
      • 这会导致我的系统崩溃
      【解决方案6】:

      虽然已经是 2 年前的今天,但我想分享一下我的经验,因为我制作了一个自定义 ShareActionProvider 类,并在 onCreateActionView() 中添加了这一行 chooserView.getDataModel().setHistoryMaxSize(0);,它为我做了所有的魔法! .. 我在 Lollipop 设备和 API 16 模拟器设备上对其进行了测试,它运行良好。这是我的自定义类:

      import android.content.Context;
      import android.graphics.drawable.Drawable;
      import android.os.Build;
      import android.support.v7.internal.widget.ActivityChooserView;
      import android.support.v7.widget.ShareActionProvider;
      import android.view.View;
      
      
      public class MyShareActionProvider extends ShareActionProvider {
          /**
           * Creates a new instance.
           *
           * @param context Context for accessing resources.
           */
          public MyShareActionProvider(Context context) {
              super(context);
          }
      
          @Override
          public View onCreateActionView() {
              ActivityChooserView chooserView = (ActivityChooserView) super.onCreateActionView();
              Drawable icon;
              if (Build.VERSION.SDK_INT >= 21) {
                  icon = getContext().getDrawable(R.drawable.share_icon);
              }else{
                  icon = getContext().getResources().getDrawable(R.drawable.share_icon);
              }
              chooserView.setExpandActivityOverflowButtonDrawable(icon);
              chooserView.getDataModel().setHistoryMaxSize(0);
              return chooserView;
          }
      
      }
      

      【讨论】:

      • 很好,但在androidx 中,setHistoryMaxSize() 方法无法访问... :(
      • @l33t 你是对的.. 我发现这一点在 appcompat v.23 库之前就已经发生了
      【解决方案7】:

      像这样添加代码:

          private void addShareSelectedListener() {
          if (null == mShareActionProvider) return;
          OnShareTargetSelectedListener listener = new OnShareTargetSelectedListener() {
              public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
                  mContex.startActivity(intent);
                  return true;
              }
          };
      
      //Set to null if share history should not be persisted between sessions.
          mShareActionProvider.setShareHistoryFileName(null);
          mShareActionProvider.setOnShareTargetSelectedListener(listener);
      
      }
      

      【讨论】:

        【解决方案8】:
            getSupportMenuInflater().inflate(R.menu.share_action_provider, menu);
        
            // Set file with share history to the provider and set the share intent.
            MenuItem actionItem = menu.findItem(R.id.menu_item_share_action_provider_action_bar);
            ShareActionProvider actionProvider = (ShareActionProvider) actionItem.getActionProvider();
            ***actionProvider.setShareHistoryFileName(null);
            OnShareTargetSelectedListener listener = new OnShareTargetSelectedListener() {
                public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
                    startActivity(intent);
                    return true;
                }
            };
            actionProvider.setOnShareTargetSelectedListener(listener);***
        

        【讨论】:

          猜你喜欢
          • 2021-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多