it-swarm.com.de

So machen Sie einen Screenshot und teilen ihn programmgesteuert

Ich mache eine Anwendung in Android, in der ich einen Screenshot von einer meiner Aktivitäten erstellen und als Anhang versenden muss. 

Ich möchte einen Screenshot der aktuellen Seite erstellen und diese dann per E-Mail, Bluetooth, Twitter oder Facebook teilen.

Mein Code lautet wie folgt:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
  MenuInflater inflater = getMenuInflater();
  inflater.inflate(R.menu.menuselected1, menu);
  return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

  switch (item.getItemId()) {
    case R.id.ScreenShot:

    try {
        takeScreenShot(this);
    }
    catch (Exception e) {
        System.out.println(e);
    }

    return true;

    default:
    return super.onOptionsItemSelected(item);
  }
}

private static void savePic(Bitmap b, String strFileName) {
  FileOutputStream fos = null;
  try {
      fos = new FileOutputStream(strFileName);
      if (null != fos) {
        b.compress(Bitmap.CompressFormat.PNG, 90, fos);
        System.out.println("b is:"+b);
        fos.flush();
        fos.close();
      }
  } catch (FileNotFoundException e) {
          e.printStackTrace();
  } catch (IOException e) {
          e.printStackTrace();
  }
}

public static void shoot(Activity a,String b) {
  //savePic(takeScreenShot(a), "sdcard/xx.png");
  savePic(takeScreenShot(a), b);
}

private static Bitmap takeScreenShot(Activity activity) {
  View view = activity.getWindow().getDecorView();
  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, 25, 320, 455);
  Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height
                                 - statusBarHeight);
  view.destroyDrawingCache();
  return b;
}
26
user1025050

Versuchen Sie Folgendes, um einen Screenshot der aktuellen Aktivität aufzunehmen:

Android 2.2:

private static Bitmap takeScreenShot(Activity activity)
{
    View view = activity.getWindow().getDecorView();
    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;
}
private static void savePic(Bitmap b, String strFileName)
{
    FileOutputStream fos = null;
    try
    {
        fos = new FileOutputStream(strFileName);
        if (null != fos)
        {
            b.compress(Bitmap.CompressFormat.PNG, 90, fos);
            fos.flush();
            fos.close();
        }
    }
    catch (FileNotFoundException e)
    {
        e.printStackTrace();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}
37

Wenn mit "Screenshot der aktuellen Seite" "Screenshot einer meiner Aktivitäten" gemeint ist, können Sie lassen Sie Ihre Views in eine mit Bitmap gesicherte Canvas umwandeln, speichern Sie dann ein Bild aus der Bitmap .

Wenn Sie unter "Screenshot der aktuellen Seite" "Screenshot der Aktivität eines anderen Benutzers" meinen, wird dies aus offensichtlichen Gründen des Datenschutzes und der Sicherheit nicht vom Android SDK unterstützt. Es gibt verschiedene Techniken, mit denen Benutzer gerooteter Geräte Screenshots erstellen können.

15
CommonsWare

1. Erstellen Sie den Share-Button

Ich wollte meine in der Aktionsleiste haben, also habe ich eine share_menu.xml-Datei erstellt:

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

    <item
        Android:id="@+id/share_item"
        app:showAsAction="always|withText"
        Android:title="Share"
        Android:icon="@drawable/share_icon"
        Android:actionProviderClass=
            "Android.widget.ShareActionProvider" />
</menu>

Dies fügt eine Schaltfläche in der Aktionsleiste mit meinem share_icon und dem Text hinzu.

2. Fügen Sie das Freigabemenü zu Ihrer Aktivität (oder zum Fragment) hinzu

Ich habe dies in einem Fragment getan, also habe ich den folgenden Code zu meiner Fragmentdatei hinzugefügt. Wenn Sie sich in einer Aktivität befinden, überschreiben Sie stattdessen public boolean onCreateOptionsMenu(Menu menu).

@Override
public void onCreateOptionsMenu(
        Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.share_menu, menu);
}

wenn Sie dies mit einem Fragment tun, müssen Sie in onCreate() Folgendes hinzufügen:

setHasOptionsMenu(true);

3. Tastenaktion/Rückruf/Ein-Klick einrichten

Dies ist, was das Teilen anstoßen wird.

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.share_item){
            Bitmap bm = screenShot(this.getView());
            File file = saveBitmap(bm, "Mantis_image.png");
            Log.i("chase", "filepath: "+file.getAbsolutePath());
            Uri uri = Uri.fromFile(new File(file.getAbsolutePath()));
            Intent shareIntent = new Intent();
            shareIntent.setAction(Intent.ACTION_SEND);
            shareIntent.putExtra(Intent.EXTRA_TEXT, "Check out my app.");
            shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
            shareIntent.setType("image/*");
            shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            startActivity(Intent.createChooser(shareIntent, "share via"));
        }
        return super.onOptionsItemSelected(item);
    }

Beachten Sie, dass dies zwei magische Methoden erfordert:

Bildschirmfoto():

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 static File saveBitmap(Bitmap bm, String fileName){
    final String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Screenshots";
    File dir = new File(path);
    if(!dir.exists())
        dir.mkdirs();
    File file = new File(dir, fileName);
    try {
        FileOutputStream fOut = new FileOutputStream(file);
        bm.compress(Bitmap.CompressFormat.PNG, 90, fOut);
        fOut.flush();
        fOut.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return file;
}

Wichtig

Zu Ihrem AndroidManifest.xml müssen Sie Folgendes hinzufügen:

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

oder der Screenshot wird nicht gespeichert, und Google Mail wird denken, dass Sie versuchen, eine leere Datei anzuhängen.

Viele SO - Antworten geben an, "*/*" für shareIntent.setType() zu verwenden. Dies führt jedoch zu einem Problem beim Teilen von Facebook. Daher sollten Sie es als "image/*" belassen.

4
Chase Roberts

So habe ich den Bildschirm erfasst und weitergegeben. Schauen Sie bei Interesse nach.

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

Und die Methode, die das Bitmap-Bild in einem externen Speicher speichert:

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);
}}

weitere Informationen finden Sie unter: https://www.youtube.com/watch?v=LRCRNvzamwY&feature=youtu.be

0
Van Toan Vu

Kotlin-Komplettlösung Code mit Berechtigungsprüfung:

1- Verwenden Sie diese Nice-Bibliothek, um Screenshots mit der Java/Kotlin/Rx-Funktion aufzunehmen und fügen Sie die Bibliotheksabhängigkeit hinzu: InstaCapture github link

 implementation "com.github.tarek360:instacapture:2.0.1"

2- Muss die Erlaubnis zur Kompatibilität mit allen Android-Versionen prüfen:

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            ) != PackageManager.PERMISSION_GRANTED
        ) { // Needs permission so request it
            DeviceUtil.showAlertMsg(this, GeneralDicModel.shareMsgScreenShot!!)
            requestPermissions(
                arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
                PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE
            )   //callback  result to onRequestPermissionsResult
        } else { //Has got the permission before or doesn't need
            screenShotAndShareIt()
        }

3- Berechtigungsergebnis prüfen:

 override fun onRequestPermissionsResult(
    requestCode: Int, permissions: Array<out String>,
    grantResults: IntArray
) {
    when (requestCode) {
        PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE -> {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                screenShotAndShareIt()
            } else {
                //  toast("Permission must be granted in order to save scrrenshot file")
            }
        }
    }
}

4- Func Aufruf zum Mitnehmen Screenshot & Teilen Sie es mit Absicht:

 fun screenShotAndShareIt() {
    Instacapture.capture(this, object : SimpleScreenCapturingListener() {
    override fun onCaptureComplete(bitmap: Bitmap) {
    val state = Environment.getExternalStorageState()
            if (Environment.MEDIA_MOUNTED == state) {
                val path: String = Environment.getExternalStorageDirectory().toString()  
                val picDir = File(path.plus("/myPic"))
                if (!picDir.exists()) {
                    picDir.mkdir()
                }
                var bitmapScreenShot = bitmap
                val fileName = "screenshot" + ".jpg"
                val picFile = File(picDir.path.plus("/" + fileName))
                try {
                    picFile.createNewFile()
                    val picOut = FileOutputStream(picFile)
                    bitmapScreenShot =
                        Bitmap.createBitmap(bitmapScreenShot, 0, 0, bitmapScreenShot.width, bitmapScreenShot.height)
                    val saved: Boolean = bitmapScreenShot.compress(Bitmap.CompressFormat.JPEG, 100, picOut)
                    if (saved) {
                        Log.i(
                            TAG,
                            "ScreenShotAndShareIt : Image saved to your device Pictures " + "directory! + ${picFile.absolutePath}"
                        )
                    } else {
                        Log.i(TAG, "ScreenShotAndShareIt Error on Save! + ${picFile.absolutePath}")
                    }
                    picOut.close()

                    // share via intent
                    val intent: Intent = Intent(Android.content.Intent.ACTION_SEND)
                    intent.type = "image/jpeg"
                    intent.putExtra(Intent.EXTRA_STREAM, Uri.parse(picFile.absolutePath))
                    startActivity(Intent.createChooser(intent, "Sharing"))
                } catch (e: Exception) {
                    Log.i(TAG, "ScreenShotAndShareIt Error catch : " + e.printStackTrace())
                }
            } else {
                //Error
                Log.i(TAG, "ScreenShotAndShareIt Error Environment.MEDIA_MOUNTED == state : " )
            }
 }
 })

5- Deklarieren Sie diese Variable:

val PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 100

6- Vergessen Sie nicht, diese Berechtigungen zu AndroidManifest.xml hinzuzufügen:

    <uses-permission Android:name="Android.permission.INTERNET"/>
    <uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"/>
0
Hamed Jaliliani