Add MediaProjection samples
Change-Id: I630900bdcfecc7f1c57b406a0bae09a0e917124a
This commit is contained in:
@@ -2971,6 +2971,14 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity android:name=".media.projection.MediaProjectionDemo"
|
||||||
|
android:label="Media/MediaProjection">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.SAMPLE_CODE" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
<!-- ************************************* -->
|
<!-- ************************************* -->
|
||||||
<!-- APPWIDGET PACKAGE SAMPLES -->
|
<!-- APPWIDGET PACKAGE SAMPLES -->
|
||||||
<!-- ************************************* -->
|
<!-- ************************************* -->
|
||||||
|
|||||||
45
samples/ApiDemos/res/layout/media_projection.xml
Normal file
45
samples/ApiDemos/res/layout/media_projection.xml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2014 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<SurfaceView
|
||||||
|
android:id="@+id/surface"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_alignParentTop="true"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_alignParentBottom="true">
|
||||||
|
<ToggleButton
|
||||||
|
android:text="@string/screen_sharing_toggle"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:onClick="onToggleScreenShare"/>
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/spinner"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
@@ -918,6 +918,7 @@
|
|||||||
<string name="stream_video">Play Streaming Video</string>
|
<string name="stream_video">Play Streaming Video</string>
|
||||||
<string name="local_audio">Play Audio from Local File</string>
|
<string name="local_audio">Play Audio from Local File</string>
|
||||||
<string name="res_audio">Play Audio from Resources</string>
|
<string name="res_audio">Play Audio from Resources</string>
|
||||||
|
<string name="screen_sharing_toggle">Toggle screen sharing</string>
|
||||||
|
|
||||||
<!-- =========================== -->
|
<!-- =========================== -->
|
||||||
<!-- os examples strings -->
|
<!-- os examples strings -->
|
||||||
|
|||||||
@@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.example.android.apis.media.projection;
|
||||||
|
|
||||||
|
import com.example.android.apis.R;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.hardware.display.VirtualDisplay;
|
||||||
|
import android.media.projection.MediaProjection;
|
||||||
|
import android.media.projection.MediaProjectionManager;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Surface;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
import android.view.SurfaceView;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import android.widget.ToggleButton;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MediaProjectionDemo extends Activity {
|
||||||
|
private static final String TAG = "MediaProjectionDemo";
|
||||||
|
private static final int PERMISSION_CODE = 1;
|
||||||
|
private static final List<Resolution> RESOLUTIONS = new ArrayList<Resolution>() {{
|
||||||
|
add(new Resolution(640,360));
|
||||||
|
add(new Resolution(960,540));
|
||||||
|
add(new Resolution(1366,768));
|
||||||
|
add(new Resolution(1600,900));
|
||||||
|
}};
|
||||||
|
|
||||||
|
private int mScreenDensity;
|
||||||
|
private MediaProjectionManager mProjectionManager;
|
||||||
|
|
||||||
|
private int mDisplayWidth;
|
||||||
|
private int mDisplayHeight;
|
||||||
|
private boolean mScreenSharing;
|
||||||
|
|
||||||
|
private MediaProjection mMediaProjection;
|
||||||
|
private VirtualDisplay mVirtualDisplay;
|
||||||
|
private Surface mSurface;
|
||||||
|
private SurfaceView mSurfaceView;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.media_projection);
|
||||||
|
|
||||||
|
DisplayMetrics metrics = new DisplayMetrics();
|
||||||
|
getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||||
|
mScreenDensity = metrics.densityDpi;
|
||||||
|
|
||||||
|
mSurfaceView = (SurfaceView) findViewById(R.id.surface);
|
||||||
|
mSurface = mSurfaceView.getHolder().getSurface();
|
||||||
|
mProjectionManager =
|
||||||
|
(MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
|
||||||
|
|
||||||
|
ArrayAdapter<Resolution> arrayAdapter = new ArrayAdapter<Resolution>(
|
||||||
|
this, android.R.layout.simple_list_item_1, RESOLUTIONS);
|
||||||
|
Spinner s = (Spinner) findViewById(R.id.spinner);
|
||||||
|
s.setAdapter(arrayAdapter);
|
||||||
|
s.setOnItemSelectedListener(new ResolutionSelector());
|
||||||
|
s.setSelection(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if (mMediaProjection != null) {
|
||||||
|
mMediaProjection.stop();
|
||||||
|
mMediaProjection = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if (requestCode != PERMISSION_CODE) {
|
||||||
|
Log.e(TAG, "Unknown request code: " + requestCode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (resultCode != RESULT_OK) {
|
||||||
|
Toast.makeText(this,
|
||||||
|
"User denied screen sharing permission", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
|
||||||
|
mVirtualDisplay = createVirtualDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onToggleScreenShare(View view) {
|
||||||
|
if (((ToggleButton) view).isChecked()) {
|
||||||
|
shareScreen();
|
||||||
|
} else {
|
||||||
|
stopScreenSharing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shareScreen() {
|
||||||
|
mScreenSharing = true;
|
||||||
|
if (mSurface == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mMediaProjection == null) {
|
||||||
|
startActivityForResult(mProjectionManager.getScreenCaptureIntent(), PERMISSION_CODE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mVirtualDisplay = createVirtualDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopScreenSharing() {
|
||||||
|
mScreenSharing = false;
|
||||||
|
if (mVirtualDisplay == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mVirtualDisplay.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
private VirtualDisplay createVirtualDisplay() {
|
||||||
|
return mMediaProjection.createVirtualDisplay("ScreenSharingDemo",
|
||||||
|
mDisplayWidth, mDisplayHeight, mScreenDensity,
|
||||||
|
false /*isSecure*/, mSurface, null /*Callbacks*/, null /*Handler*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resizeVirtualDisplay() {
|
||||||
|
if (mVirtualDisplay == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mVirtualDisplay.resize(mDisplayWidth, mDisplayHeight, mScreenDensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ResolutionSelector implements Spinner.OnItemSelectedListener {
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) {
|
||||||
|
Resolution r = (Resolution) parent.getItemAtPosition(pos);
|
||||||
|
ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
|
||||||
|
if (getResources().getConfiguration().orientation
|
||||||
|
== Configuration.ORIENTATION_LANDSCAPE) {
|
||||||
|
mDisplayHeight = r.y;
|
||||||
|
mDisplayWidth = r.x;
|
||||||
|
} else {
|
||||||
|
mDisplayHeight = r.x;
|
||||||
|
mDisplayWidth = r.y;
|
||||||
|
}
|
||||||
|
lp.height = mDisplayHeight;
|
||||||
|
lp.width = mDisplayWidth;
|
||||||
|
mSurfaceView.setLayoutParams(lp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) { /* Ignore */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class MediaProjectionCallback extends MediaProjection.Callback {
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
mMediaProjection = null;
|
||||||
|
stopScreenSharing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SurfaceCallbacks implements SurfaceHolder.Callback {
|
||||||
|
@Override
|
||||||
|
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||||
|
mDisplayWidth = width;
|
||||||
|
mDisplayHeight = height;
|
||||||
|
resizeVirtualDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
|
mSurface = holder.getSurface();
|
||||||
|
if (mScreenSharing) {
|
||||||
|
shareScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
|
if (!mScreenSharing) {
|
||||||
|
stopScreenSharing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Resolution {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
|
||||||
|
public Resolution(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return x + "x" + y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user