如何截取当前活动的截图然后分享?

时间:2015-05-12 16:48:40

标签: android android-studio share screenshot

我需要截取Activity的屏幕截图(没有标题栏,用户不应该看到实际拍摄的屏幕截图),然后通过操作菜单按钮“分享”进行分享。我已经尝试了一些解决方案,但它们对我不起作用。有什么想法吗?

15 个答案:

答案 0 :(得分:81)

这就是我捕捉屏幕并分享它的方式。

首先,从当前活动中获取根视图:

View rootView = getWindow().getDecorView().findViewById(android.R.id.content);

第二次,捕获根视图:

 public static Bitmap getScreenShot(View view) {
       View screenView = view.getRootView();
       screenView.setDrawingCacheEnabled(true);
       Bitmap bitmap = Bitmap.createBitmap(screenView.getDrawingCache());
       screenView.setDrawingCacheEnabled(false);
       return bitmap;
 }

第三次,将Bitmap存储到SD卡中:

public static void store(Bitmap bm, String fileName){
    final static String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Screenshots";
    File dir = new File(dirPath);
    if(!dir.exists())
        dir.mkdirs();
    File file = new File(dirPath, fileName);
    try {
        FileOutputStream fOut = new FileOutputStream(file);
        bm.compress(Bitmap.CompressFormat.PNG, 85, fOut);
        fOut.flush();
        fOut.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

最后,分享当前Activity的屏幕截图:

private void shareImage(File file){
    Uri uri = Uri.fromFile(file);
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_SEND);
    intent.setType("image/*");

    intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "");
    intent.putExtra(android.content.Intent.EXTRA_TEXT, "");
    intent.putExtra(Intent.EXTRA_STREAM, uri);
    try {
        startActivity(Intent.createChooser(intent, "Share Screenshot"));
    } catch (ActivityNotFoundException e) {
        Toast.makeText(context, "No App Available", Toast.LENGTH_SHORT).show();
    }
}

我希望你的灵感来自我的代码。

<强>更新

将以下权限添加到AndroidManifest.xml

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

因为它创建并访问外部存储中的文件。

<强>更新

从Android 7.0开始Nougat共享文件链接是禁止的。要处理这个问题,你必须实现FileProvider并分享“content://”uri而不是“file://”uri。

Here是一个很好的描述如何做到这一点。

答案 1 :(得分:11)

单击侦听器

创建共享按钮

    share = (Button)findViewById(R.id.share);
    share.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Bitmap bitmap = takeScreenshot();
            saveBitmap(bitmap);
            shareIt();
        }
    });

添加两个方法

    public Bitmap takeScreenshot() {
    View rootView = findViewById(android.R.id.content).getRootView();
    rootView.setDrawingCacheEnabled(true);
    return rootView.getDrawingCache();
    }

public void saveBitmap(Bitmap bitmap) {
    imagePath = new File(Environment.getExternalStorageDirectory() + "/screenshot.png");
    FileOutputStream fos;
    try {
        fos = new FileOutputStream(imagePath);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
        fos.flush();
        fos.close();
    } catch (FileNotFoundException e) {
        Log.e("GREC", e.getMessage(), e);
    } catch (IOException e) {
        Log.e("GREC", e.getMessage(), e);
    }
}

分享截屏。在这里分享实施

    private void shareIt() {
    Uri uri = Uri.fromFile(imagePath);
    Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
    sharingIntent.setType("image/*");
    String shareBody = "In Tweecher, My highest score with screen shot";
    sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "My Tweecher score");
    sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody);
    sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);

    startActivity(Intent.createChooser(sharingIntent, "Share via"));
    }

答案 2 :(得分:4)

您可以使用以下代码获取您在屏幕上看到的视图的位图您可以指定要创建位图的视图。

Range("A1").Select

答案 3 :(得分:4)

在添加

之前,我无法让Silent Knight's answer工作
var doc = XDocument.Parse(xml);

XNamespace ns = "http://www.example.com/schema/msc/referral";

doc.Descendants(ns + "Events")
    .Select(e => new DTO {
                            RoutingCode = (string)e.Attribute("Code"),
                            User = new UserDTO((string)e.Element(ns + "User").Attribute("Name"))
                     });

到我的<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

答案 4 :(得分:3)

您可以截取视图的任何部分。您只需要参考您想要截屏的布局。例如,在您的情况下,您需要活动的屏幕截图。假设您的活动根布局是线性布局。

   // find the reference of the layout which screenshot is required

     LinearLayout LL = (LinearLayout) findViewById(R.id.yourlayout);
      Bitmap screenshot = getscreenshot(LL);

     //use this method to get the bitmap
      private Bitmap getscreenshot(View view) {
        View v = view;
        v.setDrawingCacheEnabled(true);
        Bitmap bitmap = Bitmap.createBitmap(v.getDrawingCache());
        return bitmap;
      }

答案 5 :(得分:2)

此方法不需要再次存储和检索屏幕截图以进行共享。 只需调用方法,您就可以共享屏幕截图。

private Bitmap screenShot(View view) {
    Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),view.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    view.draw(canvas);
    return bitmap;
}

private void share(Bitmap bitmap){
    String pathofBmp=
            MediaStore.Images.Media.insertImage(ctx.getContentResolver(),
                    bitmap,"title", null);
    Uri uri = Uri.parse(pathofBmp);
    Intent shareIntent = new Intent(Intent.ACTION_SEND);
    shareIntent.setType("image/*");
    shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Star App");
    shareIntent.putExtra(Intent.EXTRA_TEXT, "");
    shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
    ctx.startActivity(Intent.createChooser(shareIntent, "hello hello"));
}

像这样调用这个方法

share(screenShot(view));

在没有读写权限的情况下使用此直接共享屏幕截图

答案 6 :(得分:1)

对于所有Xamarin用户:

Xamarin.Android代码:

创建一个外部类(我有一个每个平台的接口,我在android平台上实现了以下3个功能):

    public static Bitmap TakeScreenShot(View view)
    {
        View screenView = view.RootView;
        screenView.DrawingCacheEnabled = true;
        Bitmap bitmap = Bitmap.CreateBitmap(screenView.DrawingCache);
        screenView.DrawingCacheEnabled = false;
        return bitmap;
    }
    public static Java.IO.File StoreScreenShot(Bitmap picture)
    {
        var folder = Android.OS.Environment.ExternalStorageDirectory + Java.IO.File.Separator + "MyFolderName";
        var extFileName = Android.OS.Environment.ExternalStorageDirectory +
                          Java.IO.File.Separator +
                          Guid.NewGuid() + ".jpeg";
        try
        {
            if (!Directory.Exists(folder))
                Directory.CreateDirectory(folder);

            Java.IO.File file = new Java.IO.File(extFileName);

            using (var fs = new FileStream(extFileName, FileMode.OpenOrCreate))
            {
                try
                {
                    picture.Compress(Bitmap.CompressFormat.Jpeg, 100, fs);
                }
                finally
                {
                    fs.Flush();
                    fs.Close();
                }
                return file;
            }
        }
        catch (UnauthorizedAccessException ex)
        {
            Log.Error(LogPriority.Error.ToString(), "-------------------" + ex.Message.ToString());
            return null;
        }
        catch (Exception ex)
        {
            Log.Error(LogPriority.Error.ToString(), "-------------------" + ex.Message.ToString());
            return null;
        }
    }
    public static void ShareImage(Java.IO.File file, Activity activity, string appToSend, string subject, string message)
    {
        //Push to Whatsapp to send
        Android.Net.Uri uri = Android.Net.Uri.FromFile(file);
        Intent i = new Intent(Intent.ActionSendMultiple);
        i.SetPackage(appToSend); // so that only Whatsapp reacts and not the chooser
        i.AddFlags(ActivityFlags.GrantReadUriPermission);
        i.PutExtra(Intent.ExtraSubject, subject);
        i.PutExtra(Intent.ExtraText, message);
        i.PutExtra(Intent.ExtraStream, uri);
        i.SetType("image/*");
        try
        {
            activity.StartActivity(Intent.CreateChooser(i, "Share Screenshot"));
        }
        catch (ActivityNotFoundException ex)
        {
            Toast.MakeText(activity.ApplicationContext, "No App Available", ToastLength.Long).Show();
        }
    }`

现在,从您的Activity中,您运行上面的代码:

                    RunOnUiThread(() =>
                {
                    //take silent screenshot
                    View rootView = Window.DecorView.FindViewById(Resource.Id.ActivityLayout);
                    Bitmap tmpPic = ShareHandler.TakeScreenShot(this.CurrentFocus); //TakeScreenShot(this);
                    Java.IO.File imageSaved = ShareHandler.StoreScreenShot(tmpPic);
                    if (imageSaved != null)
                    {
                        ShareHandler.ShareImage(imageSaved, this, "com.whatsapp", "", "ScreenShot Taken from: " + "Somewhere");
                    }
                });

希望它对任何人都有用。

答案 7 :(得分:1)

截屏

 public Bitmap takeScreenshot() {
    View rootView = findViewById(android.R.id.content).getRootView();
    rootView.setDrawingCacheEnabled(true);
    return rootView.getDrawingCache();
}

用于保存屏幕截图

private void saveBitmap(Bitmap bitmap) {
    imagePath = new File(Environment.getExternalStorageDirectory() + "/scrnshot.png"); ////File imagePath
    FileOutputStream fos;
    try {
        fos = new FileOutputStream(imagePath);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
        fos.flush();
        fos.close();
    } catch (FileNotFoundException e) {
        Log.e("GREC", e.getMessage(), e);
    } catch (IOException e) {
        Log.e("GREC", e.getMessage(), e);
    }
}

和分享

private void shareIt() {
    Uri uri = Uri.fromFile(imagePath);
    Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
    sharingIntent.setType("image/*");
    String shareBody = "My highest score with screen shot";
    sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "My Catch score");
    sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody);
    sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);

    startActivity(Intent.createChooser(sharingIntent, "Share via"));
}

只需在onclick中,您就可以调用这些方法

shareScoreCatch.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Bitmap bitmap = takeScreenshot();
        saveBitmap(bitmap);
        shareIt();
   }
});

答案 8 :(得分:0)

这是我捕捉屏幕并分享它的方式。看看你是否感兴趣。

public Bitmap takeScreenshot() {
  View rootView = findViewById(android.R.id.content).getRootView();
  rootView.setDrawingCacheEnabled(true);
  return rootView.getDrawingCache();
 }

将位图图像保存到外部存储器的方法:

public void saveBitmap(Bitmap bitmap) {
File imagePath = new File(Environment.getExternalStorageDirectory() + "/screenshot.png");
FileOutputStream fos;
try {
    fos = new FileOutputStream(imagePath);
    bitmap.compress(CompressFormat.JPEG, 100, fos);
    fos.flush();
    fos.close();
} catch (FileNotFoundException e) {
    Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
    Log.e("GREC", e.getMessage(), e);
 }}

请参阅:https://www.youtube.com/watch?v=LRCRNvzamwY&feature=youtu.be

答案 9 :(得分:0)

这是我用来截取屏幕截图的方法。上述解决方案适用于API&lt;但是对于API 24和更高版本,需要另一种解决方案。我已经在API 15,24和&amp ;;上测试了这种方法。 27。

我在MainActivity.java中放置了以下方法:

public class MainActivity {

...

String[] permissions = new String[]{"android.permission.READ_EXTERNAL_STORAGE", "android.permission.WRITE_EXTERNAL_STORAGE"};
View sshotView;

...

private boolean checkPermission() {
List arrayList = new ArrayList();
for (String str : this.permissions) {
if (ContextCompat.checkSelfPermission(this, str) != 0) {
arrayList.add(str);
}
}
if (arrayList.isEmpty()) {
return true;
}
ActivityCompat.requestPermissions(this, (String[]) arrayList.toArray(new String[arrayList.size()]), 100);
return false;
}

protected void onCreate(Bundle savedInstanceState) {
...

this.sshotView = getWindow().getDecorView().findViewById(R.id.parent);
...

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

int id = item.getItemId();
switch (id) {


case R.id.action_shareScreenshot:
boolean checkPermission = checkPermission();
Bitmap screenShot = getScreenShot(this.sshotView);
if (!checkPermission) {
return true;
}
shareScreenshot(store(screenShot));
return true;

case R.id.option2:      
...    
return true;
}

return false;
}

private void shareScreenshot(File file) {
Parcelable fromFile = FileProvider.getUriForFile(MainActivity.this,
BuildConfig.APPLICATION_ID + ".com.redtiger.applehands.provider", file);
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setAction("android.intent.action.SEND");
intent.setType("image/*");
intent.putExtra("android.intent.extra.SUBJECT", XmlPullParser.NO_NAMESPACE);
intent.putExtra("android.intent.extra.TEXT", XmlPullParser.NO_NAMESPACE);
intent.putExtra("android.intent.extra.STREAM", fromFile);
try {
startActivity(Intent.createChooser(intent, "Share Screenshot"));
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(), "No Communication Platform Available", Toast.LENGTH_SHORT).show();
}
}

public static Bitmap getScreenShot(View view) {
View rootView = view.getRootView();
rootView.setDrawingCacheEnabled(true);
Bitmap createBitmap = Bitmap.createBitmap(rootView.getDrawingCache());
rootView.setDrawingCacheEnabled(false);
return createBitmap;

public File store(Bitmap bitmap) {
String str = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Screenshots";
File file = new File(str);
if (!file.exists()) {
file.mkdirs();
}
file = new File(str + "/sshot.png");
try {
OutputStream fileOutputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 80, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "External Storage Permission Is Required", Toast.LENGTH_LONG).show();
}
return file;
}
}

我在AndroidManifest.xml中放置了以下权限和提供程序:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.redtiger.applehands">

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />

<application

...

<provider
android:name="com.redtiger.applehands.util.GenericFileProvider"
android:authorities="${applicationId}.com.redtiger.applehands.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>

...

</application>

</manifest>

我创建了一个名为provider_paths.xml的文件(请参见下文),以指示FileProvider保存屏幕截图的位置。该文件包含一个指向外部目录根目录的简单标记。

将文件放在资源文件夹res / xml中(如果此处没有xml文件夹,只需创建一个并将文件放在那里)。

provider_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
</paths>

答案 10 :(得分:0)

如果按照SilengKnight的解决方案获得了java.io.FileNotFoundException,则问题可能出在存储中不允许写入(尽管我们在清单中添加了用户权限)。我通过在创建新的FileOutputStream之前将其添加到store函数中来解决了这个问题。

if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        //Permission was denied
        //Request for permission
        ActivityCompat.requestPermissions(MainActivity.this,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                MY_PERMISSIONS_CODE_EXTERNAL_STORAGE);
    }

答案 11 :(得分:0)

您可以尝试以下代码来捕获当前屏幕的屏幕截图并共享该图像,而无需任何 PERMISSION 。我已经对其进行了完美的测试。

只需复制粘贴此内容即可。

  1. 在MainAtivity.java

     public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
        private Button fullPageScreenshot, customPageScreenshot;
        private LinearLayout rootContent;
        private ImageView imageView;
        private TextView hiddenText;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build());
            findViews();
            implementClickEvents();
        }
        /*  Find all views Ids  */
        private void findViews() {
            fullPageScreenshot = (Button) findViewById(R.id.full_page_screenshot);
            customPageScreenshot = (Button) findViewById(R.id.custom_page_screenshot);
            rootContent = (LinearLayout) findViewById(R.id.root_content);
            imageView = (ImageView) findViewById(R.id.image_view);
            hiddenText = (TextView) findViewById(R.id.hidden_text);
        }
        /*  Implement Click events over Buttons */
        private void implementClickEvents() {
            fullPageScreenshot.setOnClickListener(this);
            customPageScreenshot.setOnClickListener(this);
        }
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.full_page_screenshot:
                    takeScreenshot(ScreenshotType.FULL);
                    break;
                case R.id.custom_page_screenshot:
                    takeScreenshot(ScreenshotType.CUSTOM);
                    break;
            }
        }
    
        /*  Method which will take screenshot on Basis of Screenshot Type ENUM  */
        private void takeScreenshot(ScreenshotType screenshotType) {
            Bitmap b = null;
            switch (screenshotType) {
                case FULL:
                    //If Screenshot type is FULL take full page screenshot i.e our root content.
                    b = ScreenshotUtils.getScreenShot(rootContent);
                    break;
                case CUSTOM:
                    //If Screenshot type is CUSTOM
                    fullPageScreenshot.setVisibility(View.INVISIBLE);//set the visibility to INVISIBLE of first button
                    hiddenText.setVisibility(View.VISIBLE);//set the visibility to VISIBLE of hidden text
                     b = ScreenshotUtils.getScreenShot(rootContent);
                    //After taking screenshot reset the button and view again
                    fullPageScreenshot.setVisibility(View.VISIBLE);//set the visibility to VISIBLE of first button again
                    hiddenText.setVisibility(View.INVISIBLE);//set the visibility to INVISIBLE of hidden text
                    //NOTE:  You need to use visibility INVISIBLE instead of GONE to remove the view from frame else it wont consider the view in frame and you will not get screenshot as you required.
                    break;
            }
            //If bitmap is not null
            if (b != null) {
                showScreenShotImage(b);//show bitmap over imageview
                File saveFile = ScreenshotUtils.getMainDirectoryName(this);//get the path to save screenshot
                File file = ScreenshotUtils.store(b, "screenshot" + screenshotType + ".jpg", saveFile);//save the screenshot to selected path
                shareScreenshot(file);//finally share screenshot
            } else
                //If bitmap is null show toast message
                Toast.makeText(this, R.string.screenshot_take_failed, Toast.LENGTH_SHORT).show();
        }
        /*  Show screenshot Bitmap */
        private void showScreenShotImage(Bitmap b) {
            imageView.setImageBitmap(b);
        }
        /*  Share Screenshot  */
        private void shareScreenshot(File file) {
            Uri uri = Uri.fromFile(file);//Convert file path into Uri for sharing
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_SEND);
            intent.setType("image/*");
            intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "");
            intent.putExtra(android.content.Intent.EXTRA_TEXT, getString(R.string.sharing_text));
            intent.putExtra(Intent.EXTRA_STREAM, uri);//pass uri here
            startActivity(Intent.createChooser(intent, getString(R.string.share_title)));
        }
    }
    
    1. ScreenshotType.java

      public enum ScreenshotType {
          FULL, CUSTOM;
      }
      
    2. ScreenshotUtils.java

      公共类ScreenshotUtils {

      /*  Method which will return Bitmap after taking screenshot. We have to pass the view which we want to take screenshot.  */
      public static Bitmap getScreenShot(View view) {
          View screenView = view.getRootView();
          screenView.setDrawingCacheEnabled(true);
          Bitmap bitmap = Bitmap.createBitmap(screenView.getDrawingCache());
          screenView.setDrawingCacheEnabled(false);
          return bitmap;
      }
      
      
      /*  Create Directory where screenshot will save for sharing screenshot  */
      public static File getMainDirectoryName(Context context) {
          //Here we will use getExternalFilesDir and inside that we will make our Demo folder
          //benefit of getExternalFilesDir is that whenever the app uninstalls the images will get deleted automatically.
          File mainDir = new File(
                  context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "Demo");
      
          //If File is not present create directory
          if (!mainDir.exists()) {
              if (mainDir.mkdir())
                  Log.e("Create Directory", "Main Directory Created : " + mainDir);
          }
          return mainDir;
      }
      
      /*  Store taken screenshot into above created path  */
      public static File store(Bitmap bm, String fileName, File saveFilePath) {
          File dir = new File(saveFilePath.getAbsolutePath());
          if (!dir.exists())
              dir.mkdirs();
          File file = new File(saveFilePath.getAbsolutePath(), fileName);
          try {
              FileOutputStream fOut = new FileOutputStream(file);
              bm.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
              fOut.flush();
              fOut.close();
          } catch (Exception e) {
              e.printStackTrace();
          }
          return file;
      
      
      
      }
      

      }

4.activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/root_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp"
    tools:context="com.takescreenshot_demo.MainActivity">

    <!--  Button which will take full page screenshot  -->
    <Button
        android:id="@+id/full_page_screenshot"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/full_page_screenshot"
        android:textColor="@android:color/white"
        android:textSize="14sp" />

    <!--   Hidden Text which will shown when taking screenshot from below Button  -->
    <TextView
        android:id="@+id/hidden_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="@string/hidden_text"
        android:textColor="@android:color/white"
        android:textSize="14sp"
        android:visibility="invisible" />

    <!--  Button which will take screenshot after hiding some view and showing some view  -->
    <Button
        android:id="@+id/custom_page_screenshot"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/custom_page_screenshot"
        android:textColor="@android:color/white"
        android:textSize="14sp" />


    <!--  ImageView to show taken Screenshot  -->
    <ImageView
        android:id="@+id/image_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitCenter"
        android:src="@mipmap/ic_launcher" />

</LinearLayout>

答案 12 :(得分:0)

合并的复制和粘贴代码:

private void takeScreenshot() {
        Date now = new Date();
        android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);

        try {
            // image naming and path  to include sd card  appending name you choose for file
            String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg";
            String screenshotPath = mPath;

            // create bitmap screen capture
            View v1 = getWindow().getDecorView().getRootView();
            v1.setDrawingCacheEnabled(true);
            Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
            v1.setDrawingCacheEnabled(false);

            File imageFile = new File(mPath);

            FileOutputStream outputStream = new FileOutputStream(imageFile);
            int quality = 100;
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
            outputStream.flush();
            outputStream.close();

//            openScreenshot(imageFile);
        } catch (Throwable e) {
            // Several error may come out with file handling or DOM
            e.printStackTrace();
        }
    }



    //Function to share Screenshot
    private void shareScreenshots(File file){
        Uri uri = Uri.fromFile(file);
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_SEND);
        intent.setType("image/*");

        intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "");
        intent.putExtra(android.content.Intent.EXTRA_TEXT, "");
        intent.putExtra(Intent.EXTRA_STREAM, uri);
        try {
            startActivity(Intent.createChooser(intent, "Share Screenshot"));
        } catch (ActivityNotFoundException e) {
            Toast.makeText(this, "No App Available", Toast.LENGTH_SHORT).show();
        }
    }

    //Function to open screenshot
    private void openScreenshot(File imageFile) {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        Uri uri = Uri.fromFile(imageFile);
        intent.setDataAndType(uri, "image/*");
        startActivity(intent);
    }

答案 13 :(得分:0)

截至 2021 年,这里是完整的答案,您只需复制此代码,它应该可以正常工作,它还使用所有新 API,包括权限启动器和 android q 保存图像的方式< /strong>
我将再添加一项功能,即像这样保存在图片文件夹内的文件夹内

setTimeout

此代码还支持 android < 10 以及较新的版本。

我正在制作屏幕截图并将其保存到桌面以获取图像的 uri,以便稍后分享。

首先,android < 10 上需要权限启动器

/Pictures/MyAppName/photos.png

然后下一个方法给出图像名称并设置目录然后共享图像

val requestStoragePermissionLauncher =
    registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        var saveImageFlag = true
        permissions.entries.forEach {
            saveImageFlag = it.value
        }
        if (saveImageFlag) {
            shareScreenShootResult()
        } else {
            showMessage(getString(R.string.cant_share_ScreenShoot))
        }
    }

val permissionListener: () -> Boolean = {
    if (ContextCompat.checkSelfPermission(
            requireContext(),
            Manifest.permission.READ_EXTERNAL_STORAGE
        ) == PackageManager.PERMISSION_GRANTED &&
        ContextCompat.checkSelfPermission(
            requireContext(),
            Manifest.permission.WRITE_EXTERNAL_STORAGE
        ) == PackageManager.PERMISSION_GRANTED
    ) {
        true
    } else {
        requestStoragePermissionLauncher.launch(
            arrayOf(
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            )
        )
        false
    }
}

getAppName 是一个扩展函数,你可以将它添加到项目的任何地方,然后在上下文中调用它,不要忘记导入它。

private fun shareScreenShootResult() {
    val dateFormatter by lazy {
        SimpleDateFormat(
            "yyyy.MM.dd 'at' HH:mm:ss z", Locale.getDefault()
        )
    }
    val filename = "${getString(R.string.my_ScreenShoot)}${dateFormatter.format(Date())}.png"
    val ScreenShootFolderPath = File.separator + requireContext().getAppName()

    val uri = binding.rootLayout.makeScreenShot()
        .saveScreenShot(requireContext(), filename, ScreenShootFolderPath, permissionListener)
        ?: return

    dispatchShareImageIntent(uri)
}

private fun dispatchShareImageIntent(screenShotUri: Uri) {
    val intent = Intent(Intent.ACTION_SEND)
    intent.type = "image/png"
    intent.putExtra(Intent.EXTRA_STREAM, screenShotUri)
    startActivity(Intent.createChooser(intent, "Share"))
}

这个方法fun Context.getAppName(): String { var appName: String = "" val applicationInfo = applicationInfo val stringId = applicationInfo.labelRes appName = if (stringId == 0) { applicationInfo.nonLocalizedLabel.toString() } else { getString(stringId) } return appName } 是View上的扩展函数 最好在不同的文件中添加所有扩展功能。

makeScreenShot

它返回我调用 fun View.makeScreenShot(): Bitmap { setBackgroundColor(Color.WHITE) val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) val canvas = Canvas(bitmap) draw(canvas) return bitmap } 的位图,这是另一个扩展函数

saveScreenShot

答案 14 :(得分:-2)

节省您的时间并使用此android library

为什么要使用InstaCapture?

  1. 它会捕获应用屏幕中的所有内容并避免:

    • 以下视图的黑色屏幕截图:Google地图(MapView,SupportMapFragment),TextureView,GLSurfaceView

    • 错过了以下观点:对话框,上下文菜单,祝酒词

  2. 设置特定视图以防止其被捕获。

  3. 无需任何权限。