Monday, August 26, 2013

android camera.open() freeze

weirdest thing happened while i was experimenting with android.hardware.camera api.
i was testing on a 2.2 device and of course there were the problems with
Camera.getNumberOfCameras() missing etc, but when i got to the point to get a handle to the camera with a simple camera.open() - nothing happened!

literally, because the app froze and nothing would unfroze it. it even blocked other applications trying to use the camera, and that until reboot of the device.

i thought maybe it happened because i was on the ui thread, but even as i pushed the camera code to an AsyncTask,doInBackground(), while the ui thread was responsive there was never response from the async portion

weird, a?

i read this was only fixed about API 5 releases and 3 years later. wow!

the obvious workaround is to use intent as i was originally planning, but is this really such a big, unsolvable problem? certainly there are apps that are using the hardware.camera api so how do they manage to workaround it? or maybe the problem is gone in the camera.open(int) method, which is introduced in 2.3

in any case, android is fun. i wonder if you'd agree with this statement if you we're working on it for money under strict client requirements...

UPDATE 2013/09/06:

So there is a way to get handle of the camera, as i suspected in involves SurfaceView which i didn't want to get much into at the time of the previous writing as i was planning to use intent, but actually there are many examples for using SurfaceView out there and here is the code that worked for me:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getWindow().setFormat(PixelFormat.TRANSLUCENT);

        surface_view = new SurfaceView(getApplicationContext());
        addContentView(surface_view, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

        if (surface_holder == null) {
            surface_holder = surface_view.getHolder();
            surface_holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//http://stackoverflow.com/a/6793598/1419136
        }

        sh_callback = my_callback();
        surface_holder.addCallback(sh_callback);
    }
   
    SurfaceHolder.Callback my_callback() {     
        SurfaceHolder.Callback ob1 = new SurfaceHolder.Callback() {

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                  mCamera.stopPreview();
                  mCamera.release();
                  mCamera = null;
            }

            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                mCamera = Camera.open();

                  try {
                       mCamera.setPreviewDisplay(holder); 
                  } catch (IOException exception) { 
                        mCamera.release(); 
                        mCamera = null; 
                  }
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width,
                    int height) {
                mCamera.startPreview();
            }
        };
        return ob1;
}

this is all from the wonderful post at http://stackoverflow.com/a/10482872/1419136 by Bharat Sharma

a very nice example of actually taking a picture is here: http://stackoverflow.com/a/16399425/1419136, by user jiahao

so stackoverflow has been getting huge over the view years, i still remember one of its founders writing a post about dreaming about such a hub of help for developers/admins and all kinds of people looking for qualified answers - well done!

Tuesday, January 01, 2013

hello github

i posted the code for the android app i mentioned earlier in github here: https://github.com/esdee-git/missed-calls

since the app itself was my coding test for android platform, a good decision was to use it as test of github :)

must say that github's windows app is pretty cool, although i thought it was capable to do more - tortoiseSvn style maybe? still checking things around so it may turn more powerful yet, for now i'll do mostly with the git console

grasping git easier as i have svn experience, but i realise the two differ a lot, but i guess it is mostly on a higher/architecture level

in any case, it would be nice if someone found the code useful, and maybe even make it better

enjoy and a Happy New Year

2013 yeyyyy!



Thursday, October 04, 2012

my first complete android app

well, what can i say - it is fun to program for android; i enjoy java and the android apis are ok.
my own android phone is quite old, running android 1.5 so i had to write for api level 3.
i see some improvements in the following apis, when i have time i'll probably try to root and upgrade to 2.1 (no intention to buy a new phone yet).

what else can i say - eclipse is great! so great, i started using it at work, instead of kdeveloper. it definitely is an accomplished platform

on the app itself - it irritated me that there was no sound notification for missed calls, so i thought, why not write one myself (it is only a few days ago, about 4 months since i started working on and off on this app that i found out that there already were couple of solutions for this on the droid market - which is absolutely not surprising).

first of course there was the alarm manager api, but i quickly dismissed it.

i decided to go with a service that checks the status of the calls periodically. but how often should this period reoccur? what if we miss some important notifications?

so i decided to hook the incoming calls intent (actually PhoneStateListener). this worked quite well - after the call is finished, if it wasn't answered my app plugged in and started sounding the alarm every few seconds.
this eventually completed the flow.

there was something strange that i observed. actually the biggest horror a developer may stumble upon - the app worked fine in the emulator, but occasionally when deployed on the phone it wouldn't pick the missed call and remain in obscure state.

so what do you do when you don't know what you program does? hook a logger and watch what your program says it is doing. after some staring at the logger output, it turned out that the system database i read phone calls from (android.provider.CallLog.Calls) registers the (missed) call a few seconds later than the call occured. unfortunately this mismatches the app's own timeline and so - the notification never gets to be fired. the fix was to wait a few seconds before quering the database.

so now i have some more confidence in my app and can show it to the world. i don't think anyone will pay attention, but the satisfaction of getting to "do something" and bring it to completion is priceless.

now if i can only find my way around to actually figuring out how to publish to google play market...