web-dev-qa-db-ja.com

スクリーンショットを撮ってプログラムで共有する方法

私はAndroid=でアプリケーションを作成しています。このアプリケーションでは、自分のアクティビティのスクリーンショットを撮り、添付ファイルとしてメールで送信する必要があります。

現在のページのスクリーンショットを撮り、メール、Bluetooth、Twitter、Facebookで共有したい。

私のコードは次のとおりです:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
  MenuInflater inflater = getMenuInflater();
  inflater.inflate(R.menu.menuselected1, menu);
  return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

  switch (item.getItemId()) {
    case R.id.ScreenShot:

    try {
        takeScreenShot(this);
    }
    catch (Exception e) {
        System.out.println(e);
    }

    return true;

    default:
    return super.onOptionsItemSelected(item);
  }
}

private static void savePic(Bitmap b, String strFileName) {
  FileOutputStream fos = null;
  try {
      fos = new FileOutputStream(strFileName);
      if (null != fos) {
        b.compress(Bitmap.CompressFormat.PNG, 90, fos);
        System.out.println("b is:"+b);
        fos.flush();
        fos.close();
      }
  } catch (FileNotFoundException e) {
          e.printStackTrace();
  } catch (IOException e) {
          e.printStackTrace();
  }
}

public static void shoot(Activity a,String b) {
  //savePic(takeScreenShot(a), "sdcard/xx.png");
  savePic(takeScreenShot(a), b);
}

private static Bitmap takeScreenShot(Activity activity) {
  View view = activity.getWindow().getDecorView();
  view.setDrawingCacheEnabled(true);
  view.buildDrawingCache();
  Bitmap b1 = view.getDrawingCache();
  Rect frame = new Rect();
  activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
  int statusBarHeight = frame.top;
  int width = activity.getWindowManager().getDefaultDisplay().getWidth();
  int height = activity.getWindowManager().getDefaultDisplay()
               .getHeight();

  // Bitmap b = Bitmap.createBitmap(b1, 0, 25, 320, 455);
  Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height
                                 - statusBarHeight);
  view.destroyDrawingCache();
  return b;
}
28
user1025050

現在のアクティビティのスクリーンショットを撮るためにこれを試してください:

Android 2.2:

private static Bitmap takeScreenShot(Activity activity)
{
    View view = activity.getWindow().getDecorView();
    view.setDrawingCacheEnabled(true);
    view.buildDrawingCache();
    Bitmap b1 = view.getDrawingCache();
    Rect frame = new Rect();
    activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
    int statusBarHeight = frame.top;

    DisplayMetrics displaymetrics = new DisplayMetrics(); 
    mContext.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);

    int width = displaymetrics.widthPixels;
    int height = displaymetrics.heightPixels;

    Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height  - statusBarHeight);
    view.destroyDrawingCache();
    return b;
}
private static void savePic(Bitmap b, String strFileName)
{
    FileOutputStream fos = null;
    try
    {
        fos = new FileOutputStream(strFileName);
        if (null != fos)
        {
            b.compress(Bitmap.CompressFormat.PNG, 90, fos);
            fos.flush();
            fos.close();
        }
    }
    catch (FileNotFoundException e)
    {
        e.printStackTrace();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}
37

「現在のページのスクリーンショット」が「私の活動の1つのスクリーンショット」を意味する場合は、次のように調整できます ViewsをビットマップバックアップされたCanvasにレンダリングし、保存します。ビットマップからの画像

「現在のページのスクリーンショット」とは、「他の誰かのアクティビティのスクリーンショット」を意味し、Android SDK、プライバシーとセキュリティ上の理由から明らかではありません。デバイスをルート化したさまざまな手法があります。ユーザーはスクリーンショットを撮るために使用できます。

15
CommonsWare

1。共有ボタンを作成します

私はアクションバーに私のものを望んでいたので、share_menu.xmlファイルを作成しました。

_<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto">

    <item
        Android:id="@+id/share_item"
        app:showAsAction="always|withText"
        Android:title="Share"
        Android:icon="@drawable/share_icon"
        Android:actionProviderClass=
            "Android.widget.ShareActionProvider" />
</menu>
_

これにより、アクションバーにボタンが追加され、share_iconとテキストが追加されます。

2。アクティビティ(またはフラグメント)に共有メニューを追加します

これをフラグメント内で行ったので、フラグメントファイルに以下のコードを追加しました。アクティビティ内にいる場合は、代わりにpublic boolean onCreateOptionsMenu(Menu menu)をオーバーライドします。

_@Override
public void onCreateOptionsMenu(
        Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.share_menu, menu);
}
_

これをフラグメントで行う場合は、onCreate()に次のように追加する必要があります。

_setHasOptionsMenu(true);
_

。ボタンアクション/コールバック/ onclickを設定

これが共有を開始するものです。

_@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.share_item){
            Bitmap bm = screenShot(this.getView());
            File file = saveBitmap(bm, "Mantis_image.png");
            Log.i("chase", "filepath: "+file.getAbsolutePath());
            Uri uri = Uri.fromFile(new File(file.getAbsolutePath()));
            Intent shareIntent = new Intent();
            shareIntent.setAction(Intent.ACTION_SEND);
            shareIntent.putExtra(Intent.EXTRA_TEXT, "Check out my app.");
            shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
            shareIntent.setType("image/*");
            shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            startActivity(Intent.createChooser(shareIntent, "share via"));
        }
        return super.onOptionsItemSelected(item);
    }
_

これが2つの魔法のメソッドを呼び出すことに注意してください。

screenShot():

_private Bitmap screenShot(View view) {
    Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),view.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    view.draw(canvas);
    return bitmap;
}

private static File saveBitmap(Bitmap bm, String fileName){
    final String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Screenshots";
    File dir = new File(path);
    if(!dir.exists())
        dir.mkdirs();
    File file = new File(dir, fileName);
    try {
        FileOutputStream fOut = new FileOutputStream(file);
        bm.compress(Bitmap.CompressFormat.PNG, 90, fOut);
        fOut.flush();
        fOut.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return file;
}
_

重要

_AndroidManifest.xml_に、以下を追加する必要があります。

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

または、スクリーンショットは保存されず、Gmailは空のファイルを添付しようとしていると考えます。

また、SOの回答の多くは、shareIntent.setType()に_"*/*"_を使用するように言っていますが、これはFacebookの共有に問題を引き起こすため、_"image/*"_。

4
Chase Roberts

Kotlin完全なソリューションコードと権限チェック:

1- Java/Kotlin/Rx機能、ライブラリの依存関係を追加してスクリーンショットを撮るには、この素敵なライブラリを使用します: InstaCapture github link

 implementation "com.github.tarek360:instacapture:2.0.1"

2-すべてのAndroidバージョンでの互換性について権限を確認する必要があります:

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            ) != PackageManager.PERMISSION_GRANTED
        ) { // Needs permission so request it
            DeviceUtil.showAlertMsg(this, GeneralDicModel.shareMsgScreenShot!!)
            requestPermissions(
                arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
                PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE
            )   //callback  result to onRequestPermissionsResult
        } else { //Has got the permission before or doesn't need
            screenShotAndShareIt()
        }

3-許可結果の確認:

 override fun onRequestPermissionsResult(
    requestCode: Int, permissions: Array<out String>,
    grantResults: IntArray
) {
    when (requestCode) {
        PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE -> {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                screenShotAndShareIt()
            } else {
                //  toast("Permission must be granted in order to save scrrenshot file")
            }
        }
    }
}

4- Funcコールのスクリーンショットを撮って意図的に共有する:

 fun screenShotAndShareIt() {
    Instacapture.capture(this, object : SimpleScreenCapturingListener() {
    override fun onCaptureComplete(bitmap: Bitmap) {
    val state = Environment.getExternalStorageState()
            if (Environment.MEDIA_MOUNTED == state) {
                val path: String = Environment.getExternalStorageDirectory().toString()  
                val picDir = File(path.plus("/myPic"))
                if (!picDir.exists()) {
                    picDir.mkdir()
                }
                var bitmapScreenShot = bitmap
                val fileName = "screenshot" + ".jpg"
                val picFile = File(picDir.path.plus("/" + fileName))
                try {
                    picFile.createNewFile()
                    val picOut = FileOutputStream(picFile)
                    bitmapScreenShot =
                        Bitmap.createBitmap(bitmapScreenShot, 0, 0, bitmapScreenShot.width, bitmapScreenShot.height)
                    val saved: Boolean = bitmapScreenShot.compress(Bitmap.CompressFormat.JPEG, 100, picOut)
                    if (saved) {
                        Log.i(
                            TAG,
                            "ScreenShotAndShareIt : Image saved to your device Pictures " + "directory! + ${picFile.absolutePath}"
                        )
                    } else {
                        Log.i(TAG, "ScreenShotAndShareIt Error on Save! + ${picFile.absolutePath}")
                    }
                    picOut.close()

                    // share via intent
                    val intent: Intent = Intent(Android.content.Intent.ACTION_SEND)
                    intent.type = "image/jpeg"
                    intent.putExtra(Intent.EXTRA_STREAM, Uri.parse(picFile.absolutePath))
                    startActivity(Intent.createChooser(intent, "Sharing"))
                } catch (e: Exception) {
                    Log.i(TAG, "ScreenShotAndShareIt Error catch : " + e.printStackTrace())
                }
            } else {
                //Error
                Log.i(TAG, "ScreenShotAndShareIt Error Environment.MEDIA_MOUNTED == state : " )
            }
 }
 })

5-この変数を宣言します。

val PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 100

6- AndroidManifest.xmlにこの権限を追加することを忘れないでください:

    <uses-permission Android:name="Android.permission.INTERNET"/>
    <uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"/>
0
Hamed Jaliliani