Friday, 19 December 2014

Xamarin Android back button event during ActionMode

When a user presses the back button during an ActionMode, OnBackPressed() doesn't get called, s0 how to do we intercept this event if we need to do something?

Like this:
 public override bool DispatchKeyEvent(KeyEvent keyevent)
        {
            if (_contextualActionBar != null && ItemsInEditMode.Any())
            {
                if (keyevent.KeyCode == KeyEvent.KeyCodeFromString("KEYCODE_BACK") && keyevent.Action == KeyEventActions.Up)
                {
                    DeselectallItems(_listOfItems);
                    KillActionBar();
                    return true;
                }
            }
            return base.DispatchKeyEvent(keyevent);
        }

Thursday, 18 December 2014

Screenshot complete listview in Xamarin Android

Today I needed to turn a complete listview into an image, including the below-the-fold content that was yet to be rendered. I found some Java code on SO and ported it to C#. It works a treat:
public static Bitmap GetWholeListViewItemsToBitmap(ListView listview, HistoryAdapter adapter)
        {

            int itemscount = adapter.Count;
            int allitemsheight = 0;
            var bmps = new List();

            for (int i = 0; i < itemscount; i++)
            {

                View childView = adapter.GetView(i, null, listview);
                childView.Measure(View.MeasureSpec.MakeMeasureSpec(listview.Width, MeasureSpecMode.Exactly),
                        View.MeasureSpec.MakeMeasureSpec(0, MeasureSpecMode.Unspecified));

                childView.Layout(0, 0, childView.MeasuredWidth, childView.MeasuredHeight);
                childView.DrawingCacheEnabled = true;
                childView.BuildDrawingCache();
                bmps.Add(childView.GetDrawingCache(true));
                allitemsheight += childView.MeasuredHeight;
            }

            Bitmap bigbitmap = Bitmap.CreateBitmap(listview.MeasuredWidth, allitemsheight, Bitmap.Config.Argb8888);
            Canvas bigcanvas = new Canvas(bigbitmap);

            Paint paint = new Paint();
            int iHeight = 0;

            for (int i = 0; i < bmps.Count; i++)
            {
                Bitmap bmp = bmps[i];
                bigcanvas.DrawBitmap(bmp, 0, iHeight, paint);
                iHeight += bmp.Height;

                bmp.Recycle();
            }

            return bigbitmap;
        }

Tuesday, 16 December 2014

Intent.FLAG_ACTIVITY_NEW_TASK in Xamarin C# Android

While trying to StartActivity from a list adapter I got this warning:
Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
The way to overcome this in Java:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
The not-so-well-documented way to acheive this using Xamarin:
intent.SetFlags(ActivityFlags.NewTask);

Tuesday, 9 December 2014

Converting from dips to pixels

Useful bit of C# Xamarin code for converting from dips to pixels:
            var dpValue = 10; // value in dips
            var d = AppContext.Resources.DisplayMetrics.Density;
            var pixValue = (int)(dpValue * d); // value in pixels

Wednesday, 12 November 2014

Testing with ExactTarget MobilePush - a couple of gotchas

It was with some reluctance I had to re-enter the world of ExactTarget's MobilePush today, something I've previously had a very poor experience with. This time round was initially met with some frustration (things not doing what you expect them to do) but seeking support was actually a pleasant experience, getting concise accurate answers to my queries within minutes.

The support guy helpfully alerted me to a gotcha, and I picked another one up myself. These together cost me a lot of time:
  1. In your development environment the ET device ID for your device changes regularly. This means that each time you deploy to your device you should check the ET ID, so that when you're sending push messages from the Interactive Marketing Hub you know you have the correct device ID in your audience list. The easiest way to check the ET ID is thus: 
  2. //iOS
    NSLog(@"== DEVICE ID ==\nThe ExactTarget Device ID is: %@\n", [ETPush safeDeviceIdentifier]);
    
    //Android
    Log.v("ETPUSH", new DeviceData().uniqueDeviceIdentifier(getApplicationContext()));
    
  3. The registration database updates on a 15 minute cycle. This means that when your device registers with ET it will take anywhere between 0 and 15 minutes for you to be able to find it in the contacts list.

Once these things were considered, and once I'd fixed my dev app which had mysteriously become unprovisioned (what happened to my APNS certificate that used to be there?) then things looked a lot brighter.

Monday, 10 November 2014

CordovaActivity cannot be resolved to a type

Another problem I had updating my Cordova framework cam with this message:

CordovaActivity cannot be resolved to a type

To resolve this, I went to project Properties -> Java Build Path -> Source and Add Folder, to include the CordovaLib\src folder.