Try PandaPow for Android
Profile for android 1

Name android 1
AvatarUsers avatar
Posts8
  • Set up VPN on Android in less than 5 minutes
    Board >> Blogs

    Setting up VPN on Android, or any smart phone for that matter, can be a bit of a pain. It's not ideal having to manually type all the info needed for setting up VPN on the phone. It is easy to make a mistake when typing, which can lead to severe headaches trying to trouble shoot the problem. If you have several accounts to set up, or several phones to configure, then it can become quite a project.

    The following short guide shows how to use the import feature of the 1 VPN app to make it easier to set up VPN. The import function lets you import one or more VPN configurations from a file or email. This feature is also useful for backup and restore of your VPN settings. The 1 VPN app can be bought from the Android market or from the app developers website http://doandroids.com/Apps/OneVpn/.

    Step 1.

    Lets assume we are setting up a PPTP connection, then the first thing to do is to send the following text in an email from your computer to your Android phone:

    PPTP; My VPN; username; password; vpn.myserver.com; ; true
    

    Naturally you should replace 'username', 'password' and 'vpn.myserver.com' with something which is appropriate for your particular VPN server. Also, if you don't want encryption, you should replace 'true' above, with 'false'. You may also want to leave the password empty, for security reasons, in which case you will have to fill it in later when you connect to the VPN.

    Step 2

    Open the email you just sent on your Android phone using the Gmail client, and copy the text to the clip board. To copy text from an email you need to press "Menu>More>Select Text", then select the text to be copied by dragging your finger across it.

    Step 3

    Open the 1 VPN app, and click the "Add". On the following screen click "Import profiles" (the last option). This will bring up the Import Wizard seen below. Next you click "From Clip board", which imports your set-up and shows the list of profiles just inported (in this case only 'My VPN'). Click OK and you're done.

    Imported Profile

    Confirm Import

    Import Wizard

    More

    The 1 VPN app makes it easier to use VPN on Android, with the import function being one of its handy features. There is also an export function which lets you backup your VPN set-ups, or copy it to other phones.

    To learn more about the import/export features of 1 VPN on Android, you can look at: http://doandroids.com/Apps/OneVpn/how-to/import/.

    The main time saver of 1 VPN is its unique 1-click connect feature. To learn more about 1 VPN visit http://doandroids.com/Apps/OneVpn/faq/.

  • My svn quickies - add an existing source tree
    Board >> Blogs

    Frequently reoccurring svn task is: add an existing source tree as a new project in a svn-repository. Here's how I do it:

    # done once and for all, this creates a template I use for all my svn-projects
    mkdir ~/svn/project_template
    mkdir ~/svn/project_template/trunk
    mkdir ~/svn/project_template/tags
    mkdir ~/svn/project_template/branches
    
    # done only if you want a new repository (which may contain several projects) 
    svnadmin create /path/to/repository 
    
    # next, create a new empty project, called NewProject, by importing the template:
    svn import -m "new app" ~/svn/project_template file:///path/to/repository/NewProject 
    
    # Next, cd to the parent of the new source directry, i.e. 'NewSourceDir' below should contain
    # all files and directories you want to add to the trunk-directory of the svn-project. Next do:
    svn co file:///path/to/repository/NewProject/trunk NewSourceDir 
    # this turns the NewSourceDir to working copy of trunk,
    # but it doesn't add any of its content.
    # So now it is time to start adding the stuff:
    cd NewSourceDir
    svn add X Y ...
    # and finally a commit:
    svn ci
    

    This is my preferred way of doing it since it lets me add the new stuff selectively. Rather than using 'svn import' to add everything at once, in which case I would first have to create a 'clean' copy of the new source. Hmm, i'm gonna put the above in a script so that I don't ever have to look at this post again :)

    Just a note on svn add. Default when add is applied to a directory is to add all its content recursively. To add only part of the content, use the --depth flag. That is:

    svn add --depth=empty NewDir
    

    adds an empty NewDir to the reporitory.

    svn add --depth=files NewDir
    

    adds NewDir and all files it contains, but leaves out directories.

    svn add --depth=immediates NewDir
    

    adds NewDir and all files and directories it contains, but not recursively.

    Here's a link to another svn cheatsheet which covers some other tasks.

  • Android Drag and Drop
    Board >> Blogs

    A fundamental UI feature such as Drag and Drop should be trivial to implement, right? In fact, on Android it isn't that difficult (depending on how flexible you wanna be of course). That said, it does require that you implement your own view class(es) so if that turns you off, then you'd better stop reading now :)

    Most drag and drop references I've found online refer to the source code of the Android Media Player. It's TouchInterceptor class implements a drag and drop of elements in a list. Another resource, which provides a more generic, but also more complicated, drag and drop is the Android Launcher app.

    Since I wanted more than just a list rearrangement, I decided to follow the example of the Launcher, albeit much much simpler. The basic idea is to introduce a class, called DragLayer, that extends FrameLayout and which takes care of most of the actual dragging. Unlike in the Launcher, however, I would restrict the DragLayer to only moving the object around, and let whatever user of the layer take care of things like scrolling, dropping it in place, et c. Also, the drag layer of the Launcher creates a copy of the view that is to be moved, rather than moving the actual view. This is obviously useful in many cases, but not always necessary, so I decided to make that optional.

    A key in implementing the DragLayer class is understanding the interaction between the touch detection callbacks that exists in a ViewGroup. They are:

    • boolean onTouchEvent(MotionEvent ev) - called whenever a touch event with this View as target is detected
    • boolean onInterceptTouchEvent(MotionEvent ev) - called whenever a touch event is detected with this ViewGroup or a child of it as target. If this function returns true, the MotionEvent will be intercepted, meaning it will be not be passed on to the child, but rather to the onTouchEvent of this View.

    So in order to for our DragLayer to take charge of the drag movements, it needs to implement these two functions. In addition I let it implement two functions startDragging and stopDragging as given in the below outline. This example only handles movement on the x-axis, but that's should be very straight forward to extend:

    class DragLayer extends FrameLayout {
        ...
    
       // Called by user with a child of this DragLayer to be 
       // dragged
       public void startDragging(View child) {
          // Do initial setup to enable moving the child
          mStartX=mLastMotionX;
          mStartRightMargin = getWidth()-child.getRight();
          mDragView=child;
          doDrag(mStartX);
    
          // Indicate that we are now in dragging mode.
          mIsDragging = true;
       }
    
       // Moves the object by changing the right margin
       void doDrag(int x) {
          View v=mDragView;
          LayoutParams params = new LayoutParams(v.getLayoutParams());
          params.gravity = Gravity.RIGHT;
          params.rightMargin = (int) (mStartX-x) + mStartRightMargin;
          v.setLayoutParams(params);
       }
    
       // Called internally when dragging is stopped
       protected void stopDragging(int x) {
          if (mIsDragging) {
              mIsDragging = false;
              // Call back to user
              callStopCallback(x);
          }
       }
    
       @Override
       public boolean onInterceptTouchEvent(MotionEvent ev) {
          final int action = ev.getAction();
    
          final float x = ev.getX();
    
          switch (action) {
    
             case MotionEvent.ACTION_DOWN:
                // Remember each down event, 
                // as it is needed in startDragging above 
                mLastMotionX = x;
                break;
    
             case MotionEvent.ACTION_CANCEL:
             case MotionEvent.ACTION_UP:
                // User stopped dragging, or some other view
                //  has taken over the motion event 
                // Normally this is handled by onTouchEvent below, 
                // but it seems safest to also handle it here
                stopDragging(x);
                break;
          }
          // Whilst dragging, we return true in order to dispatch
          // the MotionEvent to our onTouchEvent method below.
          return mIsDragging;
       }
    
       @Override
       public boolean onTouchEvent(MotionEvent ev) {
          if (!mIsDragging) {
             // Not in dragging mode, so no action taken
             return super.onTouchEvent(ev);
          }    
    
          final int action = ev.getAction();
          float x = ev.getX();
    
          switch (action) {
    
             case MotionEvent.ACTION_MOVE:
                // Move the object.
                doDrag(x);
                // Call back to user
                callMoveCallback(x);
                break;
    
             case MotionEvent.ACTION_CANCEL:
             case MotionEvent.ACTION_UP:
                stopDragging(x);
                break;
           }
           return true;
       }
    
        ...
    }
    

    A basic user of this class could be an activity with the following layout:

    <com.example.dragndrop.DragLayer ...>
      <TextView android:text="A" ...>
      <TextView android:text="B" ...>
      <TextView android:text="C" ...>
    </com.example.dragndrop.DragLayer>
    

    When the user clicks on any of the TextView children, the activity would call startDragging which would let the user move the view around.

    As mentioned, the above is rough outline, just to illustrate the ideas of the basic machinery. That said, a more complete solution won't be much more complex.

    If you want to see an example of a more complete DragLayer in action you can check out our app Amusing Snippets. Its layout includes a tool bar, which is a DragLayer containing a list of icons. An icon in the tool bar can be moved around inside the tool bar after long pressing it.

  • Flipped Out Screen Orientation
    Board >> Blogs

    A funny thing about writing code for Android is that you keep bumping into things that you can't get to work, and at first you don't understand why. After some thought, however, you realize that it all makes sense, and you can't even understand why you thought it would work in the first place.

    Hey look, I've got Robo Defense in portrait mode! (Screen shot of my Nexus)

    One example of this is when I wanted an activity to have translucent background, just to make it look a bit cooler :) No problem, I just needed to change the theme of the activity to Theme.NoTitlebar.Translucent. Or so I thought.

    At some point later when testing on a device, I suddenly found that the activity no longer flipped screen orientation. It stayed locked in portrait mode no matter what I did. It just didn't make sense! How could changing the background opacity screw up the orientation?

    A general rule in Android, as far as I can tell, is:

    All visible activities must be displayed in the same orientation. Either all are in portrait or all are in landscape mode. If one flips, then all others must flip too.

    This rule makes perfect sense. I mean have you ever come across a window manager that would allow some windows in landscape mode and others in portrait? I haven't.

    So what that this have to do with my problem? Well the thing was, I was launching my activity on top of the Launcher home screen. The home screen is locked in portrait mode, by setting the screenOrientation in the manifest. Setting my activity to have a translucent background, meant that the home screen was still visible, hence also my activity got locked in portrait mode.

    In fact, the home screen being visible alone was not enough to lock the orientation. It's also that my activity didn't specifically state any preference for the screen orientation preference. What's more, The behavior when orientation is unspecified is not defined by Android. The documentation says:

    "unspecified" The default value. The system chooses the orientation. The policy it uses, and therefore the choices made in specific contexts, may differ from device to device.

    So the problem I had may well be hardware specific. Remember that next time you get bug reports about non-rotating screens, this post may well give the answer.

    A resolution of the problem would be to set the preferred screen orientation to sensor, but as I discuss below, this is probably not a very good solution in most cases.

    Flip side

    A funny thing about how this works is that it's the latest activity (the one highest up in the stack) that controls the orientation. It can force activities below it to whatever orientation it wants. This means that if you launch a completely transparent activity on top of another, you can override its orientation preference. It's not very useful, in fat one could even argue that it shouldn't be allowed to do this. In any case, it can be a fun trick to show off. Perhaps you are curious about how your favourite Android game would look in the 'other' orientation :)

    Conclusion

    The solution to set the screenOrientation to sensor in my activity was in fact not a very good solution. Why? Well it would force whatever activity was behind mine to also follow the sensor. When an activity changes orientation, the default action by the system is to destroy and recreate it. This will take a lot of time for some activities, in particular the home screen. So I would say that the sensor preference is only useful if you are sure that the background activity can change orientation quickly.

    My activity was the start activity, so I could not predict what its background could be. In the end, the only sensible solution in my case was to have an opaque background.

  • Static References == Memory leaks && onDestroy not called
    Board >> Blogs

    Java as we all know has garbage collection (GC) which means the programmer need not bother with explicitly deleting objects he/she creates. This is almost true, except that in order for GC to work the java engine has to see that there are no "live" references to the object.

    For Android applications and their activities and services this basically boils down to one rule:

    Don't keep static references to anything that is or refers to a Context.

    To be absolutely sure we follow the above rule, we may adopt an even simpler one: only have static references to simple objects such as strings and integers.

    Let's say you keep a static reference to an Activity, then you're not only preventing the memory it uses to be freed, you're also disrupting the "normal" life cycle of the activity. The activity can't be destroyed (i.e. onDestroy() won't be called) until all references to it are released.

    In fact, if you start seeing your Activity behaving strangely (for instance as described in this previous post about saving persistent state) then you may have a static reference to your Activity somewhere. Note that it may be an indirect reference, e.g. some database helper or other object which was created in the context of the Activity.

    Now if you want to get technical, you can also avoid the memory leaks by replacing your static references with corresponding weak references. If you're unfamiliar with them, here's a short refresher on weak references in Java. In the context of writing Android apps however it shouldn't be too difficult to avoid problematic static references altogether, weak or otherwise.

  • Backwards compatibility
    Board >> Blogs

    Ok, so finally time to take the bull by the horns (is that even an expression?). As I want my lovely apps full of all the latest stuff, but at the same time I don't want to deny all poor bastards with older android versions the pleasure of using said apps. Solution: eh, right. That's what I need to find out.

    In fact the reason I decided to do this now is that I ran across a bug that is unique to 2.1. So I need to do one thing on 2.1 and another on all other platforms. To do this, I would check: Build.VERSION.SDK_INT which would have the value 7 on android 2.1. But this constant wasn't introduced until release 1.6. There is a similar constant in earlier versions, but since it is deprecated (and a String) I'd prefer to use newer one.

    Method 1: Reflection

    The "official" documentation on the how to ensure backwards compatibility says that the simplest way is by using reflection. But the example they use is really quite big and complex. In my case, the absolute minimal way of solving the problem using reflection would be the following piece of code:

    int my_SDK_INT;
    try {
        // works for level 4 and up
        Field SDK_INT_field = Build.VERSION.class.getField("SDK_INT");
        my_SDK_INT = (Integer) SDK_INT_field.get(null);
    } catch (NoSuchFieldException e) {
        // Must be level 3 (since my app doesn't support lower levels)
        my_SDK_INT=3;
    }
    

    That is, instead of a direct reference to Build.VERSION.SDK_INT, which would cause a dreaded VerifyError exception, I use getField to check if it exists. This returns a Field object, or throws an exception if the field wasn't found. In my case, an exception would mean that SDK_INT is 3 since my Manifest contains:

    <uses-sdk android:minSdkVersion="3"/>
    

    the app won't install on prior versions. On level 4 and up, once we have our Field object, we can retrieve the value using the get) method. Since the field is static, we pass a null pointer as argument to this method. Had it been an object field, we'd have to pass in the object in question.

    The same technique can be used for methods that may be non existing. E.g. the following would handle the case where a static method "someMethod" may not exist:

    try {
        Method m=SomeClass.getMethod("someMethod");
        m.invoke(obj, args);
    } catch (NoSuchMethodException e) {
        // Some default action
    }
    

    So that is reflection, the quick and dirty way. Needless to say, it makes sense to put all the code using reflection into a separate file and class just to make it tidy.

    Method 2: Wrapper class

    If we're dealing with classes or packages that may be non-existant, or if we want to avoid the overhead introduced by 'invoke' and 'get' of reflection, we can turn to the second method (which actually is a bit simpler in my opinion): using wrapper classes.

    The idea is to place all references to methods, fields, and classes that may be non-existing, in separate wrapper classes. The upside to this is that in the wrapper class, we can write nice and efficient code without having to check anything. The downside is that loading the class may throw an exception. The class should implement some 'isAvailable' method that the user can call to know if it may be used. Example:

    class WrapperUser {
        boolean mWrapperOK=false;
        static {
            try {
                WrapperClass.isAvailable()
                mWrapperOK=True;
            } catch (Throwable e) {
            }
        }
        ...
    }
    
    class WrapperClass {
        public void isAvailable() throws Exception {
            if (Reflect.SDK_INT<3)
              throw new Exception();
        }
    }
    

    The documentation suggests to use Class.forName() ) in the isAvailable-method. But this doesn't seem to work reliably when I've tried it.

    Instead I prefer to use my_SDK_INT, that I wrapped so nicely above, in order to decide if a wrapper class is available or not. Obviously, this has its drawbacks, but at least it is reliable.

    Caveats

    Note that the wrapper class should not implement an interface which may not exist. Doing so seems to cause a dreaded VerifyError, even before the class is loaded, hence it is impossible to catch for a mere mortal application. The workaround is to introduce additional classes accessed only by the wrapper class, which in turn can implement the interfaces. I suspect that there are other similar issues with extending a potentially missing class.

  • When to save the state?
    Board >> Blogs

    An Android Activity roughly corresponds to one specific user interface. At any given time, there is only one activity with which the user interacts. An application often has several activities, one which is the main activity and from which the others are launched. An activity should typically be able to save its state so that it can be paused and late resumed.

    The android documentation gives a good overview of the activity life cycle. It is pretty much summed up by the below state diagram:

    This state diagram seems pretty straight forward to understand, but there is an important detail which is easily overlooked and needs to be emphasized:

    There is nothing that ensures that an instance of an activity is destroyed before another instance of the same activity is created.

    In other words, there is no guarantee that onDestroy() is called on an old instance prior to onCreate() is called on a new instance.

    Playing around with various android apps it is easy to be mislead into thinking that ther is such a guarantee. An activity is created when it is first launched. Then pauses when some other activity is launched on top of it, or the home button is used to switch to another app. When we return to a paused app, or back to a previous activity of the same app, it will be resumed as we left it. And when we exit an activity (e.g. pushing the back button) it will be destroyed.

    In the app I was writing, I wanted the user to always return to the same state regardless of whether the app had been paused and resumed, or it had been closed using the back button and then relaunched. Looking at the activity life cycle diagram above, it then seemed appropriate to save the state in onDestroy() and restore it again in onCreate(). That however was a mistake.

    While developing the app it worked fine to save the state in onDestroy(). But later when testing the app more thoroughly, the state wasn't always restored properly. It wasn't consistent either, sometimes it worked sometimes not depending on what other apps had been launched in between closing and relaunching. Using the debugger, the problem soon became clear: onDestroy() wasn't called when the app was closed, as expected. Instead a second instance of the main activity was created before the first instance could save its state.

    Update: The behavior shown below is not normal to Android. It was in fact due to a static reference to the activity that wasn't cleared, and which prevented the system from destroying the activity (see here for more details ). Once this reference was cleared, the activity was indeed destroyed as expected. This doesn't mean one should count on it, however, so it is still "wrong" to save the state in onDestroy.

    The problem can be illustrated by the following sequences. The first column is the expected sequence of events, the second column shows what actually happened.

    Expected Actual
    App launched
    inst1.onCreate() loads initial state
    App closed
    inst1.onPause()
    inst1.onDestroy() saves the state 1
    App launched
    inst2.onCreate() restores state 1
    App closed
    inst2.onPause()
    inst2.onDestroy() saves state 2
    App launched
    inst3.onCreate() restores state 2
    ...
    App launched
    inst1.onCreate() loads initial state
    App closed
    inst1.onPause()
    App launched
    inst2.onCreate() no state to restore
    inst1.onDestroy() saves the state 1
    App closed
    inst2.onPause()
    App launched
    inst3.onCreate() restores state 1
    inst2.onDestroy() saves state 2
    ...

    Looking at the two sequences, the it was quite clear how to fix it. The save of state should be done in onPause() instead. The following compares the sequence before and after the fix.

    Before Fix After Fix
    App launched
    inst1.onCreate() loads initial state
    App closed
    inst1.onPause()
    App launched
    inst2.onCreate() no state to restore
    inst1.onDestroy() saves the state 1
    App closed
    inst2.onPause()
    App launched
    inst3.onCreate() restores state 1
    inst2.onDestroy() saves state 2
    ...
    App launched
    inst1.onCreate() loads initial state
    App closed
    inst1.onPause() saves the state 1
    App launched
    inst2.onCreate() restores state 1
    inst1.onDestroy()
    App closed
    inst2.onPause() saves state 2
    App launched
    inst3.onCreate() restores state 2
    inst2.onDestroy()
    ...

    In hindsight this "fix" seems pretty obvious; all examples and tutorials suggest that saving of state should be done in onSaveInstanceState() which is always called immediately before onPause(). The reason this wasn't done in the first place was:

    1. The onSaveInstaceState() is meant for saving and restoring state in the case the instance is destroyed by the system, not if it is closed normally by the user.
    2. Saving state was potentially time consuming, so it seemed a bad idea to save state when just pausing. If the activity was later resumed without being destroyed, then the saved state would never be used.

    For efficiency, it would of course be better if one could save the sate, only when it is necessary. But on the other hand, with the current solution, an application is forced to keep the state simple so as to not need time to save. That seems like a good direction to go in anyway.

  • onCreate()
    Board >> Blogs
    The idea first formed a bleak September day when a green little figure with a floppy head first entered my conscience. The future was here, in this retro looking little humanoid. Backed by massive resources and computing clouds of Google, this little guy was intent on creating a permanent home in the palm of every gadget geeks' hand. And after that, the rest would be sure to follow, sooner or later. Android was here to stay, and its eventual world domination was inevitable. The idea I had was simply to start building fun and beautiful android apps, no more nor less.

    Getting a first app, [a simple entertainment app](Start/AmusingSnips), up and running was quite smooth thanks to all the docs tutorials at the [android developer site](http://developer.android.com/), and with some additional help from developers at [stack overflow](http://stackoverflow.com). Reading programming books is something I haven't done since I was in university. I learn by doing and Google:ing :)

    The [ADT Plugin for Eclipse](http://developer.android.com/intl/fr/sdk/eclipse-adt.html) was a definite pleasant encounter. It made it fast and easy to create the first activities and services, and bundle it all into an app. Debugging wasn't exactly painless, but still better than a lot of other systems I've seen.

    The first real difficulty was encountered just when we thought the app was ready for release. It all worked fine, first time it was launched. But after closing and relaunching, in which case it should load a saved state, the app sometimes failed. All very frustrating, since it seemed pretty much random, sometimes it worked sometimes not, and no one could understood why.

    To be continued...