Reputation: 141
I referred to Grafika's CameraCaptureActivity to record video while simultaneously displaying the camera preview.
The changes I have made to the code (that is relevant) is -
The user clicks a button to launch PreferencesActivity
, selects the preferred camera resolution (which stores the width
and height
values) and clicks the "Back" button to return to the CameraCaptureActivity
.
In the openCamera
method- Instead of hard coding width
and height
I am picking the values from SharedPreferences
The AspectFrameLayout's
attribute is set this way android:background="@android:color/holo_blue_bright"
. So the preview is matching the size of the AspectFrameLayout
This problem occurs mostly when the size is being changed from a bigger resolution to a smaller one.
In smaller screens (HTC One M7 / Xperia SP)
In larger screens (Samsung Galaxy Tab S / Nexus 9) -
I have noticed that this happens because onSurfaceChanged
gets called twice. The first time it is with wrong values for width
and height
and the second time it is with the correct values.
However, the layout looks fine if I leave the activity and come back to it without making any changes. (Like going to PreferencesActivity
and clicking "Back" without changing the resolution.)
I have set the following in AndroidManifest.xml
-
<activity android:name=".activity.camera.CameraCaptureActivity"
android:launchMode="singleInstance"
android:screenOrientation="landscape"
android:theme="@android:style/Theme.Holo.Light.NoActionBar">
</activity>
EDIT: This issue occurs with only the preview. The recorded video is sized correctly.
EDIT 2: This is my layout.xml
<RelativeLayout xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cameracapturescreen_rootparent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
tools:context="com.myapp.CameraCaptureActivity">
<com.myapp.activity.camera.PreviewFrameLayout
android:id="@+id/surfaceview_framelayout"
android:layout_width="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="@android:color/holo_blue_bright"
android:layout_height="wrap_content">
<android.opengl.GLSurfaceView
android:id="@+id/cameraPreview_surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="left"/>
</com.myapp.activity.camera.PreviewFrameLayout>
I am sure I am passing the correct values to set the width and height of the view because the preview is set correctly if I leave the activity and come back to it without making any changes. (Like going to another activity and clicking "Back" to return to CameraCaptureActivity
.)
Upvotes: 4
Views: 605
Reputation: 5195
I am not clear with what you are trying to say if the problem is with the preview .. then you can use the following code in your open camera method
add this thing code in your openCamera() method , i just checked with this ... hope this helps
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
mCamera.setDisplayOrientation(90);
} else {
mCamera.setDisplayOrientation(180);
}
Add this code in your handleSetSurfaceTexture() method
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
mCamera.setDisplayOrientation(90);
} else {
mCamera.setDisplayOrientation(180);
}
Camera.Parameters parms = mCamera.getParameters();
CameraUtils.choosePreviewSize(parms, mCameraPreviewWidth, mCameraPreviewHeight);
// Give the camera a hint that we're recording video. This can have a big
// impact on frame rate.
parms.setRecordingHint(true);
mCamera.setParameters(parms);
and this part of code in your onPause()
InputMethodManager imm = (InputMethodManager)getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(((EditText)findViewById(R.id.username)).getWindowToken(), 0);
if(imm.isAcceptingText()) {
Intent intent = new Intent(this, CameraCaptureActivity.class);
startActivity(intent);
}
Upvotes: 1
Reputation:
Use this to open camera
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(MediaStore.EXTRA_OUTPUT, MyFileContentProvider.CONTENT_URI);
startActivityForResult(i, CAMERA_RESULT);
Here is the MyFileContentProvider class
public class MyFileContentProvider extends ContentProvider {
public static final Uri CONTENT_URI = Uri.parse("content://com.algorithmapps.dmsimagesave/");
private static final HashMap<String, String> MIME_TYPES = new HashMap<String, String>();
static {
MIME_TYPES.put(".jpg", "image/jpeg");
MIME_TYPES.put(".jpeg", "image/jpeg");
}
@Override
public boolean onCreate() {
try {
File mFile = new File(getContext().getFilesDir(), "newImage.jpg");
if(!mFile.exists()) {
mFile.createNewFile();
}
getContext().getContentResolver().notifyChange(CONTENT_URI, null);
return (true);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
public String getType(Uri uri) {
String path = uri.toString();
for (String extension : MIME_TYPES.keySet()) {
if (path.endsWith(extension)) {
return (MIME_TYPES.get(extension));
}
}
return (null);
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
File f = new File(getContext().getFilesDir(), "newImage.jpg");
if (f.exists()) {
return (ParcelFileDescriptor.open(f,
ParcelFileDescriptor.MODE_READ_WRITE));
}
throw new FileNotFoundException(uri.getPath());
}
@Override
public Cursor query(Uri url, String[] projection, String selection,
String[] selectionArgs, String sort) {
throw new RuntimeException("Operation not supported");
}
@Override
public Uri insert(Uri uri, ContentValues initialValues) {
throw new RuntimeException("Operation not supported");
}
@Override
public int update(Uri uri, ContentValues values, String where,
String[] whereArgs) {
throw new RuntimeException("Operation not supported");
}
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
throw new RuntimeException("Operation not supported");
}
}
In onActivityResultMethod get image like this
if (resultCode == RESULT_OK && requestCode == CAMERA_RESULT) {
File out = new File(getFilesDir(), "newImage.jpg");
if(!out.exists()) {
Toast.makeText(getBaseContext(),
"Error while capturing image", Toast.LENGTH_LONG)
.show();
}
originalBitmap = BitmapFactory.decodeFile(out.getAbsolutePath());
}
than resize bitmap using this code,here i am resizing for 200 width * 200 height
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap resizedBitmap = Bitmap.createScaledBitmap(originalBitmap, 200, 200, false);
This method wont let your resized image Distorted. Hope it helps.
Upvotes: 1