I'm writing an app for which the camera is an essential feature. In this regard I want to be 100% certain about the following aspects:
If I use the deprecated camera: will the app still run on all APIs
now?
If 1) is yes: At what point in time this app will not run
anymore on all APIs (my app shall cover minimum API 17) ?
Where can I find updated official information about 2), i.e. what is planned and by when?
Say, I would use the new camera2 already now, my understanding is that the app would
not run on any API below 21 - correct?
My working hypothesis from the information I got so far is: NOW still use the the deprecated Camera. But Keep watching market shares of APIs and start learning camera2 soon, in order to be ready to switch the app to camera2 within the next 2-3 years. Do you agree?
In any case, the use of a device's camera and making it run on virtually all targeted devices is tricky enough (as for now I am happy to have mastered the "old" Camera...). Therefore, I really want to be sure about the above points. Many thanks for your answers.
If I use the deprecated camera: will the app still run on all APIs now?
Yes.
At what point in time this app will not run anymore on all APIs (my app shall cover minimum API 17) ?
Build a time machine, go into the future, find out, and let the rest of us know.
IOW, we have no way of predicting if and when Google might discontinue this API entirely. That being said, they almost never discontinue APIs.
Where can I find updated official information about 2), i.e. what is planned and by when?
Get a job with Google, or go with the aforementioned time machine option. Google is not in the habit of announcing plans in advance, and their time machine is not available for rental.
(though Elon Musk probably has a Tesla outfitted with a Mr. Fusion, so you could reach out to him...)
I would use the new camera2 already now, my understanding is that the app would not run on any API below 21 - correct?
Correct.
NOW still use the the deprecated Camera. But Keep watching market shares of APIs and start learning camera2 soon, in order to be ready to switch the app to camera2 within the next 2-3 years. Do you agree?
No, for reasons I will clarify after your next quote.
the use of a device's camera and making it run on virtually all targeted devices is tricky enough
Part of that trickiness is the fact that device manufacturers have camera implementations that might be generously described as "quirky".
The problem with sticking with the old camera API exclusively is that I expect quality control on that API to steadily decline. What limited resources device manufacturers have for cameras primarily will be devoted to the new API.
Hence, my recommendation is to use both APIs: using camera2 where possible and falling back to the original API where needed. Admittedly, this requires substantially more work. If you are not in position to do that work, then you have no choice but to stick with the original camera API until such time as you are ready to have your minSdkVersion be 21+.
Google Just announced CameraX, a API wrapping camera and camera2. This new support API tries to eliminate the quirks each manufacturer added to for our enyojment.
Check it out: https://developer.android.com/training/camerax
Related
What are the next Android smartphones to be compatible with ARCore?
Is there a known list of future compatible devices yet? Maybe a general project schedule?
We are about to purchase some units for AR development assessments, at first we thought about trying one of the Tango devices out there (we already had a good experience with Tango), but our current bet is that the ARCore platform will beat it in terms of market share.
Currently, the compatible devices are only:
Google Pixel
Samsung Galaxy S8 (the non-plus version)
But obviously, we would prefer to choose from a wider variety (e.g. S8+, G6...)
I know that there is a known hack to make it work on other devices, but it is better to start on the right track with a compatible one while we still can.
Also, is there a way to run ARCore on emulator that connected to webcam?
For test purpose.
(I don't think this answer deserves the bounty, and I also don't think you'd get a worthy one any time soon. But let's roll anyway:)
So I did a bit of a research as to why are these the only devices supported. It's a tough question to answer of course, but we can speculate.
I read through the reddit on the subject (among other sources) and it seems that ARCore does not require some special hardware, but it does require a "calibration profile" per each specific set of camera, sensors, and builds. I.E. each device.
I've found this Medium article about what Apple had to do in order to calibrate their own ARKit coupled with some speculation about Google's calibration process.
WOW! Turns out it's a really heavy task. And it seems that Google has chosen these devices specifically because they've already undergone some initial calibration for other purposes. So it's even harder to start the calibration from scratch.
OK... So?
So... There seems to be mixed news here:
The good news is that ARCore does not rely on some fancy new hardware platform with some fancy new standards that are gonna be hard to enforce in an already highly fragmented market.
The bad news is that unless an automatic calibration process is invented, each device SKU needs to undergo a costly, lengthy and manual process. It's very hard to estimate the costs involved, and even harder to estimates the rewards.
Which brings us to where we started: My guess is that device manufacturers will not be quick to jump on the ARCore bandwaggon. Yet.
It seems that it's gonna take some time before you'd get a reliable answer to your question.
The current list of ARCore supported device manufacturers and models can be found here:
developers.google.com/ar/discover#supported_devices
To your last question around testing on the emulator, as of this week, you now run ARCore in the Android Emulator with a virtual AR camera:
https://developers.google.com/ar/develop/java/emulator
When you are using Android Studio 3.1, and Android Emulator v27.1.10, just create a new Android Virtual Device (AVD) for the Android Emulator that targets Android 8.1 Oreo (API 27) and verify that the back camera is set to Virtual Scene.
You will get the current list of ARCore supported device manufacturers and models below link.
ARCore Supported Devices
Here is a list of ARCore 1.4 Compatible Devices (last updated October 19th, 2018).
How to take a screenshot of other app programmatically without root permission, like Screenshot UX Trial?
I know I can capture the bitmap of the root view in my app. But I can't get the root view of the other app when my app is running in background
bitmap = Bitmap.createBitmap(rootview.getDrawingCache());
There is a permission for capturing current frame buffer in Manifest: android.permission.READ_FRAME_BUFFER. But some website says it's for signature app only.
Check Android Permissions - Protection Levels
After trying Screenshot UX Trial, I read the permission:
INTERNET: for connect to localhost screenshot server for rooted phone.
SYSTEM_ALERT_WINDOW: for topmost camera button.
VIBRATE: for vibrate feedback.
WRITE_EXTERNAL_STORAGE: to save the screenshot.
GET_TASKS: for detect foreground Develoment setting activity for non rooted&non preloaded capture method.
It seems either SYSTEM_ALERT_WINDOW or GET_TASKS allow the app to take screenshot.
I have two guess of how it works:
It may be able to access the Activity of the foreground activity, it gets the root view of the Activity, capture its screenshot.
Calling glreadpixels
If you try one of my guess, please let me know the result.
This is extremely difficult. I spent several years trying to do it. I eventually succeeded, but any solution will involve commercial as well as technical effort.
Update March 2015
Most of the stuff below is no longer up-to-date. There's now, after all these years, an android.media.projection package
https://developer.android.com/reference/android/media/projection/package-summary.html
which finally allows what you need!
Capturing the screen image of your own application
For completeness, I want to include your own comment that you can capture an image of your own application using Bitmap.createBitmap(rootview.getDrawingCache()); and similar mechanisms.
Capturing the screen of another application whilst you're in the background
Using the READ_FRAMEBUFFER permission
Firstly, you're right that a normal application can't make use of the READ_FRAMEBUFFER permission, because it's "signature"-level. That means you must be signed by the same key as the Android system ROM in order to be able to take such a screenshot.
I thought this was a bit sad, so back in 2009 I made an Android open-source project submission to ask that it be opened up1. The response from Dianne Hackborn, the Android architect was:
Um, no. Absolutely positively not.
So, that went well, then! Hence this permission is still signature-level to this day.
If you had this permission, however, you could call the captureScreen member of ISurfaceComposer2. You'd need to write some native code to access this function, using the Android NDK and also some undocumented APIs. However, it's possible.
Internally within the Android graphics subsystem, this uses a glReadPixels call to retrieve the pixels from the GPU back to the CPU. (The GPU is used for most of the compositing on Android. In fact Android 4.0+ supports extra hardware compositors, and the Surface Flinger has to do even more work to pull those pixels back to the CPU.)
This call works beautifully, except for a few small problems:
The risk of using an unsupported API which might break at any moment;
The hassle of calling it in C++
It causes the GPU pipelines to stall, which can upset the GPU designers but doesn't really cause problems in reality
It relies on a large bandwidth from the GPU back to the CPU. This is sometimes problematic because memory architectures are designed to send data in the opposite direction. However, I seem to recall that all modern Android chipset architectures directly share memory between the GPU and CPU, except for one (it may be Broadcom? - I can't remember) where this may cause this mechanism to be very slow.
... and one large problem ...
Most importantly, as a normal application writer, you can't even call this API due to the signature-level permissions required.
Still, on most Android devices, you can get 10 frames per second out of this. Better still, this API actually supports scaling the resulting image in hardware on the GPU, so if you're clever you can pre-scale the image to just the size you need, before the pixels even hit the CPU. So it can be extremely high performance.
Note, of course, that you as an application writer can't call glReadPixels because you don't have access to the relevant OpenGL context. It's owned by the surface flinger.
Using /dev/graphics/fb0 and similar
Some are tempted to try to read these Linux device files which represent the framebuffer. However, there are three problems:
You need root.
Sometimes they're not even there.
Often, they don't represent the real screen image. Remember on Android that the graphics are composited on the GPU. So there's no reason why the CPU should have access to a copy of the full composited screen image, and it often doesn't. This file sometimes contains tearing (at best) and a garbage image (at worst). Interestingly, some of the tools for rooted phones do use this method, which I think is a mistake. If you've got root, you by definition have all Android permissions and can therefore call the above captureScreen API to get a correct image.
Using hardware partners
Now we get into the solutions which require commercial action.
Talking to the Android chipset makers often presents a solution. Since they design the hardware, they have access to the framebuffer - and they often are able to provide libraries which entirely avoid the Android permissions model by simply accessing their custom kernel drivers directly.
If you're aiming at a specific phone model, this is often a good way forward. Of course, the odds are you'll need to cooperate with the phone maker as well as the silicon manufacturer.
Sometimes this can provide outstanding results. For example I have heard it's possible on some hardware to pipe the phone hardware framebuffer directly into the phone hardware H.264 video encoder, and retrieve a pre-encoded video stream of whatever is on the phone screen. Outstanding. (Unfortunately, I only know this is possible on TI OMAP chips, which are gradually withdrawing from the phone market3).
Using security holes
Android rigidly enforces its permission model, and has few security holes. However the Android OEMs can sometimes be more careless.
For example a major OEM whose name begins with S has implemented a way to capture the screen using a keystroke. It saves it to a world-readable file on the SD card. Hypothetically you might be able to find what intercepts those keys and see how it works. Perhaps you could do something similar.
And perhaps there's a way for another major OEM whose name also begins with S.
No, I'm not going to go into any more detail on this section. To work out how to do those things, I'd need to have reverse-engineered software, and that might be illegal. Good luck, though.
Working with the phone makers
As described previously, the phone makers have ready access to an API which does work. And the phone makers have the signature-level permissions required.
So, all you need to do is to arrange to get your software signed by the phone maker.
This is, however, hard. By signing the software, the phone maker is guaranteeing its quality - so they should want to audit your source code. Also, due to the nature of Android - if they sign the software, they need to be the ones distributing it. You can't put it on the Market if it is signed by someone else's signature.
However, the OEM need not include it on the ROM - they can still distribute it on the Android market. But you can't.
A good solution would be if each vendor signed a small library which then could be accessed by a common SDK. Which leads me onto...
Work with software partners who have solved this already
I know a lot about this because I used to work at RealVNC. We worked with all the major Android phone vendors to get access to these signature-level APIs. I cannot overemphasise the many, many man-years of effort (commercially and technically) required to achieve this. Some of the OEMs have publicised this work - for example 4.
I do not work at RealVNC any more, so I have nothing to gain from advertising their software. But if you really really want to be able to capture the screen on multiple Android devices, you may wish to approach them about re-using their Remote Control Service or Android VNC SDK 5. It is not open-source so you should expect to pay, and believe me this is fair enough given the epic effort involved in working with all these Android OEMs.
In the interests of balance I should point out that other vendors have also worked with the phone makers on this - e.g. Soti. But I believe they all offer specific device management solutions, rather than a general remote control/event injection SDK.
Over USB
Another option - the adb daemon which listens for debugging connections over USB has slightly more privileges than a normal application, which is why it's able to grab the screen (you can see its image using the ddms tool). If you're able to run any command using adb then you too can gain those privileges (as per the android-screenshot-library linked previously).
Contribute to the Android open-source project
Eventually this problem reduced me to dust, and I left for greener pastures which didn't involve trying to squeeze pixels out of Android phones.
Before I left RealVNC though, we tried again to contribute these APIs to the Android open-source project. This time we got a more positive reaction6. In short, it was suggested that our security approach was almost right, but that the graphics system was in too much turmoil to accept our patches. Well, the great news is that the graphics system is no longer in turmoil - in fact it now has that captureScreen API which means no graphics system changes are needed whatsoever. It may therefore be possible to submit a new security mechanism to AOSP around this API which finally solves this problem.
Maybe the android-screenshot-library can help. But well in their Usage page it says that it needs a native service started with adb (from the android sdk).
PS: Remember that Screenshot UX does not work for every unrooted phone.
I don't think Android will allow you to access another app's frame buffer. This is just part of the security of Android. Each app should keep to its own resources.
If you really need to get a screen capture of any app, I would suggest using the native screen grab "gesture". For the the Nexus 7 for example, simply "... hold the power button and the volume down button at the same time for approximately 2 seconds."
A Google search will usually find the trick with your device.
I am trying to write an android application that uses several of the android apis(like policy manager, package manager, wifi apis etc).
The concern i have is, android being open, manufacturers/carriers are free to take any specific version of android as their start point and customize the same and ship it with the device.
Note:Please excuse me if this post is in anyway a repeat of earlier posts on the same/similar topic. In such a case, appreciate anyone sharing the earlier post.
Few things that bother me are:
Does android enforce/require manufacturers/carriers to retain the default apis and only over-ride/customize the look-and-feel?
even if manufacturers change the implementation/behavior of the basic apis that comes from android, do they adhere to the interfaces so that my code doesnt break?
how do i ensure/test that my code works on all of the android devices since there is a possibility that one or more customizations could break my whole application?
I know these are some naive questions for many of you who may have been on android for a while, but any pointers in this regard would be of immense help.
Any other information in general w.r.t cross version, cross device incompatibilities and strategies to deal with them would be very helpful.
Thanks a lot in advance.
Regards,
Deepak
Your concerns (and many other developers) are addressed by: http://source.android.com/compatibility/index.html
But this still does not guarantee that manufacturer will not change API and break your application.
The common approach is to initially target subset of devices that make up large percentage of market and then implement workaround for other devices (if necessary). Sample info about device market penetration can be found at:
http://opensignalmaps.com/reports/fragmentation.php?
Kind regards,
Bo
First off, I don't believe you should need to worry about this. Only after you have thousands of users will you end up needing to face the more complex issues caused by the great number of manufacturers offering Android devices. This should not discourage you from developing for Android.
Does android enforce/require manufacturers/carriers to retain the default apis and only over-ride/customize the look-and-feel?
No. But it would certainly work against them if they remove important APIs from the system. The core exists as a whole, though there really isn't anything preventing them from removing or disabling chunks as they wish. For example, AT&T had disabled the ability to sideload apps on Android devices some time ago (but I don't think they still do that). An example of a device with reduced functionality: Amazon Kindle Fire. It doesn't at all look like Android in the majority of its interfaces (except within third-party apps) and it doesn't offer the complete API set. Even with those dramatic changes, Android app developers still have great success building and selling apps that run well on the Kindle Fire.
Even if manufacturers change the implementation/behavior of the basic apis that comes from android, do they adhere to the interfaces so that my code doesnt break?
That's the idea, but there isn't anything in place to forbid them from breaking things. Nor is there anything that will keep them from introducing bugs accidentally.
How do I ensure/test that my code works on all of the android devices since there is a possibility that one or more customizations could break my whole application?
I know that some manufacturers will offer an emulator for their devices/configurations to help test against their systems. For example, Motorola offers MOTODEV Studio for this purpose.
As discussed in other posts, most Android devices don't support recording calls.
Recording AudioSource.VOICE_CALL does though work fine on my Samsung Galaxy S2.
Does anyone know if supporting this is Google's new trend, or it's just a feature specific to SGS2?
I don't believe that Google is moving towards recording voice calls. In fact, I think they are probably working on ways not to allow this due to large security issues. Speaking of which, some recent news that happened a few days ago reports of such security flaws. I don't think that using AudioSource.VOICE_CALL was meant to be used in this way. Hope this answered your question.
Update: News link from 2011 is unfortunately broken now. Sorry about that.
Google doesn't have any control over this (unless they start mandating that devices must / mustn't support voice call recording in their Compatibility Definition Document).They have provided a way for applications to request the voice call audio by adding the VOICE_CALL AudioSource, but the actual implementation of this feature is platform-specific and is handled by the platform vendors and OEMs.
It may, however, be the case that you see more platforms having support for this feature now than you did back in 2011 (or 2010, since it takes a while for new platforms to appear on the market in consumer products).
I've worked with about half a dozen different mobile platforms over the last couple of years. Of these, every single one has had support for recording voice calls, although on two of them the software support was unfinished.
TL;DR: No, it's not an SG2-specific feature, but it's also not universally supported. And it doesn't really have anything to do with Google.
I have been developing for Android 2.2+ for the majority of the year. But when I look at the "List of Android Devices" on wikipedia, I see a substantial number of Android 2.1 devices. A lot of these may have never received OTA updates and some were released not that long ago. I've seen the readily available statistics about Android 2.2 being the most widely used, but I can't help feel like I'm cutting a big audience out.
I've seen a few differences between 2.1 and 2.2 (like with TabWidgets) but if I just dropped my SDK down to 2.1 what differences should I be aware of?
Is this even less relevant now, thoughts and experience welcome, or links to informative sources
As always, it depends on the specific features of your application. I don't want to talk you out of supporting 2.1. I'm certainly not an expert. But you have to weight how much work it is to make your application available to the last 20% percent of the market.
Although I like the idea of maintaining a lot of backward compatibility, I think it makes sense to support the "current and future market" more than spending a lot of effort to support older devices. Of course, if your application works well with older API levels that's great and you should obviously set it as such. Who knows, maybe adding support for 2.1 will take you less time than it took me to type this. :)
You can see up-to-date stats directly on the Android Platform Versions website.
I think the more interesting graph is the 2nd one that shows "number of Android devices that accessed Android Market" recently. (current one inlined here). So if you support 2.2 it looks like you're supporting over 75% of the market (and that number is only going to grow).
One other thing to watch out for is performance. In addition to features the pre-8 API doesn't support, older devices sometimes just don't have the performance of the newer ones. (Not always the case since there are dozens of devices.) One test device I used didn't support Live Wallpapers, not because of the API, but because the device just didn't have enough horsepower.
I'd definitely target 2.1 to get the largest audience.
The changes you have to be aware of are not huge, but can definitely stick you if you don't catch them.
A couple of things:
showDialog(int) can't take a Bundle as an argument in 2.l. The 2.2 call is: showDialog(int, Bundle)
You use a different function to access the SD card (also note that the SD card paths are different in 2.1 and 2.2)
I suggest using the android dev's reference pages feature of filtering by version. It'll make coding for 2.1 much easier.
http://developer.android.com/sdk/android-2.2.html
Personally I think you should just use the lowest you can support without damaging your functionality, features or UX.