web-dev-qa-db-fra.com

Comment faire une capture d'écran de l'activité en cours et ensuite la partager?

Je dois prendre une capture d'écran de Activity (sans la barre de titre et l'utilisateur NE doit PAS voir qu'une capture d'écran a bien été prise), puis la partager via un bouton du menu Action "Partager". J'ai déjà essayé des solutions, mais elles n'ont pas fonctionné pour moi. Des idées?

30
just_deko

Voici comment j'ai capturé l'écran et partagé.

First, obtenez la vue racine de l'activité en cours:

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

Second, capturez la vue racine:

 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, enregistrez la Bitmap dans la carte 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();
    }
}

Enfin, partagez la capture d'écran de la Activity actuelle:

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

J'espère que mes codes vous inspireront.

METTRE À JOUR:

Ajoutez les autorisations ci-dessous dans votre AndroidManifest.xml:

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

Parce qu'il crée et accède aux fichiers du stockage externe.

METTRE À JOUR:

À partir d'Android 7.0, les liens de partage de fichiers Nougat sont interdits. Pour résoudre ce problème, vous devez implémenter FileProvider et partager "content: //" uri not "fichier: //" uri.

Ici est une bonne description comment le faire.

78
SilentKnight

créer un bouton de partage en cliquant sur l'écouteur 

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

Ajouter deux méthodes

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

Partager la capture d'écran. partage de mise en œuvre ici

    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

Je ne pouvais pas obtenir la réponse de Silent Knight travailler avant d’ajouter 

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

à mon AndroidManifest.xml.

4
Chase Roberts

Vous pouvez utiliser le code ci-dessous pour obtenir le bitmap de la vue que vous voyez à l'écran. Vous pouvez spécifier quelle vue créer.

    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

Vous pouvez prendre une capture d'écran de n'importe quelle partie de votre vue. Vous avez juste besoin de la référence de la mise en page dont vous voulez voir la capture. par exemple, dans votre cas, vous voulez la capture d'écran de votre activité. supposons que la disposition de votre racine d'activité soit une disposition linéaire. 

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

pour prendre une capture d'écran

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

pour sauvegarder une capture d'écran

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

et pour le partage

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

et simplement dans la onclick vous pouvez appeler ces méthodes

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

Pour tous les utilisateurs Xamarin:

Xamarin.Android Code:

Créez une classe externe (j'ai une interface pour chaque plate-forme et j'ai implémenté les 3 fonctions ci-dessous depuis la plate-forme Android):

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

Maintenant, à partir de votre activité, vous exécutez le code ci-dessus comme ceci:

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

J'espère qu'il sera utile à quiconque.

1
Roy Doron

C'est ce que j'utilise pour prendre une capture d'écran. Les solutions décrites ci-dessus fonctionnent bien pour les API <24, mais pour les API 24 et supérieures, une autre solution est nécessaire. J'ai testé cette méthode sur les API 15, 24 et 27.

J'ai placé les méthodes suivantes dans 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;
}
}

J'ai placé les autorisations et le fournisseur suivants dans mon fichier 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>

J'ai créé un fichier appelé provider_paths.xml (voir ci-dessous) pour indiquer à FileProvider où enregistrer la capture d'écran. Le fichier contient une balise simple qui pointe vers la racine du répertoire externe. 

Le fichier a été placé dans le dossier de ressources res/xml (si vous n’avez pas de dossier xml ici, créez-en un et placez-y votre fichier).

provider_paths.xml:

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

Si une personne obtient une exception Java.io.FileNotFoundException, le problème est probablement, suite à la solution de SilengKnight, que l'écriture dans la mémoire n'a pas été autorisée (Bien que nous ayons ajouté l'autorisation d'utilisateur au manifeste). Je l'ai résolu en ajoutant ceci dans la fonction store avant de créer un nouveau FileOutputStream.

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

Voici comment j'ai capturé l'écran et partagé. Jetez un oeil si vous êtes intéressé.

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

Et la méthode qui enregistre l'image bitmap sur un stockage externe:

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

voir plus dans: https://www.youtube.com/watch?v=LRCRNvzamwY&feature=youtu.be

0
Van Toan Vu