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