I am trying to take a photo in my Android application using my PC's built-in webcam. I am using the eclipse Android emulator and have set the AVD to use webcam0 as the rear-facing camera, but when I run my program it always crashes, saying "Unfortunately, Camera has stopped". I have added the following line to my Manifest xml:
<uses-permission android:name="android.permission.CAMERA"/>
though it still does not seem to work. I have read in a few places that there's supposed to be a "Hardware" section in the AVD manager edit/create screen, but mine does not have it.
Am I missing something? Here is the logcat that appears when I try to run the app:
Any thoughts about what might be happening? I've searched for solutions all over the place and can't seem to find any that solve this exact problem. Thanks for the help.
EDIT
Here's my image capture button/method code:
/* Create capture button */
Button capture = (Button) findViewById(R.id.btnCapture);
capture.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//create directory/picture file
count++;
file = dir + count + ".jpg";
File picFile = new File(file);
try {
picFile.createNewFile();
} catch (IOException e) {}
Uri outputFileUri = Uri.fromFile(picFile);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, TAKE_PHOTO_CODE);
}
});
/* Check if valid photo */
#Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TAKE_PHOTO_CODE && resultCode == RESULT_OK) {
Log.d("CameraDemo", "Pic saved");
}
}
This code was mostly created based on a thread I found here on SO, I'm afraid I don't recall which one though.
Have you added:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
in your manifest?
If you feel that you have followed all the right procedures for activating your camera but fails, then as for my case, I had to try the in-built camera in the emulator to rule out any possibility that it is my codes. I realized that the same error was being produced by the default camera app - as you reported.
So, after several trials: (adding space, ram, more manifest files, clearing Google Play Services Data, updating Play Services, etc), I decided to use an Android Studio on Windows 10 x64 machine (the earlier one was Windows 7 x64). To my surprise, the error was gone and the camera did not crash. Now, I don't know if it has to do with OS (Win 7) or the Processor, or any other hardware or software issue. You can try this if you are not already using Windows 10.
Related
I am trying to develop a basic app usage monitor for Android. There's not much online help I could find bar one video here without just copying someone else's GitHub repo. I selected development with Android 10 (Q) as my SDK.
Essentially, since to my understanding in Lollipop and above you have to perform an Intent to get permissions, it should be as simple doing an intent to get Settings.ACTION_USAGE_ACCESS_SETTINGS which is what I would need to get an app's total time in foreground.
However, the app recognises it lacks permissions and takes the user to the system permissions page in the settings, but there is no option to actually give the app any settings. The app will complain about having no required permissions but I, as the user, have no ability to grant it any of those permissions on the emulated device.
The following is an extract of the start of my MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sharedPreferences = getSharedPreferences("Focus", MODE_PRIVATE);
if(!checkUsageStatsAllowedOrNot()) {
Intent usageAccessIntent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
usageAccessIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(usageAccessIntent);
if (checkUsageStatsAllowedOrNot()) {
startService(new Intent(MainActivity.this, BackgroundService.class));
}
else {
Toast.makeText(getApplicationContext(), "please give me access", Toast.LENGTH_SHORT).show();
}
This is the checkUsageStatsAllowedOrNot function:
public boolean checkUsageStatsAllowedOrNot() {
try {
PackageManager packageManager = getPackageManager();
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(getPackageName(), 0);
AppOpsManager appOpsManager = (AppOpsManager) getSystemService(APP_OPS_SERVICE);
int mode = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, applicationInfo.uid, applicationInfo.packageName);
return (mode==AppOpsManager.MODE_ALLOWED);
}
catch (Exception e) {
Toast.makeText(getApplicationContext(), "error cannot find any usage stats", Toast.LENGTH_SHORT).show();
return false;
}
}
As you can see from this image (ignore the crossed out one, that's not relevant), the only apps there are generic pre-installed ones when it opens the Usage permissions screen:
usage permissions opens but relevant developer app not there
Do you have any idea why this may be the case? I'm not sure if it's just because the video I followed is a bit old or most likely the fact that I only started using Android Studio 2 weeks and have barely a clue how this all works, but from my research this seems fine??
Any ideas will go a long way, thanks for reading.
Let's say I have a method inside my activity that looks like this:
private void dispatchTakeVideoIntent() {
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
if (takeVideoIntent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE);
}
}
Then if everything works out fine, I access the taken video by its URI:
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent intent) {
if (requestCode == REQUEST_VIDEO_CAPTURE && resultCode == Activity.RESULT_OK) {
Uri videoUri = intent.getData();
// process video
}
}
Where does the video actually reside at this point? Is it temporarily stored in memory or does it get saved to permanent storage?
If I want my app to reliably access that video at some later point, what's the best way to go about this? Do I have to copy the video to my app's storage folder(s)?
Where does the video actually reside at this point?
It will reside wherever the user's camera app elects to put it. There are hundreds of different camera apps, both pre-installed by manufacturers and user-installed from the Play Store or elsewhere.
Is it temporarily stored in memory or does it get saved to permanent storage?
That is up to the camera app.
If I want my app to reliably access that video at some later point, what's the best way to go about this?
You can try passing a content Uri value via EXTRA_OUTPUT as an extra on your Intent. You can use FileProvider to get that Uri, pointing to some file in a location that you control (e.g., getFilesDir() on Context). Most camera apps should honor this extra, but not all will.
Or, you could copy the video, as you suggest.
Or, you could use a camera library (e.g., FotoApparat, CameraKit-Android) and record the video within your own app.
So I have a Fragment that calls the following method which launches the camera:
private void launchCamera() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
And I expect to receive the picture data in this method in my fragment:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (!(resultCode == RESULT_OK)) return;
if (requestCode == REQUEST_IMAGE_CAPTURE || requestCode == REQUEST_GALLERY_IMAGE) {
Uri imageURI = data.getData();
// do something
}
}
However, after I take a picture and confirm it, the app goes to my launcher. After setting breakpoints in the onActivityResult method, the app never even reaches this method before crashing. I've granted made sure to grant all permissions in both the manifest and at runtime.
There are also no outputs to Logcat with this crash, both in the app logs and the device logs. I have also tested on both my device (Moto G5 Plus) & Pixel XL API 26 emulator; both have the same result.
I think you need to call super.onActivityResult().
The fragment is the one making the startActivityForResult() call, but the activity gets the first shot at handling the result so you need to implement super.onActivityResult() to make the fragment handle the result.
the app immediately crashes to my launcher
No, the camera app immediately brings up the launcher. Apparently, the developers of this camera app wrote it to bring up the home screen when the user is done taking the picture. This is a bug, of course, but there is little that you can do about it.
Use ACTION_IMAGE_CAPTURE when you would like a picture but do not mind if you do not get it, due to bugs in some of the hundreds of camera apps that you are integrating with. Otherwise, use a camera library (Fotoapparat, CameraKit-Android, etc.) to take the picture directly in your own app.
Also, and FWIW, ACTION_IMAGE_CAPTURE does not return a Uri, so your onActivityResult() code will not work anyway. Given your particular ACTION_IMAGE_CAPTURE Intent configuration, in onActivityResult(), data.getParcelableExtra("data") will return a Bitmap representing a thumbnail-sized image.
I believe this is yet another manifestation of the Android: Activity getting Destroyed after calling Camera Intent.
The bottom line is, the system restarts your app from scratch and your activity is created but has a chance to restore its state.
So you must implement onRestoreInstanceState(). I am not sure you can guarantee that the fragment will be ready to receive onActiviyResult() timely, so to be in the safe side, I prefer to handle the captured image in activity itself.
So this issue was actually because of an intent flag I had attached to the activity. My activity was started using the NO_HISTORY intent flag, which apparently prevented it from being recreated when returned from a startActivityForResult call.
I'm trying to use the camera to take pictures in my app, and then crop the taken images.
Everything is working for the recent versions for Android, but not for Android Kitkat 4.4.2.
the Camera returns a null URI.
get the URI onActivityReslult :
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_CODE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
picUri = data.getData();
Intent i = new Intent(PublierActivity.this, CropActivity.class);
i.putExtra("Uri", picUri);
startActivityForResult(i, CROP_CODE);
}
Here is how I call the camera intent :
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, CAMERA_CODE);
}
is there any way to make an exception for oldest versions for android to resolve this problem ?
From your code, it would appear that you are trying to use ACTION_IMAGE_CAPTURE. In that case, there should never be a Uri — data.getData() should always be returning null. If a camera app happens to return a Uri, that may be the image, but since ACTION_IMAGE_CAPTURE is not documented to return a Uri, you have no way of knowing what that Uri is for.
If you are using EXTRA_OUTPUT on the ACTION_IMAGE_CAPTURE Intent, you know where the image should be stored, because you told the camera app where to store it. Note that some camera apps are buggy and fail to honor EXTRA_OUTPUT, putting the image wherever they want.
If you are not using EXTRA_OUTPUT, then you will get a thumbnail back in the "data" extra.
Also, please bear in mind that this has nothing to do with Android OS version, and everything to do with the camera app that the user chooses to use. There are thousands of Android device models. These ship with dozens, if not hundreds, of different camera apps pre-installed. The user might also elect to install a third-party camera app. Any of those could be handling your request.
I want to have a way to trigger the camera on Google Glass right after I get in (e.g., "Ok Glass", "App", ) but I cannot find any similar examples online.
Any idea how to trigger this?
Also, currently when I try to create a new Android project it will be the default Hello World, is there a template for Google Glass?
On Ok glass you can write like -
String fileUri ="file:///mnt/sdcard/Pictures/" ;
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // file:///mnt/sdcard/Pictures/MyCameraApp/IMG_20130812_105617.jpg
startActivityForResult(intent, TAKE_PICTURE_REQUEST);
Then you have to call -
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TAKE_PICTURE_REQUEST && resultCode == RESULT_OK) {
String picturePath = data.getStringExtra(
CameraManager.EXTRA_PICTURE_FILE_PATH);
}
super.onActivityResult(requestCode, resultCode, data);
}
It will work.
If you want to launch the built-in camera application immediately at the beginning of your application, you can call startActivityForResult with an intent whose action is MediaStore.ACTION_IMAGE_CAPTURE inside your initial activity's onCreate method. (But note the differences between Android and Glass with respect to how the captured photo is returned; see the Glass Camera class Javadoc for more details.)
Eclipse and Android Studio do not currently have any special support to generate Glass projects out of the box.
You can use my sample Camera Snapshot on GitHub. It does exactly what you're asking.
Here it is:
https://github.com/dazza222/GlassCameraSnapshot