使用我的应用程序当前视图的 ShareActionProvider 共享屏幕截图

Posted

技术标签:

【中文标题】使用我的应用程序当前视图的 ShareActionProvider 共享屏幕截图【英文标题】:Share screenshot using ShareActionProvider of my apps current view 【发布时间】:2015-02-28 13:33:47 【问题描述】:

我查看了所有相关的类似帖子,但没有一个回答我的问题。

我的程序设置了一个 ShareActionProvider 来截取当前视图并与任何可以与 .png 图像交互的应用共享。

问题:共享的屏幕截图始终是上一个屏幕截图,这意味着我必须单击操作栏中的共享按钮两次才能获取当前页面或片段视图的屏幕截图。我希望用户能够只按一次按钮。另外,是否可以在首次创建活动时不截屏,而是等到按下分享按钮。

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

    // Find the MenuItem that we know has the ShareActionProvider
    MenuItem shareItem = menu.findItem(R.id.menu_item_share);

    // Get its ShareActionProvider
    mShareActionProvider = (ShareActionProvider) shareItem.getActionProvider();

    setShareIntent(getDefaultScreenshotShareIntent());

    mShareActionProvider.setOnShareTargetSelectedListener(MainActivity.this);

    // Return true so android will know we want to display the menu
    return true;


public boolean onShareTargetSelected (ShareActionProvider source, Intent intent) 

    setShareIntent(getDefaultScreenshotShareIntent());

    return false;


// Call to update the share intent
// Connect the dots: give the ShareActionProvider its Share Intent
private void setShareIntent(Intent shareIntent) 
    if (mShareActionProvider != null) 
        mShareActionProvider.setShareIntent(shareIntent);
    


private Uri saveScreenShotDirectoryLocation() 
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.TITLE, "Some Title");
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
    Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            values);

    return uri;


private void screenShotHandler(Uri uri) 
    Bitmap screenShot = takeScreenShot(MainActivity.this);

    OutputStream outstream;
    try 
        outstream = getContentResolver().openOutputStream(uri);
        screenShot.compress(Bitmap.CompressFormat.PNG, 100, outstream);
        outstream.flush();
        outstream.close();
     catch (Exception e) 
        System.err.println(e.toString());
    


private Intent getDefaultScreenshotShareIntent() 

    Uri uri = saveScreenShotDirectoryLocation();

    Intent intent = new Intent(Intent.ACTION_SEND);

    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
    intent.setType("image/png");

    long currenttime = System.currentTimeMillis();

    intent.putExtra(Intent.EXTRA_SUBJECT, "Some Title" + currenttime);

    File path = Environment.getDataDirectory();
    long usablePartitionSpace = path.getUsableSpace();

    if (usablePartitionSpace >= SCREENSHOT_FILE_SIZE_IN_BYTES ) 
        screenShotHandler(uri);
        intent.putExtra(Intent.EXTRA_STREAM, uri);
     else 
        Toast.makeText(this, "Not enough freespace for screenshot", Toast.LENGTH_SHORT).show();
    

    intent.putExtra(Intent.EXTRA_TEXT, "Some Title");

    File file = new File(uri.getPath());
    file.delete();

    return intent;


private static Bitmap takeScreenShot(Activity activity)

    View view = activity.getWindow().getDecorView();
    //View view = (View) MainActivity.viewPager.getChildAt(MainActivity.viewPager.getCurrentItem());
    view.setDrawingCacheEnabled(true);
    view.buildDrawingCache();
    Bitmap b1 = view.getDrawingCache();
    Rect frame = new Rect();
    activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
    int statusBarHeight = frame.top;
    int width = activity.getWindowManager().getDefaultDisplay().getWidth();
    int height = activity.getWindowManager().getDefaultDisplay().getHeight();

    Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height  - statusBarHeight);
    view.destroyDrawingCache();
    return b;

我编辑的代码:

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

    // Find the MenuItem that we know has the ShareActionProvider
    MenuItem shareItem = menu.findItem(R.id.menu_item_share);

    // Get its ShareActionProvider
    mShareActionProvider = (ShareActionProvider) shareItem.getActionProvider();

    Uri uri = saveScreenShotDirectoryLocation();
    screenShotHandler(uri);

    mShareActionProvider.setOnShareTargetSelectedListener(MainActivity.this);

    // Return true so Android will know we want to display the menu
    return true;


public boolean onShareTargetSelected (ShareActionProvider source, Intent intent) 

    Uri uri = saveScreenShotDirectoryLocation();
    screenShotHandler(uri);
    setShareIntent(getDefaultScreenshotShareIntent());

    return false;


private void screenShotHandler(Uri uri) 

    File path = Environment.getDataDirectory();
    long usablePartitionSpace = path.getUsableSpace();

   // if (usablePartitionSpace >= SCREENSHOT_FILE_SIZE_IN_BYTES ) 

        Bitmap screenShot = takeScreenShot(MainActivity.this);

        OutputStream outstream;
        try 
            outstream = getContentResolver().openOutputStream(uri);
            screenShot.compress(Bitmap.CompressFormat.PNG, 100, outstream);
            outstream.flush();
            outstream.close();
         catch (Exception e) 
            System.err.println(e.toString());
        
   //  else 
  //      Toast.makeText(this, "Not enough freespace for screenshot", Toast.LENGTH_SHORT).show();
  //  
    setShareIntent(getDefaultScreenshotShareIntent());


 private Intent getDefaultScreenshotShareIntent() 

    Uri uri = saveScreenShotDirectoryLocation();

    Intent intent = new Intent(Intent.ACTION_SEND);

    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
    intent.setType("image/png");

    long currenttime = System.currentTimeMillis();

    intent.putExtra(Intent.EXTRA_SUBJECT, "Some Title" + currenttime);

    File path = Environment.getDataDirectory();
    long usablePartitionSpace = path.getUsableSpace();

   // if (usablePartitionSpace >= SCREENSHOT_FILE_SIZE_IN_BYTES ) 
        intent.putExtra(Intent.EXTRA_STREAM, uri);
    //

    intent.putExtra(Intent.EXTRA_TEXT, "Some Title");

    return intent;

Answer:那么也许 ShareActionProvider 不是正确的工具。有一个操作栏项来截取屏幕截图,然后只需使用 Intent.createChooser() 和 startActivity() 让用户共享屏幕截图。

【问题讨论】:

【参考方案1】:

在您截取屏幕截图时致电setShareIntent()(例如,在screenShotHandler() 附近的某个地方)。现在,在用户根据之前的Intent (onShareTargetSelected()) 选择要做什么之后,您正在调用setShareIntent()

【讨论】:

感谢您的快速回复。我试过了,但现在文件的持续时间不够长,无法作为附件发送。我现在收到“无法发送附件”错误 @user3211265:那是因为,由于某种原因,您正在删除getDefaultScreenshotShareIntent()中的文件,因此使用Intent时该文件将不存在。 哦不,它被注释掉了。我把它放在那里作为早期编辑的参考。除非你指的不是 file.delete(); @user3211265:这不是我写评论的时候。现在,删除onShareTargetSelected(),因为您确实想在那里重新设置Intent 删除 onShareTargetSelected() 还是在 onShareTargetSelected 中包含 file.delete()?我都试过了,但屏幕截图仍然没有坚持到意图。

以上是关于使用我的应用程序当前视图的 ShareActionProvider 共享屏幕截图的主要内容,如果未能解决你的问题,请参考以下文章

从 AppDelegate 访问当前视图

给予不允许后当前位置权限警报视图未显示

使用 mvvmcross 显示视图模型时无法解析当前的***活动

从应用程序委托获取当前视图控制器(模式是可能的)

iOS - 获取当前视图控制器

如何获取当前显示为 NSString 的视图?