webentwicklung-frage-antwort-db.com.de

Wie mache ich einen Screenshot der aktuellen Aktivität und teile ihn dann?

Ich muss einen Screenshot von Activity erstellen (ohne Titelleiste, und der Benutzer sollte NICHT sehen, dass tatsächlich ein Screenshot erstellt wurde) und ihn dann über einen Aktionsmenü-Button "share" freigeben. Ich habe schon einige Lösungen ausprobiert, aber sie funktionierten nicht für mich. Irgendwelche Ideen?

30
just_deko

So habe ich den Bildschirm erfasst und weitergegeben.

Zuerst, holt die aktuelle Ansicht aus der Grundansicht:

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

Sekunde, erfassen Sie die Stammansicht:

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

Third, speichere die Bitmap auf der SDCard:

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

Zum Schluss, teile den Screenshot der aktuellen 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();
    }
}

Ich hoffe, Sie werden von meinen Codes inspiriert.

UPDATE:

Fügen Sie unten in Ihrem AndroidManifest.xml Berechtigungen hinzu:

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

Weil es Dateien im externen Speicher erstellt und darauf zugreift.

UPDATE:

Ab Android 7.0 ist das Teilen von Nougat-Links verboten. Um damit umzugehen, müssen Sie FileProvider implementieren und "content: //" uri nicht "file: //" uri freigeben.

Hier ist eine gute Beschreibung, wie es geht.

78
SilentKnight

erstellen Sie die Share-Schaltfläche mit einem Klick auf den Listener 

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

Fügen Sie zwei Methoden hinzu

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

Bildschirmfoto freigeben. Teilen Sie die Implementierung hier

    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"));
    }
11
Mani kandan

Ich konnte Silent Knights Antwort nicht zur Arbeit kommen, bis ich hinzufügte 

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

zu meinem AndroidManifest.xml.

4
Chase Roberts

Mit dem folgenden Code können Sie die Bitmap für die auf dem Bildschirm angezeigte Ansicht abrufen. Sie können angeben, welche Ansicht Bitmap erstellen soll.

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

Sie können einen Screenshot von jedem Teil Ihrer Ansicht erstellen. Sie benötigen lediglich die Referenz des Layouts, dessen Screenshot Sie erstellen möchten. In Ihrem Fall möchten Sie beispielsweise den Screenshot Ihrer Aktivität anzeigen lassen. Nehmen Sie an, dass Ihr Aktivitätsstammlayout Lineares Layout ist. 

   // 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;
      }
3
Chandra Sharma

für den Screenshot

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

zum Speichern des Screenshots

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

und zum teilen

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

und einfach in der onclick können Sie diese Methoden aufrufen

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

Für alle Xamarin-Benutzer:

Xamarin.Android Code:

Erstellen Sie eine externe Klasse (ich habe eine Schnittstelle für jede Plattform und habe diese 3 Funktionen von der Android-Plattform implementiert):

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

Jetzt führen Sie den obigen Code in Ihrer Aktivität folgendermaßen aus:

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

Ich hoffe, es wird für jeden von Nutzen sein.

1
Roy Doron

So mache ich einen Screenshot. Die oben beschriebenen Lösungen funktionieren gut für API <24, für API 24 und höher ist jedoch eine andere Lösung erforderlich. Ich habe diese Methode mit API 15, 24 und 27 getestet.

Ich habe die folgenden Methoden in MainActivity.Java platziert:

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

Ich habe die folgenden Berechtigungen und Anbieter in meine AndroidManifest.xml eingefügt:

<?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>

Ich habe eine Datei mit dem Namen provider_paths.xml (siehe unten) erstellt, um den FileProvider dahin zu bringen, wo der Screenshot gespeichert werden soll. Die Datei enthält ein einfaches Tag, das auf das Stammverzeichnis des externen Verzeichnisses verweist. 

Die Datei wurde im Ressourcenordner res/xml abgelegt (wenn Sie hier keinen XML-Ordner haben, erstellen Sie einfach einen und legen Sie Ihre Datei dort ab).

provider_paths.xml:

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

Wenn jemand nach der Lösung von SilengKnight eine Java.io.FileNotFoundException erhält, besteht das Problem wahrscheinlich darin, dass das Schreiben in den Speicher nicht zulässig war (obwohl wir die Benutzerberechtigung im Manifest hinzugefügt haben). Ich habe es gelöst, indem ich dies in die Store-Funktion eingefügt habe, bevor ich einen neuen FileOutputStream erstellt habe.

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);
    }
0
Simon Iyamu

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

mehr dazu in: https://www.youtube.com/watch?v=LRCRNvzamwY&feature=youtu.be

0
Van Toan Vu