web-dev-qa-db-ja.com

現在のアクティビティのスクリーンショットを撮って共有する方法は?

Activityのスクリーンショットを撮り(タイトルバーなしで、スクリーンショットが実際に撮られたことをユーザーが見るべきではない)、アクションメニューボタン「共有」で共有する必要があります。私はすでにいくつかの解決策を試しましたが、それらは私にはうまくいきませんでした。何か案は?

30
just_deko

これが、スクリーンをキャプチャして共有する方法です。

最初に、現在のアクティビティからルートビューを取得します:

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

Second、ルートビューをキャプチャします。

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

3番目Bitmapを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();
    }
}

最後に、現在の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();
    }
}

あなたが私のコードに触発されることを願っています。

UPDATE:

以下の権限をAndroidManifest.xmlに追加します。

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

外部ストレージにファイルを作成してアクセスするためです。

UPDATE:

Android 7.0 Nougat共有ファイルリンクは禁止されています。これに対処するには、FileProviderを実装し、 "file://" uriではなく "content://" uriを共有する必要があります。

ここ は、それを行う方法の良い説明です。

84
SilentKnight

リスナーをクリックして共有ボタンを作成

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

2つのメソッドを追加する

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

スクリーンショットを共有します。ここで実装を共有する

    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

サイレントナイトの答え を追加するまで仕事をすることができませんでした

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

わたしの AndroidManifest.xml

4
Chase Roberts

以下のコードを使用して、画面に表示されているビューのビットマップを取得できます。ビットマップを作成するビューを指定できます。

    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

ビューの任意の部分のスクリーンショットを撮ることができます。スクリーンショットが必要なレイアウトの参照だけが必要です。たとえば、あなたの場合、アクティビティのスクリーンショットが必要です。アクティビティのルートレイアウトが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
Chandra Sharma

スクリーンショットを取るため

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

スクリーンショットを保存するため

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

そして共有のために

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

そして、単にonclickでこれらのメソッドを呼び出すことができます

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

すべてのXamarinユーザーの場合:

Xamarin.Androidコード:

外部クラスを作成します(プラットフォームごとにインターフェイスがあり、以下の3つの関数を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();
        }
    }`

次に、アクティビティから、次のように上記のコードを実行します。

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

それが誰にとっても役に立つことを願っています。

1
Roy Doron

これは私がスクリーンショットを撮るために使用するものです。上記のソリューションは、API <24では正常に機能しますが、API 24以降では別のソリューションが必要です。 API 15、24、および27でこのメソッドをテストしました。

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

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>

スクリーンショットの保存先をFileProviderに指示するために、provider_paths.xmlというファイルを作成しました(以下を参照してください)。このファイルには、外部ディレクトリのルートを指す単純なタグが含まれています。

ファイルはリソースフォルダーres/xmlに配置されました(ここにxmlフォルダーがない場合は、作成してファイルを配置します)。

provider_paths.xml:

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

SilengKnightのソリューションに従ってJava.io.FileNotFoundExceptionが発生した場合、問題はおそらくストレージへの書き込みが許可されていないことです(マニフェストにユーザー許可を追加しましたが)。新しい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

これが、スクリーンをキャプチャして共有する方法です。興味があればご覧ください。

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

そして、ビットマップ画像を外部ストレージに保存する方法:

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

詳細を参照してください: https://www.youtube.com/watch?v=LRCRNvzamwY&feature=youtu.be

0
Van Toan Vu