I want to build an app that keeps the front LED flash/torch on while taking a picture. So I have the following code that opens the camera using an implicit intent:
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(intent, requestImageCapture)
And the code for turning on and off the torch/flash of the phone:
if(isLightOn) {
val manager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
val cameraId = manager.cameraIdList[0]
manager.setTorchMode(cameraId, false)
isLightOn = false
} else {
val manager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
val cameraId = manager.cameraIdList[0]
manager.setTorchMode(cameraId, true)
isLightOn = true
}
I've set the listeners of 2 buttons to perform these actions. Though they work well on their own, the torch/flash does not stay on when the camera is opened with the intent. Is there any way by which I can achieve this behavior?
The code for the torch works, but it only works for your app. After the startActivityForResult(intent, requestImageCapture) is executed you are no longer in your app. You are in whatever camera app you select. Your app loses access to the camera and the Camera app gets it.
The flash now can be controlled for the Camera app. The camera app probably has controls for flash.
If you want to enable the flash and take a photo you'll have to create your own camera app. You can do it from scratch following this guide or you can use a camera library like Fotoapparat or material-camera
Related
I have to create an app, which detects user inactivity, and then start activity which displays some videos with WebView, and then when displaying with WebView is finished, it has to play videos from SDCard. I've already handled part with WebView and SDCard (with JavaScriptInterface etc.)
This application has to work with API 19 all the way to the newest one.
The question is - Is there a possibility to detect if user is inactive and start my application, or keep the app running in background, and then start activity in the foreground after the user becomes inactive for certain time?
I'm not trying to play ads, when user is not looking at his screen. Application is for my client, who have stores with all kind of electrical equipments, including smartphones. The goal is to play video presentations with hardware details specific for each smartphone (informations about processor, ram, camera, screen etc.).
In short: I have to make an app which is similar to "Demo Apps" created for example by Samsung (playing some kind of presentations on screen).
So far I've read and tested things like:
1) BroadcastReceiver with combination of ACTION_SCREEN_OFF / ACTION_SCREEN_ON events.
Receiver works properly, I can detect this event and then start activity, but... The screen is already off so i can't see the displayed activity - it's visible running in the foreground after unlocking the phone. Is there a way to unlock the phone when the event is received?
That's my code so far.
EventReceiver Class:
class EventReceiver: BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
StringBuilder().apply {
append("Action: ${intent.action}\n")
append("URI: ${intent.toUri(Intent.URI_INTENT_SCHEME)}\n")
toString().also { log ->
Log.d(TAG, log)
Toast.makeText(context, log, Toast.LENGTH_LONG).show()
}
}
if (intent.action == Intent.ACTION_SCREEN_OFF) {
val i = Intent(context, MainActivity::class.java)
context.startActivity(i)
}
}
}
MainActivity Class:
val br : BroadcastReceiver = EventReceiver()
val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION).apply {
addAction(Intent.ACTION_SCREEN_OFF)
addAction(Intent.ACTION_SCREEN_ON)
addAction(Intent.ACTION_BOOT_COMPLETED)
}
2) Foreground Services - I read that this is a great way to make some asyc stuff in the background and show notifications to user. Is there a way to start the activity with it?
3) Job Scheduler
4) Daydream / Dream Service - it actually works great with almost every API and manufacturer, but.. there's no way to set the app as Screen Saver on Huawei/Honor smartphones, at least from phone settings, I've read that this is possible with ADB etc. but this is not an option that I can use here.
It seems that none of these fullfill my expectations.
Im currently trying to activate the built in front flashlight on a Samsung Galaxy A6, but the device provides information like there is no built in front flash.
I've already tried different methods, which can be found by searching for activating flash.
First Try was to get supportedFlashModes and then activate the flash by using setParameters (API < 23). But simply the getParameters() for the front camera doesn't return any information of the built in front flash. For the app it just seems like there is no front flash available.
Then i tried to use the Camera2 API, introduced in API >= 23 and there the same Problem occurs. Fetching camera characteristics and then check if FLASH_INFO is available just results in returning false. Also trying to just activate the flash unit with setTorchMode(FRONT_CAMERA, true) throws an exception which says: No flash unit available.
I currently only have Samsung Galaxy A6 as test device with built in front flash. The same code works fine for the rear (back) camera without any problems.
ad 1)
try {
Camera camera;
camera = Camera.open(cameraId);
if (camera == null) {
return false;
}
Camera.Parameters parameters = camera.getParameters();
if (parameters.getFlashMode() == null) {
camera.release();
return false;
}
...
It just quits at that point because .getFlashMode() returns null for the front camera. Next steps would be to check the supportedFlashModes and then call setParamater of Camera.
ad 2)
try {
String camID = null;
for(String cameraID : mCameraManager.getCameraIdList()) {
CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics(cameraID);
int orientation = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
if (orientation == CameraCharacteristics.LENS_FACING_FRONT) {
if(cameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE)) {
camID = cameraID;
}
}
if(camID != null) {
mCameraManager.setTorchMode(camID, true);
}
} catch (Exception exc) {
...
}
These are only snippets for simply activating the front flash, but both methods act like the hardware response without a built in front flash.
After research it seems that some phone manufacturers are using private APIs to control hardware. Especially Samsung and Huawei are making use of that. The main camera app on a device is mainly controlled by that API and Frontflash can be used as expected. But even big camera apps like Instagram and Snapchat can't get rid of that and are also not able to activate e.g. Frontflash.
For own purposes the hardware just doesn't provide any features for activating Frontflash on some devices, it just reacts like there is no built-in frontflash. For now there are no solutions available for this problem.
Exisiting workarounds are doing a whitening of the screen to lighten up the environment in front of the phone.
I have a simple Flutter app that start a native background service using MethodChannel. This native background service notify my Flutter app using BasicMessageChannel<String> to display text when a particular native information is catched. All of this work perfectly when my app is in foreground. When an other app is in foreground, I can't see the text without having to switch to my app.
I want that my native service can display a particular Flutter screen even if an other application is running in foreground.
It can be perceived as not user friendly, but this is an message of utmost importance.
Any suggestion or solution will be welcome !
Note : Native service is for the moment only available in Java for Android, I'm working on C# for IOS side.
On Android you need to display a high priority notification. This displays the slide-down notification panel which will appear over the lock screen or another app. Since you are using native code already, you can create this notification there, or send a message to the Dart side (as you are doing, using MethodChannel) where it can use the flutter_local_notifications plugin to display it. When the user click the notification, your flutter app is brought to the foreground. In Java you might use code similar to this:
// Create an intent which triggers the fullscreen notification
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.setAction("SELECT_NOTIFICATION");
Class mainActivityClass = getMainActivityClass(context);
intent.setClass(context, mainActivityClass);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Build the notification as an ongoing high priority item to ensures it will show as
// a heads up notification which slides down over top of the current content.
final Notification.Builder builder = new Notification.Builder(context, CHANNEL_ID);
builder.setOngoing(true);
// Set notification content intent to take user to fullscreen UI if user taps on the
// notification body.
builder.setContentIntent(pendingIntent);
// Set full screen intent to trigger display of the fullscreen UI when the notification
// manager deems it appropriate.
builder.setFullScreenIntent(pendingIntent, true);
// Setup notification content.
int resourceId = context.getResources().getIdentifier("app_icon", "drawable", context.getPackageName());
builder.setSmallIcon(resourceId);
builder.setContentTitle("Your notification title");
builder.setContentText("Your notification content.");
MyPlugin.notificationManager().notify(someId, builder.build());
Then, for Android 8.1 or higher, add the following to your MainActivity class, found under the android/app/src/main/java/packageName/ folder
GeneratedPluginRegistrant.registerWith(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true);
setTurnScreenOn(true);
}
(This shows the Flutter app even when the screen is locked.)
Flutter only has one activity, so the above code will bring that Flutter activity to the foreground (note that you don't always see the notification, but sometimes you do - if you set it to autoCancel then touching it clears it). It's up to you to build the correct screen in Flutter, which you can do as you send the notification. Use Navigator.push or equivalent to change the page that Flutter is showing.
i use this method to record video from front camera:
Recording video via Mediarecorder
it works fine in my Nexus 4 but some people says that there is a lot of phones that their front camera cant record video and they only can take pictures. My Android App functionality based on recording video from front camera and my question is that is this true that some phones can't record video via front camera? and how i can detect this and inform user?
Try calling some code like this
CameraInfo cameraInfo = new CameraInfo();
if (cameraInfo.facing = CameraInfo.CAMERA_FACING_FRONT) {
//do your code?
} else {
//alert the user via toast or dialog
}
no built in way to figure it out though.
EDIT:
should work on API 9 and above.
maybe try calling these methods to first get a camera object, then check to see if there is a camcorderProfile available for the front facing camera?
hasProfile (int cameraId, int quality)
setCamera(camera);
I am using Android emulator and development platform.
I have created a new application and wonder how can I close or open Android cell phone camera?
If you are talking about opening it from your app you should use the camera Intent for that.
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra("android.intent.extras.CAMERA_FACING", 1);
startActivityForResult(intent, 1);
EDIT:
1 - is for the front-facing camera
When you create the AVD for your emulator, there are options for enabling front and back camera. If you have enabled this option for your emulator, you will be able to access the camera just like you would on a regular phone (using the camera app, or via the system).
You probably didn't enable the camera option on your emulator image if you are not seeing it.
I am going to assume you have enabled a camera on your emulator, and want to access it's functions yourself, instead of opening an existing camera application. You'll need to use functions in Android to actually access this hardware, and you'll also need to give the app permission to use it.
private void startCamera(){
//First check if a camera is available
if(getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
Log.d("CameraApp", "It has a camera");
Camera cam = Camera.open(); //Start using the camera. From here on out you should be able to access it's functions.
cam.unlock();
cam.startPreview();
} else {
Log.d("CameraApp", "It does not have a camera");
Toast.makeText(this, "No camera available",
Toast.LENGTH_SHORT).show();
}
}
Be sure to close it when you're done.
private void stopCamera(){
cam.stopPreview();
cam.release();
}
Add this to your AndroidManifest.xml to give your app permission:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
Each function (zoom, autofocus, etc.) needs it's own permission to be added.
Also see this for more information: http://developer.android.com/reference/android/hardware/Camera.html