2015-05-12 5 views
22

Ich muss einen Screenshot von Activity (ohne die Titelleiste, und der Benutzer sollte nicht sehen, dass ein Screenshot tatsächlich aufgenommen wurde) und dann teilen Sie es über einen Aktionsmenü Button "teilen". Ich habe bereits einige Lösungen versucht, aber sie haben nicht für mich funktioniert. Irgendwelche Ideen?Wie mache ich einen Screenshot der aktuellen Aktivität und teile ihn dann?

+1

try [diese] (http://stackoverflow.com/questions/21228239/android-capture-screenshot-programmatically-without-title-bar) – dora

+0

@dora dies nicht die perfekte Lösung für mich, weil es Layouts verwendet und ich nichts tun will außer nur einen Screenshot der Aktivität zu machen. –

+0

Wie auch immer Sie eine Ansicht erfassen. Entweder über das XML-Layout oder das programmatisch erstellte Layout. Dora hat Recht. – SmulianJulian

Antwort

64

So habe ich den Bildschirm erfasst und geteilt. Schauen Sie, wenn Sie interessiert sind.

Erste, Stammansicht aus der laufenden Tätigkeit erhalten:

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

Zweite, fangen 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; 
} 

Dritte, speichern Sie die Bitmap in die SD-Karte:

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

Endlich, teilen sich 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 durch meine Codes inspiriert wird.

UPDATE:

hinzufügen unter Berechtigungen in Ihrem AndroidManifest.xml:

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

Weil es erstellt und greift auf Dateien in externen Speicher.

UPDATE:

ab Android 7.0 Nougat-Sharing-Datei Links forbiden. Um damit umzugehen, müssen Sie FileProvider implementieren und "content: //" uri nicht "file: //" uri teilen.

Here ist eine gute Beschreibung, wie es geht.

+0

seine Aufnahme des Screenshots aber nicht in der Galerie angezeigt, wenn ich den Gerätespeicher überprüfen, gibt es Screenshot-Dateien, aber wenn ich versuche, sie zu klicken, sagt es nicht möglich, App zu finden, um diese Datei zu öffnen –

+0

Es kann nicht sein. Fangen Sie 'ActivityNotFoundException' von' startActivity (Intent.createChooser (intent, "Share Screenshot")); 'und danach' Toast.makeText (Kontext, "No App Available", Toast.LENGTH_SHORT) .show(); '. – SilentKnight

+2

java.io.FileNotFoundException:/storage/emuliert/0/Screenshots/Bild: Öffnen fehlgeschlagen: ENOENT (Keine solche Datei oder Verzeichnis) –

4

Sie können den folgenden Code verwenden, um die Bitmap für die Ansicht zu erhalten, die Sie auf dem Bildschirm sehen 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; 
    } 
2

Sie können einen Screenshot von irgendeinem Teil Ihrer Ansicht machen. Sie brauchen nur die Referenz des Layouts, von dem Sie den Screenshot wollen. Zum Beispiel in Ihrem Fall möchten Sie den Screenshot Ihrer Aktivität. Angenommen, Ihr Aktivitätsstammlayout ist Linear Layout.

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

konnte ich nicht Silent Knight's answer zu arbeiten, bis ich

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

meiner AndroidManifest.xml hinzugefügt zu arbeiten.

0

So habe ich den Bildschirm erfasst und geteilt. Schauen Sie, wenn Sie interessiert sind.

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

Und die Methode, die das Bitmap-Bild auf externe 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 sehen in: https://www.youtube.com/watch?v=LRCRNvzamwY&feature=youtu.be

6

Share-Taste mit einem Klick auf Zuhörer

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

Add erstellen zwei Methoden

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

Bildschirm teilen teilen. Sharing 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")); 
    } 
+1

Das ist gute Codierung! –

+1

Saubere und elegante Antwort :) – ch3tanz

+0

Danke :) # ch3tanz –

0

Für alle Xamarin Benutzer verwenden:

Xamarin.Android Code:

eine externe Klasse erstellen (Ich habe eine Schnittstelle für Jede Plattform, und ich implementierte diese 3 Funktionen von Android-Plattform):

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

nun von Ihrer Aktivität führen Sie den obigen Code wie folgt 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"); 
        } 
       }); 

Hoffe, dass es von Nutzen für jeden sein wird.

1

für Screenshot Aufnahme

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

für Screenshot Speichern

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 für

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

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

rufen
0

Dies ist, was ich benutze, um einen Screenshot zu machen. Die oben beschriebenen Lösungen funktionieren gut für API < 24, aber für API 24 und höher wird eine andere Lösung benötigt. Ich habe diese Methode auf 15 API getestet, 24, & 27.

ich die folgenden Methoden in MainActivity.java gestellt:

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 die folgenden Berechtigungen und Anbieter in meine AndroidManifest.xml gelegt:

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

Die Datei wurde in den Ressourcenordner res/xml gestellt (wenn Sie keinen xml-Ordner hier 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> 
Verwandte Themen