Camerax produces different images than android's cam app and OpenCamera - android-camerax

I am using Camerax to capture 4032x3024 images but getting different results than other apps like open camera or android's camera app (different scale ? different fov?).
See that attached android's app
and the camerax:
Both apps use the back camera and same resolution.
Here is my code to bind to camera
private void bindCamera(#NonNull ProcessCameraProvider cameraProvider, CameraSelector cameraSelector, Size captureResolution, ImageAnalysis.Analyzer imageAnalyzer) {
var imageAnalysisBuilder = new ImageAnalysis.Builder();
var imageAnalysis = imageAnalysisBuilder.setImageQueueDepth(1)
.setTargetResolution(captureResolution)
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build();
imageAnalysis.setAnalyzer(analyzerExecutor, imageAnalyzer);
cameraProvider.unbindAll();
if (lifecycleOwner.getLifecycle().getCurrentState() != DESTROYED) {
this.camera = cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, imageAnalysis);
}
}
How can I init cameraX differently ?

I found the answer myself. Seems that in pixel 6 pro, video stabilization is enabled by default in CameraX, which results in cropping and smaller FOV (see https://issuetracker.google.com/issues/230013960?pli=1)
So to fix this I do the following before binding the use case:
new Camera2Interop.Extender<>(myUseCase)
.setCaptureRequestOption(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE,CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_OFF);

Related

Xamarin Local Notification custom sound not playing

Currently working on implementing local notifications in my app and so far it's working exactly as intended but when attempting to replace the default sound with my sound file I no longer get any sound when the notification triggers and I cannot figure out why.
The code for the local notification:
public void GetLocalNotification(string message)
{
Android.Net.Uri sound = Android.Net.Uri.Parse("android.resource://" + Application.Context.PackageName + "/" + Resource.Raw.alarm);
// Build the notification:
NotificationCompat.Builder builder = new NotificationCompat.Builder(Application.Context)
.SetAutoCancel(true) // Dismiss from the notif. area when clicked
.SetContentTitle("Notification") // Set its title
.SetSmallIcon(Resource.Drawable.icon) // Display this icon
.SetDefaults(1 | 2) //Sets sound and vibration
.SetSound(sound)
.SetContentText(String.Format(
message)); // The message to display.
// Finally, publish the notification:
NotificationManager notificationManager =
(NotificationManager)Application.Context.GetSystemService(Context.NotificationService);
notificationManager.Notify(ButtonClickNotificationId, builder.Build());
}
Try setting this line: .SetDefaults(1 | 2) //Sets sound and vibration to .SetDefaults(0), which should stand for 'all'.
I've seen cases where this only plays sound when you set it to 0. I which I could say why, I have no clue to be honest, but it works.
#Gerald Versluis: thanks, but noticed that .SetDefaults(0) adds sounds but then also removes vibration. So to add on this questions, do.SetDefaults(0 | 2), with 2 being (int)NotificationDefaults.Vibrate.
Thus, my solution to add sound and vibrate is:
.SetDefaults(0 | (int)NotificationDefaults.Vibrate)

LaunchUriAsync Windows calculator - first time

Perhaps this is expected behavior, but the programmatic launching of built-in applications in Windows 10 is scarce for anything aside from settings app, maps, and contacts, in my experience - and I could use some help on this.
I am launching the stock Windows Calculator from within the application. I took some guesses as the Uri and it appears to work - except on the first launch. When we get a new device, the first time the app is run and the calculator is attempted to be launched, it wants to get an app from the store (which the end users will not have access to) - it does not even offer the built-in calculator as a choice. If the calculator is opened manually, even once, it just works from that point on. Is there something else I could/should be doing? Any guidance or suggestions would be greatly appreciated.
I would like to have it work the first time (a setting on the device?), or at least offer the built-in calculator as a choice.
Here is the code I am using:
private async void LaunchCalculatorAsync(object sender, TappedRoutedEventArgs e)
{
var options = new Windows.System.LauncherOptions();
options.TreatAsUntrusted = false;
options.DesiredRemainingView = Windows.UI.ViewManagement.ViewSizePreference.UseNone;
await Windows.System.Launcher.LaunchUriAsync(new Uri("calculator:"), options);
}
From running a list of installed apps on the device, I see the calculator listed: Microsoft.WindowsCalculator_8wekyb3d8bbwe. I have been unsuccessful with attempting to provide the PreferredApplicationPackageFamilyName using options.PreferredApplicationPackageFamilyName = "WindowsCalculator";
I have tried with/without the "Microsoft." as well as with/without the odd string of characters.
You may get the demo from Microsoft in GitHub,
Association launching sample
Hope this can help you.
private async void LaunchUriWithWarning()
{
// Create the URI to launch from a string.
var uri = new Uri(UriToLaunch.Text);
// Configure the warning prompt.
var options = new LauncherOptions() { TreatAsUntrusted = true };
// Launch the URI.
bool success = await Launcher.LaunchUriAsync(uri, options);
if (success)
{
rootPage.NotifyUser("URI launched: " + uri.AbsoluteUri, NotifyType.StatusMessage);
}
else
{
rootPage.NotifyUser("URI launch failed.", NotifyType.ErrorMessage);
}
}

Port Admob to mobile web

I am in the depths of creating a mobile web game that I will soon release. I am interested in monetizing this app. I want the game to feel like its a regular app and therefore wish to have admob ads (with deep links to the app store). I have heard that these also have substantially higher cpm that adsense mobile. My question is this: if I "port" admob using node.js will the clicks and views be recorded as server side, i.e. coming from one place, or mobile, i.e. from the user?
Here are some resources I am thinking of using:
https://media.admob.com/api/v1/docs/
https://github.com/floatinghotpot/cordova-plugin-admob
Any thoughts?
I am the author of the plugin you mentioned: https://github.com/floatinghotpot/cordova-plugin-admob
The basic version has been deprecated, and the pro version is recommended: https://github.com/floatinghotpot/cordova-admob-pro
Instead of porting AdMob to mobile web, you can consider use Cordova to pack your html5 game as a hybrid APP, then publish to Apple AppStore or Google Play Store.
Use the AdMob plugin to present Ad in your app, then Google will pay you.
Only a few javascript lines to present the Ad, and the AdMob SDK will take care of Ad presenting and user click.
See the example code:
function onLoad() {
if(( /(ipad|iphone|ipod|android|windows phone)/i.test(navigator.userAgent) )) {
document.addEventListener('deviceready', initApp, false);
} else {
initApp();
}
}
var admobid = {};
if( /(android)/i.test(navigator.userAgent) ) {
admobid = { // for Android
banner: 'ca-app-pub-6869992474017983/9375997553',
interstitial: 'ca-app-pub-6869992474017983/1657046752'
};
} else if(/(ipod|iphone|ipad)/i.test(navigator.userAgent)) {
admobid = { // for iOS
banner: 'ca-app-pub-6869992474017983/4806197152',
interstitial: 'ca-app-pub-6869992474017983/7563979554'
};
} else {
admobid = { // for Windows Phone
banner: 'ca-app-pub-6869992474017983/8878394753',
interstitial: 'ca-app-pub-6869992474017983/1355127956'
};
}
// it will display smart banner at top center, using the default options
if(AdMob) AdMob.createBanner( {
adId: admobid.banner,
position: AdMob.AD_POSITION.TOP_CENTER,
autoShow: true } );

How to get information/data from platformRequest() in J2ME?

I want to implement a behavior similar to Whatsapp, where when the user can upload an image. I tried opening the images in my app, but if the image is too large, I will have an out of memory error.
To solve this, I'm opening forwarding the images to be open in the phone's native image viewer using the platformRequest() method.
However, I want to know how is it Whatsapp modifies the phone's native image viewer to add a "Select" button, with which the user selects the image he wants to upload. How is that information sent back to the J2ME application and how is the image resized?
Edit:
I tried this in two different ways, both of which gave me the OOME.
At first, I tried the more direct method:
FileConnection fc = (FileConnection) Connector.open("file://localhost/" + currDirName + fileName);
if (!fc.exists()) {
throw new IOException("File does not exists");
}
InputStream fis = fc.openInputStream();
Image im = Image.createImage(fis);
fis.close();
When that didn't work, I tried a more "manual" approach, but that gave me an error as well.
FileConnection fc = (FileConnection) Connector.open("file://localhost/" + currDirName + fileName);
if (!fc.exists()) {
throw new IOException("File does not exists");
}
InputStream fis = fc.openInputStream();
ByteArrayOutputStream file = new ByteArrayOutputStream();
int c;
byte[] data = new byte[1024];
while ((c = fis.read(data)) != -1) {
file.write(data, 0, c);
}
byte[] fileData = null;
fileData = file.toByteArray();
fis.close();
fc.close();
file.close();
Image im = Image.createImage(fileData, 0, fileData.length);
When I call the createImage method, the out of memory error occurs in both cases.
This varies with the devices. An E72 gives me the error with 3MB images, while a newer device will give me the error with images larger than 10MBs.
MIDP 2 (JSR 118) does not have API for that, you need to find another way to handle big images.
As for WhatsApp, it looks like they do not rely on MIDP in supporting this functionality. If you check the Wikipedia page you'll note that they don't claim general Java ME as supported platform, but instead, list narrower platforms like Symbian, S40, Blackberry etc.
This most likely means that they implement "problematic features" like one you're asking about using platform-specific API of particular target devices, having essentially separate projects / releases for every platform listed.
If this feature is really necessary in your application, you likely will have to do something like this.
In this case, consider also encapsulating problematic features in a way to make it easier to switch just part of your source code when building it for different platforms. For example, Class.forName(String) can be used to load platform specific implementation depending on target platform.
//...
Image getImage(String resourceName) {
// ImageUtil is an interface with method getImage
ImageUtil imageUtil = (ImageUtil) Class.forName(
// get platform-specific implementation, eg
// "mypackage.platformspecific.s40.S40ImageUtil"
// "mypackage.platformspecific.bb.BBImageUtil"
// "mypackage.platformspecific.symbian.SymbialImageUtil"
"mypackage.platformspecific.s40.S40ImageUtil");
return imageUtil.getImage(resourceName);
}
//...

Java Me video player realize error with http - MediaException

I'm using the below code (references from, http://www.java-tips.org/java-me-tips/midp/playing-video-on-j2me-devices.html). It fails at 'realize()', with the javax.microedition.media.MediaException, "Unable to create native player". What is the problem here?
I tried this using both Eclipse and Netbeans. Am I missing some "internet" permissions or using any incorrect encoding, the video is an external 'mpg' test-resource and does work fine when downloaded through a desktop browser.
public void run()
{
String url = "http://www.fileformat.info/format/mpeg/sample/05e7e78068f44f0ea748855ef33c9f4a/MELT.MPG";
//Append the GUI to a form
Form form = new Form("Video on java mobile!");
Display display = Display.getDisplay(this);
display.setCurrent(form);
try
{
HttpConnection conn = (HttpConnection)Connector.open(url,
Connector.READ_WRITE);
InputStream is = conn.openInputStream();
Player p = Manager.createPlayer(is,"video/mpeg");
//I tried the below, but that didn't work either
//Player p = Manager.createPlayer(url);
p.realize();
//Get the video controller
VideoControl video = (VideoControl) p.getControl("VideoControl");
if(video != null)
{
//Get a GUI to display the video
Item videoItem = (Item)video.initDisplayMode(
VideoControl.USE_GUI_PRIMITIVE, null);
form.append(videoItem);
}
//Start the video
p.prefetch();
p.start();
}
catch(Exception e)
{
form.append(url + " Error:" + e.getMessage());
}
}
I've just started with Java, Eclipse, Netbeans. Since, there similar samples found everywhere, I believe I'm missing something very basic. Can someone please help?
The problem here was the video file. Although my source video seemed "mpeg", it wasn't acceptable to the emulator. After searching through a bit, I found a converter and I manually converted some sample mp4 to "mpeg". It finally worked with the same emulator, after I tried to download and play these manually converted files.
One piece of advise if you are new J2ME/JavaME apps (like me), keep playing with the input data sources/formats and the emulators. Switching emulators or the input data-formats is an easy way to identify the not-so-evident problems.

Resources