2017-02-07 2 views
2
public class MainActivity extends AppCompatActivity { 

private static final String TAG = "MainActivity"; 
private static final int REQUEST_CODE = 1234; 
private int mScreenDensity; 
private MediaProjectionManager mProjectionManager; 
private static final int DISPLAY_WIDTH = 720; 
private static final int DISPLAY_HEIGHT = 1280; 
private MediaProjection mMediaProjection; 
private VirtualDisplay mVirtualDisplay; 
private ToggleButton mToggleButton; 
private MediaRecorder mMediaRecorder; 
private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); 
private static final int REQUEST_PERMISSIONS = 10; 

static { 
    ORIENTATIONS.append(Surface.ROTATION_0, 90); 
    ORIENTATIONS.append(Surface.ROTATION_90, 0); 
    ORIENTATIONS.append(Surface.ROTATION_180, 270); 
    ORIENTATIONS.append(Surface.ROTATION_270, 180); 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 


    DisplayMetrics metrics = new DisplayMetrics(); 
    getWindowManager().getDefaultDisplay().getMetrics(metrics); 
    mScreenDensity = metrics.densityDpi; 


    mProjectionManager = (MediaProjectionManager) getSystemService 
      (Context.MEDIA_PROJECTION_SERVICE); 

    mToggleButton = (ToggleButton) findViewById(R.id.toggle); 
    mToggleButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if (ContextCompat.checkSelfPermission(MainActivity.this, 
        Manifest.permission.WRITE_EXTERNAL_STORAGE) + ContextCompat 
        .checkSelfPermission(MainActivity.this, 
          Manifest.permission.RECORD_AUDIO) 
        != PackageManager.PERMISSION_GRANTED) { 
       if (ActivityCompat.shouldShowRequestPermissionRationale 
         (MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) || 
         ActivityCompat.shouldShowRequestPermissionRationale 
           (MainActivity.this, Manifest.permission.RECORD_AUDIO)) { 
        mToggleButton.setChecked(false); 
        Snackbar.make(findViewById(android.R.id.content), R.string.label_permissions, 
          Snackbar.LENGTH_INDEFINITE).setAction("ENABLE", 
          new View.OnClickListener() { 
           @Override 
           public void onClick(View v) { 
            ActivityCompat.requestPermissions(MainActivity.this, 
              new String[]{Manifest.permission 
                .WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, 
              REQUEST_PERMISSIONS); 
           } 
          }).show(); 
       } else { 
        ActivityCompat.requestPermissions(MainActivity.this, 
          new String[]{Manifest.permission 
            .WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, 
          REQUEST_PERMISSIONS); 
       } 
      } else { 
       onToggleScreenShare(v); 
      } 
     } 
    }); 
} 

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 

    Log.d(TAG, " requestCode " + requestCode + " resultCode " + requestCode); 

    if (REQUEST_CODE == requestCode) { 
     if (resultCode == RESULT_OK) { 
      mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data); 
      startRecording(); // defined below 
     } else { 
      Log.d(TAG, "Persmission denied"); 
     } 
    } 
} 

private static final String VIDEO_MIME_TYPE = "video/avc"; 
private static final int VIDEO_WIDTH = 720; 
private static final int VIDEO_HEIGHT = 1280; 
// … 
private boolean mMuxerStarted = false; 
private Surface mInputSurface; 
private MediaMuxer mMuxer; 
private MediaCodec mVideoEncoder; 
private MediaCodec.BufferInfo mVideoBufferInfo; 
private int mTrackIndex = -1; 

private final Handler mDrainHandler = new Handler(Looper.getMainLooper()); 
private Runnable mDrainEncoderRunnable = new Runnable() { 
    @Override 
    public void run() { 
     drainEncoder(); 
    } 
}; 

private void startRecording() { 

    DisplayManager dm = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE); 
    Display defaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY); 
    if (defaultDisplay == null) { 
     throw new RuntimeException("No display found."); 
    } 
    prepareVideoEncoder(); 

    try { 
     mMuxer = new MediaMuxer(Environment.getExternalStoragePublicDirectory(Environment 
       .DIRECTORY_DOWNLOADS) + "/video.mp4", MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); 
    } catch (IOException ioe) { 
     throw new RuntimeException("MediaMuxer creation failed", ioe); 
    } 

    // Get the display size and density. 
    DisplayMetrics metrics = getResources().getDisplayMetrics(); 
    int screenWidth = metrics.widthPixels; 
    int screenHeight = metrics.heightPixels; 
    int screenDensity = metrics.densityDpi; 

    // Start the video input. 
    mMediaProjection.createVirtualDisplay("Recording Display", screenWidth, 
      screenHeight, screenDensity, 0 /* flags */, mInputSurface, 
      null /* callback */, null /* handler */); 

    // Start the encoders 
    drainEncoder(); 
} 

private void prepareVideoEncoder() { 

    mVideoBufferInfo = new MediaCodec.BufferInfo(); 
    MediaFormat format = MediaFormat.createVideoFormat(VIDEO_MIME_TYPE, VIDEO_WIDTH, VIDEO_HEIGHT); 
    int frameRate = 15; // 30 fps 

    // Set some required properties. The media codec may fail if these aren't defined. 
    format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); 
    //format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 8000); 
    format.setInteger(MediaFormat.KEY_BIT_RATE, 6000000); // 6Mbps 
    format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate); 
    //format.setInteger(MediaFormat.KEY_CAPTURE_RATE, frameRate); 
    // format.setInteger(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, 1000000/frameRate); 
    //format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1); 
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10); // 1 seconds between I-frames 

    // Create a MediaCodec encoder and configure it. Get a Surface we can use for recording into. 
    try { 
     mVideoEncoder = MediaCodec.createEncoderByType(VIDEO_MIME_TYPE); 
     mVideoEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); 
     mInputSurface = mVideoEncoder.createInputSurface(); 
     mVideoEncoder.start(); 
    } catch (IOException e) { 
     releaseEncoders(); 
    } 
} 

private void releaseEncoders() { 


    mDrainHandler.removeCallbacks(mDrainEncoderRunnable); 
    if (mMuxer != null) { 
     if (mMuxerStarted) { 
      mMuxer.stop(); 
     } 
     mMuxer.release(); 
     mMuxer = null; 
     mMuxerStarted = false; 
    } 
    if (mVideoEncoder != null) { 
     mVideoEncoder.stop(); 
     mVideoEncoder.release(); 
     mVideoEncoder = null; 
    } 
    if (mInputSurface != null) { 
     mInputSurface.release(); 
     mInputSurface = null; 
    } 
    if (mMediaProjection != null) { 
     mMediaProjection.stop(); 
     mMediaProjection = null; 
    } 
    mVideoBufferInfo = null; 
    //mDrainEncoderRunnable = null; 
    mTrackIndex = -1; 
} 

private boolean drainEncoder() { 
    mDrainHandler.removeCallbacks(mDrainEncoderRunnable); 
    while (true) { 
     int bufferIndex = mVideoEncoder.dequeueOutputBuffer(mVideoBufferInfo, 0); 

     if (bufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) { 
      // nothing available yet 
      break; 
     } else if (bufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { 
      // should happen before receiving buffers, and should only happen once 
      if (mTrackIndex >= 0) { 
       throw new RuntimeException("format changed twice"); 
      } 
      mTrackIndex = mMuxer.addTrack(mVideoEncoder.getOutputFormat()); 
      if (!mMuxerStarted && mTrackIndex >= 0) { 
       mMuxer.start(); 
       mMuxerStarted = true; 
      } 
     } else if (bufferIndex < 0) { 
      // not sure what's going on, ignore it 
     } else { 
      ByteBuffer encodedData = mVideoEncoder.getOutputBuffer(bufferIndex); 
      if (encodedData == null) { 
       throw new RuntimeException("couldn't fetch buffer at index " + bufferIndex); 
      } 

      if ((mVideoBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { 
       mVideoBufferInfo.size = 0; 
      } 

      if (mVideoBufferInfo.size != 0) { 
       if (mMuxerStarted) { 
        encodedData.position(mVideoBufferInfo.offset); 
        encodedData.limit(mVideoBufferInfo.offset + mVideoBufferInfo.size); 
        mMuxer.writeSampleData(mTrackIndex, encodedData, mVideoBufferInfo); 
       } else { 
        // muxer not started 
       } 
      } 

      mVideoEncoder.releaseOutputBuffer(bufferIndex, false); 

      if ((mVideoBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { 
       break; 
      } 
     } 
     Log.d(TAG, "Recording"); 
    } 

    mDrainHandler.postDelayed(mDrainEncoderRunnable, 10); 

    return false; 
} 


public void onToggleScreenShare(View view) { 
    if (((ToggleButton) view).isChecked()) { 
     if (mMediaProjection == null) { 
      startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE); 
     } else { 
      startRecording(); 
     } 
    } else { 
     releaseEncoders(); 
    } 
} 

}comment prendre l'autorisation de capture d'écran MediaProjectionManager pour une seule fois au lieu de chaque utilisation?

startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE); 

Cette ligne d'autorisation de demande de code pour la capture écran. Chaque fois que mon code appelle cela et affiche une boîte de dialogue pour la permission. Mais si je clique sur "ne plus afficher ceci", il ne demandera pas la permission mais accordera l'autorisation en arrière-plan. Comment puis-je prendre la permission une seule fois et accorder tout le temps sans sélectionner ne pas montrer à nouveau ?? code complet est donné ici

+0

postez le code complet s'il vous plaît. – tahsinRupam

+0

Rupam, modifier kore disi –

+0

OK, dara dekhtesi – tahsinRupam

Répondre

1
public void onToggleScreenShare(View view) { 
if (((ToggleButton) view).isChecked()) { 
    if (mMediaProjection == null) { 
     startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE); 
    } else { 
     startRecording(); 
    } 
} else { 
    releaseEncoders(); 
} 
} 

Sur cet écran rapide méthode Méthode startActivityForResult() l'autorisation de capture. Si l'autorisation de subvention ou nier l'appel de transfert de code à onActivityResultMethod()

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 

Log.d(TAG, " requestCode " + requestCode + " resultCode " + requestCode); 

if (REQUEST_CODE == requestCode) { 
    if (resultCode == RESULT_OK) { 
     mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data); 
     startRecording(); // defined below 
    } else { 
     Log.d(TAG, "Persmission denied"); 
    } 
} 
} 

Sur cette méthode, nous obtenons les données d'intention et resultCode. Pour utiliser plus MediaProjectionManager sans demander l'autorisation continue, nous devons sauver référence de l'intention et la valeur de resultCode et utiliser mediaProjectionManager via cette ligne de code

mMediaProjection = mProjectionManager.getMediaProjection(saveResult, savedIntent); 

Il ne demander la permission à nouveau que l'autorisation est déjà accordée