Thursday, October 09, 2014

wpf, entity framework, sqlite and all that jazz

so i wanted to do something with wpf and of course data had to be involved. for this project i first played a bit with velocitydb, then some more with ravendb - both great nosql databases, but their licenses drove me away and to SQLite. yep, it is not a nosql db, but is embedded and well known and maintained (which proved priceless when trying to access it with EF6, but this may be the subject a different post).

so loading up vs2013 (and alternatively 'blend') i created my entities and added a datagrid with one of them, F5 and off we go! nowhere
i have some data in my table but it is not shown, wtf?

a quick look at the xaml i notice this: what are these and how do i make them display my data?

soon i understand (i'm new to wpf, mvvm, databinding etc) that it's gotta be something like this creating the entities context, a bit of linq to entities, assign to viewsource.source and...? still nothing!!
i hate to give up on something that should be easy and obvious, so giving it another try - scrap those views and assign data directly to the grid's source and it worked! open the champagne!
wait a second, why can't i add a new row???
now here is gets messy and includes a lot of hair pulling and stackoverflow.com scrolling...
i don't remember the numerous attempts to fix this, but the solution was...i cannot say elegant, but life-saving - wrap the results in an ObservableCollection! this bloody worked...by the way there is another quirk a forgot to mention: if in the xaml your columns are DataGridTemplateColumns - bad things would happen, so to say
better use the datagrid.columns struct and define manually all your columns beautiful...
btw (again) - note the Mode=TwoWay and especially UpdateSourceTrigger=PropertyChanged
without them you may loose couple of precious hours, waisted to gentle hair pulling and swearing..

ah...life is beautiful...let me just, edit some of the fields in the grid and reload the app to ensure changes were saved to db...
what?? where are my changes? everything is so beautifully binded together, what happened?
one of several ways to solve this is via where context is your entities holder.
but several days into this i realized there is a better way: use the grid's RowEditEnding event.
btw i spent maybe two or three days trying to find a way to add new rows from the datagrid to the underlying db. i got really desperate and miserable because there was no example or explanation of how to add new rows as in my case: wpf and entityframework.i searched and searched and searched...probably if i had gotten to read and learn about wpf and binding and EF from scratch, i would've done this earlier, but i guess sometimes even the harder road leads you to your goal....stupid me, anyway..

so how to add new rows from the datagrid back to db with entityframework? turns out the way i solved it didn't include any mistery: use the RowEditEnding, but without relying on any magical bindings - go straightforward:
are we adding a new row? add it to the source
are we updating an existing row? find it in the datasource and updated it, like this: a few important things to note:
  • in the xaml make sure your column Binding definitions include UpdateSourceTrigger=PropertyChanged. otherwise you'll loose the info from the newly added column - all fields will be empty
  • this new row data (here it is p of type razhodi) cannot simply be added to the datasource!!! it is similar, but is not actually a genuine `razhodi` entity instance - you have to create one from the context (context.razhodis.Create()) and assign the values in the real one, before adding to the datasource. the maddening issue here is that context.SaveChanges() will not complain in any way!!! it will be as if everything is fine and all data is saved to db, only it mysteriously IS NOT.
  • another minor trick is to use FirstOrDefault which will return null if nothing is found in db, while SingleOrDefault will return null also, but if there are multiple records in the collection it will throw. so i thought it is cleaner to use the former.
  • in my case i had to explicitly load the updated data back in the datagrid. there is probably a more correct way to do this, i suspect that somehow binding is involved in this :)

so this is it. how to add new rows to wpf datagrid with entityframework. it is probably VERY ugly to an experienced wpf programmer, i know. but i needed a quick hack to serve as a base on which the improve.
next stop - MVVM!

Saturday, June 21, 2014

The provider did not return a ProviderManifest instance (VS 2013, EntityFramework 6)

checking out EntityFramework 6 code-first and encountering various errors during the process :)

this is more of a saved hint how to deal with this...found in the comments here:
https://connect.microsoft.com/VisualStudio/feedback/details/806693/the-provider-did-not-return-a-providermanifest-instance-in-vs-2013-and-entityframework-6

this comes with the inner exception of "Could not determine storage version; a valid storage connection or a version hint is required"

and what solved it was this comment:

Open the EDMX file and change ProviderManifestToken="2012" to ProviderManifestToken="2008"

judging by MS supports' comment, Microsoft seem terribly slow in keeping tools up to date with frameworks...whats the point in rushing when creating ugly problems for (early) adopters?

Saturday, October 05, 2013

AndroVM network setup for android apps testing

not sure how i got to http://therockncoder.blogspot.com/2013/06/using-virtualbox-android-emulator.html, but the idea to have a faster emulation for android apps testing was great so when the time came i decided to put some time and set this up

the original source claimed that setting 'bridged adapter' worked for him so i followed this advice and...it didn't work

this unleashed a couple of hours of testing different variants, scratching my head and searching on the web (btw duckduckgo.com is getting better, and while the results are not so comprehensive as google's, they still manage to provide the most essential hits, most of the time).

the search lead me to this result at stackoverflow.com: http://stackoverflow.com/questions/16321715/how-to-figure-out-the-ip-address-of-androvm-4-1-1-r6-1-20130222-emulator, which in turn got me playing with virtualbox's host-only settings, and then after a moment of tense expectation...nothing...

another search lead me to this article: http://www.cnx-software.com/2013/03/01/how-to-run-android-apps-in-linux-with-androvm/, where they mention that actually it is not the first adapter that needs to be configured, but the second one...back some testing which again didn't provide anything

i should mention that on virtual box i was looking into the androVM configuration screen, where the IP of the device did show up a couple of times, but i could never connect with adb.
i also installed terminal emulator on the virtual box device - i was surprised an first that it managed to connect to internet and download the app from market.

so after scrapping all the previous advices i started experimenting again and finally one of the combinations worked:

the only one, actually that worked is this:

host-only adapter on Adapter1
bridged adapter on Adapter 2

don't ask me why it worked, but in the end it did.
strange thing is that androVM  configuration screen doesn't show the ip. the terminal shows it in netcfg. also make sure the bridge adapter is bound to the actual working network adapter

now i have to figure out why my ActionBarSherlock application works on 2.2-2.3 devices, but the bar is not shown on 3.0, 4.0 etc... any ideas?

p.s. eclipse has no problem detecting the 'device' started on androVM, just tell it to detect running Android devices, connect to yours and off you go...


Thursday, September 19, 2013

image is rotated after camera preview in portrait mode (android)

this was quite a headache.
in surface preview (portrait) everything is fine, but once you save the image it turns out it is stored rotated on 90 degrees. what the heck?!

it seems a huge problem with some phones and checking some groups, android team has no intention to fix this, claiming it is manufacturer problem. ok.

there are many useful  discussions on stackoverflow.com (of course) with different suggestions. some of them quite ugly. i tried to go with the one to rotate the image back before saving, but then you cannot do this in every case because in landscape everything seems to work fine...grrrr...

ok, first lets see how may we know what mode we're in (landscape/portrait)

again a bunch of hacks and solutions...
- "width>heigh? you're landscape"
- check in mode the file itself was saved via exifinterface:
             exif = new ExifInterface(file.getAbsolutePath());

- blah blah blah

here's the one that works for me:
        Configuration newConfig = parentActivity.getResources().getConfiguration();
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
                Log.v(LOG_TAG, "detected landscape mode");
        } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
            Log.v(LOG_TAG, "portrait mode detected");
        }
 so how do we use this info?

rotate!

now if we rotate the camera (and we're sure we're in the bloody portrait) will it save what is sees correctly? Noooooooooooo, the images is again rotated incorectly

ok, so lets rotate the image as well then

but here is another darn problem; "Out Of Memory" exceptions - first we get the byte[] of the image, then we create a bitmap out of it, and then try to rotate with a Matrix. well, you can't - BOoooM!

at least on my humble device

so you have to come up with some trick i guess

using square's excellent picasso wouldn't do the trick because even if it may rotate the image when it loads it, it cannot save it rotated back to storage.

wait a second, did you say "rotate the image when it loads it"?

so here is how we can trick the trickster - rotate the image on loading!

but we have to know if the image even has to be rotated, what if it has been saved in landscape mode and all is good? do we have to, like, open the file and read some information from it? blah...

well - there is an easier way - just give the file such a name that you'll know it has to be rotated when loaded, then it gets as easy as PI:

        if (filename.contains("MUSTBEROTATED")) {
            Picasso.with(activity.this.getApplicationContext()) //
            .load(new File(filename)) //
            .rotate(90f)
            .resize(screenWidth, screenHeight)
            .centerInside()
            .into(imageView);
        }
        else {
            Picasso.with(activity.this.getApplicationContext()) //
            .load(new File(filename)) //
            .resize(screenWidth, screenHeight)
            .centerInside()
            .into(imageView);
        }

and thats about it i guess

what remains to be seen is how this will work on devices that do not have this portrait nightmare problem...probably doesn't...so much for hacking glory...


Tuesday, September 03, 2013

rotate image in android apps

i guess i'm starting to learn a thing or two about organizing my stuff, and as result decided to post the result of one task that is a part of a bigger task, that is a part of an idea that i'm already getting tired of chasing...

my app has to display images and i want to be able to rotate them! sounds simple, and it is! especially with the miracle of Internet, GOOG and stackoverflow.com

so we have this imageview...
  ImageView imageView = (ImageView) findViewById(R.id.test_image1);

we're loading some picture onto it...
 Bitmap bMap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);

and turns out there is this lovely Matrix class, that exists for all kind of math abuses
                 Matrix mat = new Matrix();
                 mat.postRotate(gradus);


so we can take the original bitmap and apply the matrix operation on it
                  Bitmap bMapRotate = Bitmap.createBitmap(bMap, 0, 0, bMap.getWidth(), bMap.getHeight(), mat, true);

and when we set this image on the imageView we expect to see the rotated image, right?
                imageView.setImageBitmap(bMapRotate);

but somewhere something is wrong or some manual has not been read, cause a vital piece is missing: you have to set scale type on the imageView, (before assigning the new image?)
              imageView.setScaleType(ScaleType.MATRIX);

now this will work fine and will leave this highly uninformative post online, so i can remember how i did it!

i simply don't have the time to research the why's and do's - at least not right now that i'm still in prototyping phase and the steam has already began to ...steam away...
i lost a few days (all right - couple of hours over few days) with the rotate images problem and at least it made me learn to split bigger tasks into smaller ones - and how effective and helpful it can be!

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!