2017-02-07 75 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(); 
    } 
} 

}如何僅將媒體投影管理器屏幕鎖定權限設爲每次使用一次而不是每次使用?

startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE); 

這行代碼請求許可的用於捕獲屏幕。每次我的代碼都會調用它,並顯示一個權限對話框。但是,如果我點擊「不再顯示這個」,它不會請求權限,但在後臺授予權限。我怎樣才能獲得許可只有一次,並授予所有時間沒有選擇不再顯示?此處給出完整代碼

+0

請發送完整的代碼。 – tahsinRupam

+0

Rupam,編輯kore disi –

+0

好的,dara dekhtesi – tahsinRupam

回答

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

對此方法的startActivityForResult()方法提示屏幕捕獲權限。如果授予許可或拒絕它()代碼轉接到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"); 
    } 
} 
} 

在此方法中,我們得到的數據意圖和resultCode爲。爲了進一步使用MediaProjectionManager沒有要求連續許可之前,我們必須保存發送resultCode的意圖和價值的基準,並通過這行代碼

mMediaProjection = mProjectionManager.getMediaProjection(saveResult, savedIntent); 

使用mediaProjectionManager因此,作爲許可業已給予

就不會再申請許可
相關問題