I have made an application to capture photos from the camera.
I have created two Activities: In Activity1 there is one Button which starts the camera wehen it is clicked. When the image is captured, it is passed to Activity2.
However, when I run the application and start the Activity1 (with the one Button) and I click on the button to start the camera it displays a pop up window showing the message "Unfortunately, camera has stopped". There are no errors in the log-cat or on the console.
Can anyone help me. Please. Thanks a lot.
You need only one Activity if you use startActiviyForResult():
Bello, a simple source code for take a picture from camera app, you need to start Activity with startActiviyForResult() and receive the intent from camera application.
Java source code:
package com.example.coursandroid_chp;
import android.os.Bundle;
import android.provider.MediaStore;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class MediaActivity extends Activity {
private static final String TAG = "MediaActivity";
private static final int REQUEST_IMAGE_CAPTURE = 1;
private static final int REQUEST_VIDEO_CAPTURE = 2;
private Button mCameraPhotoButton;
private Button mCameraVideoButton;
private ImageView mPhotoImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.screen_media);
mCameraPhotoButton = (Button) this.findViewById(R.id.screen_media_camera_photo_button);
mCameraVideoButton = (Button) this.findViewById(R.id.screen_media_camera_video_button);
mPhotoImageView = (ImageView) this.findViewById(R.id.screen_media_photo_imageview);
mCameraPhotoButton.setOnClickListener(onClickListener);
mCameraVideoButton.setOnClickListener(onClickListener);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.screen_media, menu);
return true;
}
private OnClickListener onClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.screen_media_camera_photo_button:
startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE), REQUEST_IMAGE_CAPTURE);
break;
case R.id.screen_media_camera_video_button:
startActivityForResult(new Intent(MediaStore.ACTION_VIDEO_CAPTURE), REQUEST_VIDEO_CAPTURE);
break;
}
}
};
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE) {
switch (resultCode) {
case RESULT_OK:
Log.v(TAG, "Picture taken! :)");
if (data != null) {
Bitmap bitmap = data.getParcelableExtra("data");
mPhotoImageView.setImageBitmap(bitmap);
}
break;
case RESULT_CANCELED:
Log.v(TAG, "Picture canceled! :(");
break;
}
} else if (requestCode == REQUEST_VIDEO_CAPTURE) {
switch (resultCode) {
case RESULT_OK:
Log.v(TAG, "Video taken! :)");
break;
case RESULT_CANCELED:
Log.v(TAG, "Video canceled! :(");
break;
}
}
}
}
Xml layout file
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MediaActivity" >
<Button
android:id="#+id/screen_media_camera_photo_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="32dp"
android:text="Camera photo" />
<Button
android:id="#+id/screen_media_camera_video_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/screen_media_camera_photo_button"
android:layout_centerHorizontal="true"
android:layout_marginTop="28dp"
android:text="Camera video" />
<ImageView
android:id="#+id/screen_media_photo_imageview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/screen_media_camera_video_button"
android:layout_centerHorizontal="true"
android:layout_marginLeft="32dp"
android:layout_marginTop="57dp"
android:src="#drawable/ic_bitmap" />
</RelativeLayout>
Try the following code :
package com.example.sample1;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import android.os.Bundle;
import android.os.Environment;
import android.os.StatFs;
import android.provider.MediaStore;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class CapturePhotoSample1 extends Activity implements OnClickListener
{
public static final int TAKE_PHOTO=1;
ImageView imageView=null;
private File folder;
String imageFileName=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_capture_photo_sample1);
Button button=(Button)this.findViewById(R.id.capture_button);
button.setOnClickListener(this);
button=null;
imageView=(ImageView)this.findViewById(R.id.image_view1);
folder = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES)+ "/sample1/");
if (!folder.exists()) {
folder.mkdir();
}
}
private void dispatchTakePictureIntent(int actionCode) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePictureIntent,actionCode);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int id=v.getId();
if(id==R.id.capture_button)
this.dispatchTakePictureIntent(TAKE_PHOTO);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu1, menu);
return true;
}
public void handleCameraPhoto(Intent intent)
{
Bundle extras=intent.getExtras();
Bitmap bitmap=(Bitmap)extras.get("data");
this.imageView.setImageBitmap(bitmap);
if(this.isExternalStorageAvailable())
{
this.imageFileName="img_"+SDUtil.now(-1)+".png";
/*SDUtil.now() is our own library.It is for creating file name with respect to data and time.IF u copy the hole program means sdutil shows error.For that you write a logic for creating a file name. */
String path=folder+"/"+this.imageFileName;
FileOutputStream fos=null;
BufferedOutputStream bos=null;
try
{
fos=new FileOutputStream(path);
bos=new BufferedOutputStream(fos);
bitmap.compress(Bitmap.CompressFormat.PNG, 40, bos);
}
catch(Exception ex)
{
ex.printStackTrace();
}
if(bos!=null)
{
try
{
bos.flush();
//bos.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
if(bos!=null)
{
try
{
bos.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
if(fos!=null)
{
try
{
fos.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
bos=null;
fos=null;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(resultCode==Activity.RESULT_OK)
{
if(requestCode==TAKE_PHOTO)
{
handleCameraPhoto(data);
}
}
}
private boolean isExternalStorageAvailable() {
StatFs stat = new StatFs(Environment.getExternalStorageDirectory()
.getPath());
double sdAvailSize = (double) stat.getAvailableBlocks()
* (double) stat.getBlockSize();
// One binary gigabyte equals 1,073,741,824 bytes.
double mbAvailable = sdAvailSize / 1048576;
String state = Environment.getExternalStorageState();
boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// We can only read the media
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
// Something else is wrong. It may be one of many other states, but
// all we need
// to know is we can neither read nor write
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
if (mExternalStorageAvailable == true
&& mExternalStorageWriteable == true && mbAvailable > 10) {
return true;
} else {
return false;
}
}
}
make sure to add permissions
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
if that doesn't fix youre problem than u should show us youre code
check below code in your activity
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
//Check that request code matches ours:
if (requestCode == CAPTURE_IMAGE_THUMBNAIL_ACTIVITY_REQUEST_CODE)
{ //Check if your application folder exists in the external storage, if not create it:
your code should be here.....
//Check if data in not null and extract the Bitmap:
if (data != null)
{
String filename = "image";
String fileNameExtension = ".jpg";
File sdCard = Environment.getExternalStorageDirectory();
String imageStorageFolder = File.separator+"Your application Folder"+File.separator;
File destinationFile = new File(sdCard, imageStorageFolder + filename + fileNameExtension);
Log.d(TAG, "the destination for image file is: " + destinationFile );
if (data.getExtras() != null)
{
Bitmap bitmap = (Bitmap)data.getExtras().get("data");
try
{
FileOutputStream out = new FileOutputStream(destinationFile);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
}
catch (Exception e)
{
Log.e(TAG, "ERROR:" + e.toString());
}
}}}
The steps are:
1. So First of all as before we need to create a static int that will be our
public static final int CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE = 1777;
2. Next we fire intent to start Activity for result:
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "image.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent, CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE);
Here we are actually passing an URI as an extra to the intent in order to save the image at this location when it will be taken.
3. Finally we will receive the result in onActivityResult:
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
//Check that request code matches ours:
if (requestCode == CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE)
{
//Get our saved file into a bitmap object:
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "image.jpg");
Bitmap bitmap = decodeSampledBitmapFromFile(file.getAbsolutePath(), 1000, 700);
}
}
When decodeSampledBitmapFromFile method is:
public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight)
{ // BEST QUALITY MATCH
//First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize, Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
options.inPreferredConfig = Bitmap.Config.RGB_565;
int inSampleSize = 1;
if (height > reqHeight)
{
inSampleSize = Math.round((float)height / (float)reqHeight);
}
int expectedWidth = width / inSampleSize;
if (expectedWidth > reqWidth)
{
//if(Math.round((float)width / (float)reqWidth) > inSampleSize) // If bigger SampSize..
inSampleSize = Math.round((float)width / (float)reqWidth);
}
options.inSampleSize = inSampleSize;
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
don't forget to add the relevent camera permissions to the manifest file:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
Related
The preview is showing but when I click zoom in or out nothing happens. Here is the code
This is the xml for the main activity
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="#+id/activity_main"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:onClick="captureImage"
android:text="Capture" />
<Button
android:id="#+id/button2"
android:layout_alignTop="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_marginEnd="5dp"
android:text="Gallery" />
<FrameLayout
android:id="#+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="686dp">
</FrameLayout>
<ZoomControls
android:id="#+id/zoomControls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="104dp"
android:layout_marginBottom="-4dp" />
</RelativeLayout>
This is the code in java for the MainActivity
MainActivity.java
package com.example.mycustomcamera;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends AppCompatActivity
{
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
String currentPhotoPath = null;
private static final String TAG = "MainActivity";
Camera camera;
FrameLayout frameLayout;
ShowCamera showCamera;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
frameLayout = (FrameLayout)findViewById(R.id.frameLayout);
Button button = (Button)findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
camera.takePicture(null, null, mPictureCallBack);
}
});
//open the camera
camera = camera.open();
showCamera = new ShowCamera(this,camera);
frameLayout.addView(showCamera);
}
Camera.PictureCallback mPictureCallBack = new Camera.PictureCallback()
{
#Override
public void onPictureTaken(byte[] data, Camera camera)
{
File picture_file = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if(picture_file == null)
{
Log.d(TAG, "Error creating media file, check storage permissions");
return;
}
else
{
try
{
FileOutputStream fos = new FileOutputStream(picture_file);
fos.write(data);
fos.close();
//sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
//camera.startPreview();
//galleryAddPic();
}
catch (FileNotFoundException e)
{
Log.d(TAG, "File not found: " + e.getMessage());
}
catch (IOException e)
{
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
camera.startPreview();
//camera.stopPreview();
//camera.release();
}
}
};
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCustomCamera");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCustomCamera", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
private void galleryAddPic()
{
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(currentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
}
This is the code in java for the camera preview
ShowCamera.java
package com.example.mycustomcamera;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.ZoomControls;
import java.io.IOException;
import java.util.List;
public class ShowCamera extends SurfaceView implements
SurfaceHolder.Callback
{
private static final String TAG = " => Main Activity: ";
private SurfaceHolder holder;
private Camera mcamera;
private Context mContext;
int currentZoomLevel = 0;
int maxZoomLevel = 0;
ZoomControls zoomControls;
public ShowCamera(Context context, Camera camera)
{
super(context);
mContext = context;
this.mcamera = camera;
holder = getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceCreated(SurfaceHolder holder)
{
if(mcamera == null) return;
try
{
mcamera.setDisplayOrientation(90);
mcamera.setPreviewDisplay(holder);
mcamera.startPreview();
}
catch (IOException e)
{
Log.d(TAG, "Blad wlaczania podgladu kamery: " + e.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (holder.getSurface() == null) {
return;
}
try {
mcamera.stopPreview();
} catch (Exception e) {
}
Camera.Parameters params = mcamera.getParameters();
List<Camera.Size> sizes = params.getSupportedPreviewSizes();
Camera.Size optionalSize = getBestPreviewSize(width, height);
params.setPreviewSize(optionalSize.width, optionalSize.height);
mcamera.setParameters(params);
Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
switch (display.getRotation()) {
case Surface.ROTATION_0:
mcamera.setDisplayOrientation(90);
break;
case Surface.ROTATION_90:
mcamera.setDisplayOrientation(0);
break;
case Surface.ROTATION_180:
mcamera.setDisplayOrientation(270);
break;
case Surface.ROTATION_270:
mcamera.setDisplayOrientation(180);
break;
}
try {
mcamera.setParameters(params);
mcamera.setPreviewDisplay(holder);
mcamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Blad wlaczania podgladu kamery" + e.getStackTrace());
}
ZoomControls zoomControls = (ZoomControls) findViewById(R.id.zoomControls);
if (params.isZoomSupported()) {
maxZoomLevel = params.getMaxZoom();
try {
zoomControls.setIsZoomInEnabled(true);
zoomControls.setIsZoomOutEnabled(true);
zoomControls.setOnZoomInClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (currentZoomLevel < 500) {
currentZoomLevel++;
mcamera.startSmoothZoom(currentZoomLevel);
}
}
});
zoomControls.setOnZoomOutClickListener(new OnClickListener() {
public void onClick(View v) {
if (currentZoomLevel > 0) {
currentZoomLevel--;
mcamera.startSmoothZoom(currentZoomLevel);
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
} else {
zoomControls.hide();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
mcamera.release();
mcamera = null;
}
private Camera.Size getBestPreviewSize(int width, int height) {
Camera.Size result = null;
Camera.Parameters p = mcamera.getParameters();
for (Camera.Size size : p.getSupportedPreviewSizes()) {
if (size.width <= width && size.height <= height) {
if (result == null) {
result = size;
} else {
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea > resultArea) {
result = size;
}
}
}
}
return result;
}
}
This is the manifest
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mycustomcamera">
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.MyCustomCamera">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/paths"></meta-data>
</provider>
</application>
</manifest>
I m trying to make a web view app of a web page where user can upload a file (image) to a form and submit.
however, the web app works just fine, but couldn't able to select any file through input type="file" field and submit.
I did gone through other stack queries over this issues like but unfortunately I still need help on this particular issue.
My code goes as :
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.TargetApi;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import android.os.Handler;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_SELECT_FILE = 100;
private ValueCallback<Uri> mUploadMessage;
private ValueCallback<Uri[]> uploadMessage;
private WebView webView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webviewid);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("website url");
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.getSettings().setDomStorageEnabled(true);
webView.setWebChromeClient(new WebChromeClient() {
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public boolean onShowFileChooser(WebView mWebView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
if (uploadMessage != null) {
uploadMessage.onReceiveValue(null);
uploadMessage = null;
}
uploadMessage = filePathCallback;
Intent intent = fileChooserParams.createIntent();
try {
startActivityForResult(intent, REQUEST_SELECT_FILE);
} catch (ActivityNotFoundException e) {
uploadMessage = null;
Toast.makeText(getApplicationContext(), "Cannot Open File Chooser", Toast.LENGTH_LONG).show();
return false;
}
return true;
}
});
}
private boolean doubleBackToExitPressedOnce = false;
#Override
protected void onResume() {
super.onResume();
// .... other stuff in my onResume ....
this.doubleBackToExitPressedOnce = false;
}
#Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
if(webView.canGoBack()){
webView.goBack();
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Press again to exit", Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
}
}
The file can't be uploaded since its not returning with file path in the input field upon selecting.
Any help is greatly appreciated..
So, after hours of articles in androdi studio.. i finally found the solution.
Hope this helps some one like me.,
AndoridManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.suman.demo">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.Java
package com.package.name;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
private final static int FCR = 1;
WebView webView;
private String mCM;
private ValueCallback<Uri> mUM;
private ValueCallback<Uri[]> mUMA;
private ValueCallback<Uri> mUploadMessage;
private Uri mCapturedImageURI = null;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
private static final int INPUT_FILE_REQUEST_CODE = 1;
private static final int FILECHOOSER_RESULTCODE = 1;
private static final String TAG = MainActivity.class.getSimpleName();
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
Uri[] results = null;
// Check that the response is a good one
if (resultCode == Activity.RESULT_OK) {
if (data == null) {
// If there is not data, then we may have taken a photo
if (mCameraPhotoPath != null) {
results = new Uri[]{Uri.parse(mCameraPhotoPath)};
}
} else {
String dataString = data.getDataString();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
} else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
if (requestCode != FILECHOOSER_RESULTCODE || mUploadMessage == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == this.mUploadMessage) {
return;
}
Uri result = null;
try {
if (resultCode != RESULT_OK) {
result = null;
} else {
// retrieve from the private variable if the intent is null
result = data == null ? mCapturedImageURI : data.getData();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "activity :" + e,
Toast.LENGTH_LONG).show();
}
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
return;
}
#SuppressLint({"SetJavaScriptEnabled", "WrongViewCast"})
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webview_sample);
if (Build.VERSION.SDK_INT >= 23 && (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, 1);
}
assert webView != null;
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccess(true);
webView.getSettings().setSupportZoom(true);
webView.getSettings().setBuiltInZoomControls(true);
if (Build.VERSION.SDK_INT >= 21) {
webSettings.setMixedContentMode(0);
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
} else if (Build.VERSION.SDK_INT >= 19) {
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
} else if (Build.VERSION.SDK_INT < 19) {
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
webView.setWebViewClient(new Callback());
webView.loadUrl("website name goes here");
webView.setWebChromeClient(new WebChromeClient() {
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File imageFile = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
return imageFile;
}
public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
// Double check that we don't have any existing callbacks
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePath;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
// Error occurred while creating the File
Log.e(TAG, "Unable to create Image File", ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[]{takePictureIntent};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
return true;
}
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
mUploadMessage = uploadMsg;
// Create AndroidExampleFolder at sdcard
// Create AndroidExampleFolder at sdcard
File imageStorageDir = new File(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)
, "AndroidExampleFolder");
if (!imageStorageDir.exists()) {
// Create AndroidExampleFolder at sdcard
imageStorageDir.mkdirs();
}
// Create camera captured image file path and name
File file = new File(
imageStorageDir + File.separator + "IMG_"
+ String.valueOf(System.currentTimeMillis())
+ ".jpg");
mCapturedImageURI = Uri.fromFile(file);
// Camera capture image intent
final Intent captureIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
// Create file chooser intent
Intent chooserIntent = Intent.createChooser(i, "Image Chooser");
// Set camera intent to file chooser
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS
, new Parcelable[] { captureIntent });
// On select image call onActivityResult method of activity
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg,
String acceptType,
String capture) {
openFileChooser(uploadMsg, acceptType);
}
});
}
public class Callback extends WebViewClient {
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Toast.makeText(getApplicationContext(), "Failed loading app!", Toast.LENGTH_SHORT).show();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater myMenuInflater = getMenuInflater();
myMenuInflater.inflate(R.menu.super_menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.myMenuOne:
onBackPressed();
break;
case R.id.myMenuTwo:
GoForward();
break;
}
return true;
}
private void GoForward() {
if (webView.canGoForward()) {
webView.goForward();
} else {
Toast.makeText(this, "Can't go further!", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onBackPressed() {
if (webView.canGoBack()) {
webView.goBack();
}
}
}
Super_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.filechooser.file.MainActivity">
<item
android:id="#+id/myMenuOne"
android:icon="#drawable/ic_arrow_back_black_24dp"
android:title="Item"
app:showAsAction="always" />
<item
android:id="#+id/myMenuTwo"
android:icon="#drawable/ic_arrow_forward_black_24dp"
android:title="Item"
app:showAsAction="always" />
</menu>
Thanks to those who took the time on checking my query.
Happy to Help.
So as stated in the headline,
given: two Bitmaps
wanted: one Bitmap with both images mixed together.
Is there a way to do this on android? I've thought about converting both maps to bufferedImages and then overlapping and transforming back to Bitmap but that doesn't seem to work on android. I'm still fairly new to all this.
Basically the bitmaps that are saved at currentImagePath1 and currentImagePath2. Here's the java code:
package com.example.cameraexample;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.ImageView;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
String currentImagePath1 = null;
String currentImagePath2 = null;
ImageView imageView;
int pic = 1;
private static final int IMAGE_REQUEST = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void captureImage1(View view) {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if(cameraIntent.resolveActivity(getPackageManager()) != null){
File imageFile = null;
try {
imageFile = getImageFile1();
}
catch (IOException e) {
e.printStackTrace();
}
if(imageFile != null) {
Uri imageUri = FileProvider.getUriForFile(this, "com.example.android.fileprovider", imageFile);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(cameraIntent, IMAGE_REQUEST);
}
}
}
public void captureImage2(View view) {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if(cameraIntent.resolveActivity(getPackageManager()) != null){
File imageFile = null;
try {
imageFile = getImageFile2();
}
catch (IOException e) {
e.printStackTrace();
}
if(imageFile != null) {
Uri imageUri = FileProvider.getUriForFile(this, "com.example.android.fileprovider", imageFile);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(cameraIntent, IMAGE_REQUEST);
}
}
}
/*public void displayImageBackup(View view) {
Intent intent = new Intent(this, DisplayImage.class);
intent.putExtra("image_path", currentImagePath);
startActivity(intent);
}*/
public void displayImage1(View view) {
showImage(currentImagePath1);
}
public void displayImage2(View view) {
showImage(currentImagePath2);
}
private File getImageFile1() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
String imageName = "1_jps_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File imageFile = File.createTempFile(imageName, ".jpg", storageDir);
currentImagePath1 = imageFile.getAbsolutePath();
return imageFile;
}
private File getImageFile2() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
String imageName = "2_jps_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File imageFile = File.createTempFile(imageName, ".jpg", storageDir);
currentImagePath2 = imageFile.getAbsolutePath();
return imageFile;
}
public void showImage(String image_path) {
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.mimageView);
Bitmap bitmap = BitmapFactory.decodeFile(image_path);
imageView.setImageBitmap(bitmap);
}
public void overlay(View view) {
}
public void switch_images(View view) {
if(pic == 1) displayImage2(view);
if(pic == 2) displayImage1(view);
if(pic == 1) pic = 2;
else pic = 1;
}
}
Testing didn't really show any helpful results for me unfortunately.
How about creating two ImageView that overlap each other by putting them in a FrameLayout. Then set 50% alpha value to the top image like so:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="#drawable/a"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:alpha="0.5"
android:src="#drawable/b"/>
</FrameLayout>
Thank you very much to user1506104 for pointing out a solution to my problem. Sorry for the late reply, I had a few things going on in my life that couldn't wait.
I can just put two ImageViews ontop of each other. :)
It worked like the follogwing: To overlay i made another method like the showImage just that the ImageView it projected the bitmap to had an alpha of 0.5. The mistake was that I had to delete this line: setContentView(R.layout.activity_main);
i'll be simply generate video recorder application using Camera. but it's crash and give me a bellow error :
Attempt to invoke virtual method
'android.view.SurfaceHolderandroid.view.SurfaceView.getHolder()' on a
null object reference`
Capture Video Activity.class
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
import android.hardware.camera2.CameraCharacteristics;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ToggleButton;
import static android.provider.MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE;
import static android.provider.MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO;
public class CaptureVideoActivity extends Activity implements SurfaceHolder.Callback {
private MediaRecorder mMediaRecorder;
private Camera mCamera;
private SurfaceView mSurfaceView;
private SurfaceHolder mHolder;
private View mToggleButton;
private boolean mInitSuccesful;
CameraCharacteristics characteristics;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_capture_video);
// we shall take the video in landscape orientation
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mToggleButton = (ToggleButton) findViewById(R.id.toggleRecordingButton);
mToggleButton.setOnClickListener(new View.OnClickListener() {
#Override
// toggle video recording
public void onClick(View v) {
if (((ToggleButton) v).isChecked()) {
mMediaRecorder.start();
try {
Thread.sleep(7 * 1000); // This will recode for 10 seconds, if you don't want then just remove it.
} catch (Exception e) {
e.printStackTrace();
}
//finish();
} else {
mMediaRecorder.stop();
mMediaRecorder.reset();
try {
initRecorder(mHolder.getSurface());
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
/* Init the MediaRecorder, the order the methods are called is vital to
* its correct functioning */
private void initRecorder(Surface surface) throws IOException {
// It is very important to unlock the camera before doing setCamera
// or it will results in a black preview
if (mCamera == null) {
mCamera = Camera.open();
mCamera.unlock();
}
if (mMediaRecorder == null) mMediaRecorder = new MediaRecorder();
mMediaRecorder.setPreviewDisplay(surface);
mMediaRecorder.setCamera(mCamera);
File file = getOutputMediaFile(2);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
// mMediaRecorder.setOutputFormat(8);
// mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setOutputFile(file.getAbsolutePath());
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_720P));
/*mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setVideoEncodingBitRate(512 * 1000);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(640, 480);*/
int deviceorientation = getResources().getConfiguration().orientation;
mMediaRecorder.setOrientationHint(getJpegOrientation(characteristics, deviceorientation));
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
// This is thrown if the previous calls are not called with the
// proper order
e.printStackTrace();
}
mInitSuccesful = true;
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
if (!mInitSuccesful)
initRecorder(mHolder.getSurface());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
shutdown();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
private void shutdown() {
// Release MediaRecorder and especially the Camera as it's a shared
// object that can be used by other applications
mMediaRecorder.reset();
mMediaRecorder.release();
mCamera.release();
// once the objects have been released they can't be reused
mMediaRecorder = null;
mCamera = null;
}
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "Test Capture");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
private int getJpegOrientation(CameraCharacteristics c, int deviceOrientation) {
if (deviceOrientation == android.view.OrientationEventListener.ORIENTATION_UNKNOWN)
return 0;
int sensorOrientation = c.get(CameraCharacteristics.SENSOR_ORIENTATION);
// Round device orientation to a multiple of 90
deviceOrientation = (deviceOrientation + 45) / 90 * 90;
// Reverse device orientation for front-facing cameras
boolean facingFront = c.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT;
if (facingFront) deviceOrientation = -deviceOrientation;
// Calculate desired JPEG orientation relative to camera orientation to make
// the image upright relative to the device orientation
return (sensorOrientation + deviceOrientation + 360) % 360;
}
}
activity_capture_video.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ToggleButton
android:id="#+id/toggleRecordingButton"
android:layout_width="fill_parent"
android:textOff="Start Recording"
android:textOn="Stop Recording"
android:layout_height="wrap_content"
/>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<SurfaceView android:id="#+id/surfaceView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"></SurfaceView>
</FrameLayout>
</LinearLayout>
i have already read all the link details :
How to solve "android.view.SurfaceView.getHolder()' on a null object reference"?
'android.view.SurfaceHolder android.view.SurfaceView.getHolder()' on a null object reference in SurfaceView
surfaceView.getHolder not returning SurfaceHolder
but not useful for me.
I guess you were following some tutorial video or website. If not please do it now.
Check the following things.
Check the import statements for all mainly surfaceview, surfaceholder and camera.
Check the elements in xml.
Check whether the xml is linked to java by ctrl+click on R.id.surfaceView
I have a custom camera application , everything works fine .But whenever the app gets paused (when the onPause or onDestroyed is called) camera is released and afterwards when onResume is called and capture button is clicked is to take an image ,my Application crashes.How do i fix this ? Please help me , Thanks in advance
CameraActivity Code
package com.example.skmishra.plates.Activities;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.SensorManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.MotionEvent;
import android.view.OrientationEventListener;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ZoomControls;
import com.example.skmishra.plates.Asyncs.CameraAsync;
import com.example.skmishra.plates.CameraHandler;
import com.example.skmishra.plates.Library.Fonts;
import com.example.skmishra.plates.R;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* Created by skmishra on 12/28/2015.
*/
public class camera extends Activity {
private static final int RESULT_LOAD_IMAGE = 200 ;
private Camera mCamera=null;
private CameraHandler surface_view;
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
public static final String TAG = "Aloo";
int toRotate = 90;
public int currentCameraID = 0;
OrientationEventListener myOrientationEventListener;
private ZoomControls zoomControls;
private double mDist;
Boolean imageSwitchClicked = false;
Boolean mShowFlash = false;
ImageView mSwitch_cam;
ImageView mFlashBut;
FrameLayout preview;
CameraAsync mCamAsync;
ImageView imageGallery;
TextView raleway;
TextView headerCameraText;
Fonts mFonts;
int permCode=4;
Camera.Parameters params;
String recievedType=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.e("I Called Thus "," cda");
mCamAsync=new CameraAsync(this);
mCamAsync.execute();
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
imageGallery = (ImageView) findViewById(R.id.select_gallery);
mFonts = new Fonts();
preview = (FrameLayout) findViewById(R.id.camera_preview);
mFlashBut = (ImageView) findViewById(R.id.flash);
mSwitch_cam = (ImageView) findViewById(R.id.white_switch);
raleway = (TextView) findViewById(R.id.textView2);
headerCameraText = (TextView) findViewById(R.id.imageHead);
// mFonts.setRalewayBold(this, headerCameraText);
Intent gets = getIntent();
recievedType = gets.getExtras().getString("recievedCameraPurpose");
handleHeaderText(recievedType);
mFonts.setRalewayBold(this, raleway);
myOrientationEventListener
= new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {
#Override
public void onOrientationChanged(int arg0) {
int rotation = arg0;
if (rotation > 340) {
if (currentCameraID == 0) {
toRotate = 90;
} else {
toRotate =270;
Log.e("POSITION_TITLT", "-> Potrait Front camera");
}
} else if (rotation < 80 && rotation > 30) {
toRotate = 180;
Log.e("POSITION_TILT", "-> Landscape Right " + rotation);
} else if (rotation < 280 && rotation > 240) {
toRotate = 0;
Log.e("POSITION_TILT", "-> Landscape Left " + rotation);
}
}
};
if (myOrientationEventListener.canDetectOrientation()) {
myOrientationEventListener.enable();
} else {
Toast.makeText(this, "Can't DetectOrientation", Toast.LENGTH_LONG).show();
finish();
}
}
private boolean checkifCamera(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
return true;
} else {
return false;
}
}
public Camera getCameraInstance() {
Camera c = null;
try {
releaseCameraAndPreview();
c = Camera.open();
} catch (Exception e) {
Toast.makeText(this, "Print error" + e.getMessage(), Toast.LENGTH_LONG).show();
}
return c;
}
public void onCompleteInstanceCameraAysnc(Camera camera)
{
mCamera = camera;
surface_view = new CameraHandler(this, mCamera);
params = mCamera.getParameters();
preview.addView(surface_view);
set_image_gallery();
}
public void switchC(View view) {
if (!imageSwitchClicked) {
mSwitch_cam.setAlpha(1.0f);
imageSwitchClicked = true;
} else {
mSwitch_cam.setAlpha(0.5f);
imageSwitchClicked = false;
}
setCameraID();
mCamera = surface_view.switchCamera();
params=mCamera.getParameters();
}
public void flash_onOf(View view) {
if (!mShowFlash) {
params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
mFlashBut.setAlpha(1.0f);
mShowFlash = true;
} else {
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
mFlashBut.setAlpha(0.5f);
mShowFlash = false;
}
}
private void releaseCameraAndPreview() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.lock();
mCamera.release();
mCamera=null;
}
else
{
Log.e("Cert","Lerts");
}
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onDestroy() {
Log.e("LLL", "Dessssdccc");
super.onDestroy();
try {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.lock();
myOrientationEventListener.disable();
mCamera.release();
mCamera=null;
permCode=15;
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onPause() {
Log.e("LLL", "Dessssdccc");
super.onPause();
try {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.lock();
myOrientationEventListener.disable();
mCamera.release();
mCamera=null;
permCode=15;
} catch (Exception e) {
e.printStackTrace();
}
}
public void takePH(View view) {
if(mShowFlash && !imageSwitchClicked)
{
params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
}
params.set("rotation", toRotate);
mCamera.setParameters(params);
mCamera.takePicture(null, null, mPicture);
}
Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null) {
Log.d(TAG, "Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
Intent i=new Intent(getApplicationContext(),ShowOut.class);
i.putExtra("purpose",recievedType);
i.putExtra("img-url",pictureFile.toString());
startActivity(i);
}
};
/**
* Create a file Uri for saving an image or video
*/
private static Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
/**
* Create a File for saving an image or video
*/
private static File getOutputMediaFile(int type) {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "Plates");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_" + timeStamp + ".jpg");
} else if (type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_" + timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
public void handleHeaderText(String type) {
Log.e("Type",type);
headerCameraText.setText("");
if (type.equals("ADD_COVER_PLATES")) {
headerCameraText.setText("Take a cover image for your plate");
}
else if(type.equals("ADD_PROFILE_USER"))
{
imageGallery.setVisibility(View.GONE);
}
else if(type.equals("PLATE_UPLOAD_SINGLETON")) {
headerCameraText.setText("Click an image for a plate");
}
}
public void setCameraID() {
if (currentCameraID == Camera.CameraInfo.CAMERA_FACING_BACK) {
currentCameraID = Camera.CameraInfo.CAMERA_FACING_FRONT;
toRotate = 270;
} else {
currentCameraID = Camera.CameraInfo.CAMERA_FACING_BACK;
toRotate = 90;
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// Get the pointer ID
Camera.Parameters params = mCamera.getParameters();
int action = event.getAction();
if (event.getPointerCount() > 1) {
// handle multi-touch events
if (action == MotionEvent.ACTION_POINTER_DOWN) {
mDist = getFingerSpacing(event);
} else if (action == MotionEvent.ACTION_MOVE && params.isZoomSupported()) {
mCamera.cancelAutoFocus();
handleZoom(event, params);
}
} else {
// handle single touch events
if (action == MotionEvent.ACTION_UP) {
handleFocus(event, params);
}
}
return true;
}
private void handleZoom(MotionEvent event, Camera.Parameters params) {
int maxZoom = params.getMaxZoom();
int zoom = params.getZoom();
double newDist = getFingerSpacing(event);
if (newDist > mDist) {
//zoom in
if (zoom < maxZoom)
zoom++;
} else if (newDist < mDist) {
//zoom out
if (zoom > 0)
zoom--;
}
mDist = newDist;
params.setZoom(zoom);
mCamera.setParameters(params);
}
public void handleFocus(MotionEvent event, Camera.Parameters params) {
int pointerId = event.getPointerId(0);
int pointerIndex = event.findPointerIndex(pointerId);
// Get the pointer's current position
float x = event.getX(pointerIndex);
float y = event.getY(pointerIndex);
List<String> supportedFocusModes = params.getSupportedFocusModes();
if (supportedFocusModes != null && supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
mCamera.autoFocus(new Camera.AutoFocusCallback() {
#Override
public void onAutoFocus(boolean b, Camera camera) {
// currently set to auto-focus on single touch
}
});
}
}
/**
* Determine the space between the first two fingers
*/
private double getFingerSpacing(MotionEvent event) {
// ...
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
double pres;
pres = Math.sqrt(x * x + y * y);
return pres;
}
public void set_image_gallery() {
// Find the last picture
String[] projection = new String[]{
MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATA,
MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
MediaStore.Images.ImageColumns.DATE_TAKEN,
MediaStore.Images.ImageColumns.MIME_TYPE
};
final Cursor cursor = getContentResolver()
.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null,
null,MediaStore.Images.ImageColumns._ID + " DESC");
// Put it in the image view
if (cursor.moveToFirst()) {
String imageLocation = cursor.getString(1);
File imageFile = new File(imageLocation);
if (imageFile.exists()) { // TODO: is there a better way to do this?
Bitmap bm=decodeFile(imageFile);
imageGallery.setImageBitmap(bm);
}
}
cursor.close();
}
public Bitmap decodeFile(File f) {
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
//The new size we want to scale to
final int REQUIRED_SIZE = 490;
//Find the correct scale value. It should be the power of 2.
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_SIZE && o.outHeight / scale / 2 >= REQUIRED_SIZE)
scale *= 2;
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {
}
return null;
}
public void imagePick(View view)
{
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, RESULT_LOAD_IMAGE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
Intent transfer=null;
if(recievedType.equals("ADD_COVER_PLATES")) {
transfer = new Intent(this, create_plates.class);
}
else if(recievedType.equals("PLATE_UPLOAD_SINGLETON"))
{
transfer=new Intent(this,plate_select_upload.class);
}
transfer.putExtra("imagUrl",picturePath);
startActivity(transfer);
}
}
}
Camera Handler Code
package com.example.skmishra.plates;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
/**
* Created by skmishra on 12/28/2015.
*/
public class CameraHandler extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera=null;
public int currentCameraID=0;
public CameraHandler(Context context,Camera camera) {
super(context);
mCamera=camera;
mHolder=getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
if(mCamera==null)
{
mCamera=Camera.open();
}
mCamera.setPreviewDisplay(holder);
Camera.Parameters p = mCamera.getParameters();
}
catch (IOException e)
{
Log.d("--DS", "Error setting camera preview: " + e.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
fixOr();
if(mHolder.getSurface()==null)
{
return;
}
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d("--DS", "Error starting camera preview: " + e.getMessage());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
mCamera.release();
mCamera = null;
}
public void fixOr()
{
mCamera.stopPreview();
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
}
public Camera switchCamera() {
mCamera.stopPreview();
mCamera.release();
if(currentCameraID==Camera.CameraInfo.CAMERA_FACING_BACK)
{
currentCameraID = Camera.CameraInfo.CAMERA_FACING_FRONT;
}
else
{
currentCameraID=Camera.CameraInfo.CAMERA_FACING_BACK;
}
mCamera=Camera.open(currentCameraID);
fixOr();
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
return mCamera;
}
}
UPDATE **
StackTrace
Process: com.example.skmishra.plates, PID: 10575
java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.<init>(Camera.java:545)
at android.hardware.Camera.open(Camera.java:403)
at com.example.skmishra.plates.CameraHandler.surfaceCreated(CameraHandler.java:35)
at android.view.SurfaceView.updateWindow(SurfaceView.java:599)
at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:243)
at android.view.View.dispatchWindowVisibilityChanged(View.java:9034)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1275)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1275)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1275)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1275)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1275)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1319)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1062)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5873)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5753)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
After a lot of research , i finally found out what the problem was . Problem was with the FrameLayout , i had to remove it on Pause and recreate it on OnResume
#Override
protected void onResume() {
super.onResume();
mCamAsync = new CameraAsync(this);//Async task to get the camera instance
mCamAsync.execute();
}
#Override
protected void onPause() {
super.onPause();
releaseCameraAndPreview();
preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.removeViewAt(0);
}
** EDIT **
i also removed the execution of cameraAsync from onCreate , that means i instantiate the camera only in OnResume