Posts

Android - UnsupportedOperationException: Cant convert to color: type=0x2

 You are most likely trying to reference a styleable attribute of reference type in a drawable resource and it bailed out with an UnsupportedOperationException.    <shape android:shape="rectangle">         <solid android:color="?attr/item_background" />     </shape> Sadly this is the case with pre-lollipop android versions. There isn't any way to reference attributes in a drawable resource. This works just fine in Lollipop though and is tracked here . The only other alternative is to have a hard coded color specific drawable resource for older platform versions. /drawable/red_rectangle.xml    <shape android:shape="rectangle">         <solid android:color="@android:color/red" />     </shape> /drawable/orange_rectangle.xml    <shape android:shape="rectangle">         <solid android:color="@android:color/orang...

Android - negative x and y in onTouchEvent

    Android's handling of touch event recommends to use getX() and getY() when trying to determine the coordinates with respect to the actual view that is being touched. This makes sense for most use cases and developers might expect positive values starting from 0,0 to width-1,height-1.    However, there are cases when getX() and getY() would return negative values and values greater than the actual view dimensions. The reason is due to padding added to the view. Padding unlike margin is internal to the view. Clicking on the padded space before the start of the view dimensions would result in a negative values. The best solution is just to check for the touch coordinates to be within the view boundary and then handle appropriately.

Android - Chrome browser tabs as separate tasks in Recent Apps Overview

    Chrome browser for Lollipop and above introduced a nice feature to show tabs as separate tasks in Recent Apps Overview. Users can turn off this feature via settings. For some reason, this was only supported from Lollipop and not for older versions of Android. This is most likely due to SDK APIs introduced in API level 21, ActivityManager.AppTask . This is meant for applications wanting to manage tasks in recent apps overview. Applications can determine how and when activities appear in the overview screen. Chrome browser is most likely using these APIs restricting the feature to Lollipop and above.    Besides, Chrome also has the ability to resume the last used task when users launch the browser via launcher's shortcut. In a typical android application, android's launcher shortcut would always fire a specific intent resolving to the main activity of the application. In case of Chrome, this action is mapped to launch the last used tab and not the first tab. How...

Android - Tinting RippleDrawables

     Android starting from Lollipop provided ability to tint UI elements for better user feedback. Pressing and holding a button starts a tint animation which is stopped as soon as the user lets go of the button. This is done by handling the touch event and using appropriate drawable resources to redraw the button. Besides, the tint animation is pivoted at the touch coordinates known as a hot spot. Lollipop by default supports tint animations for all applications and the SDK offers API to customize the color. This would be needed for applications which have a custom color for the UI elements and the platform's tint color doesn't necessarily work with the app custom color. Besides, new versions of support library even offers compat versions to apply tint colors.    DrawableCompat offers a setTintList API to apply tint colors based on various states of the drawable resource. This is usually applicable for stateful drawables ( Drawable.isStateful ).   ...

Android - Could not read input channel file descriptors from parcel

     This is one crazy runtime failure that doesn't really give any straight forward hint to application developers. The stack trace is usually related to android's internal classes with the top of the frame failing in InputChannel. java.lang.RuntimeException: Could not read input channel file descriptors from parcel.        at android.view.InputChannel.nativeReadFromParcel(InputChannel.java)        at android.view.InputChannel.readFromParcel(InputChannel.java:148)        at android.view.InputChannel$1.createFromParcel(InputChannel.java:39)        at android.view.InputChannel$1.createFromParcel(InputChannel.java:36)        at com.android.internal.view.InputBindResult.<init>(InputBindResult.java:62)        at com.android.internal.view.InputBindResult$1.createFromParcel(InputBindResult.java:102)        at com.android.int...

Android - Marshmallow Now on Tap

Image
   One of the fascinating features of Marshmallow was Now on Tap. It crawls through the screen content and displays relevant information.     The trigger event is to long press the home button for few seconds. This kind of suggests that some kind of intent is being fired and is being handled by a background application launching the relevant UI. However, an intent design can be hijacked by third party applications and might be confusing for users expecting Now on Tap. In fact, firefox managed to trap the launch intent for Google Now cards in earlier versions of Android. Based on the logs, this seems to be some kind of platform level core changes and surprisingly is coupled with speech and audio inputs. It looks like the touch event is being routed as audio inputs. This feature was either designed with speech input as a trigger event or speech input is further down the line. MicrophoneInputStream: mic_starting com.google.android.apps.gsa.speech.audio.y@4799...

Android - Marshmallow WifiInfo's getMacAddress()

Image
     Android Marshmallow changed the behavior for WifiInfo's getMacAddress() due to privacy concerns. The API wasn't removed or deprecated instead was just updated to return a default address 02:00:00:00:00:00. The intention is to block access to device's hardware identifier using WiFi and Bluetooth APIs. In addition, any background wifi or bluetooth scan is shown as being generated by random mac address starting from Android 6.0. This doesn't let tracking softwares like the ones used in coffee shops, malls do what they used to do, study customer behavior without their knowledge, just because they had their wifi or bluetooth turned on by default. This is similar to what Apple did to iOS8. In Android 6.0, there are still few apps like Settings which continue to have access to the mac address. This is accessed via Settings > About Phone > Status or via Settings > WiFi > Advanced.      Is there any other hidden API that might return the...

Android - Preventing screen capture and secure windows

   Android has an API FLAG_SECURE to prevent the window contents to be captured. This can be applied to any kind of window controlled by the application and an application could have multiple windows shown simultaneously (each on top of the other). This begs a question as to what happens when FLAG_SECURE is requested only for one of the window and not for dialog windows or vice versa. An application like Netflix might want to enforce security just for playback window and not a dialog showing options etc.    What happens if the dialog window is in focus? The fact that FLAG_SECURE is associated with a window seems that one could probably skip the check when a non secure window (Dialog) is in focus. This is a concern for application developers. Turns out this is not possible and any attempt to capture would fail (irrespective of the security of the focus window). This is because the framework checks for all windows of the current display and bails out when even on...

Android - Keyline Pushing's Grid on top of other applications

Image
    Keyline pushing displays a Grid on top of other applications for UI testing. This is really useful for designers working with material design. The approach of displaying content on top of other applications and yet be able to control the actual application (behind the grid) is cool.      Users can notice a notification. This is most likely a result of a foreground service started by the application. This makes sense as the Grid has to stay alive even when the application is backgrounded and other applications are in focus. The actual grid is shown on a separate window most likely using public API, TYPE_SYSTEM_ALERT, TYPE_SYSTEM_OVERLAY, TYPE_SYSTEM_DIALOG or TYPE_SYSTEM_ERROR. This is why the app has a permission request claiming that it can draw on top of other applications. The next question is as to how the touch events are actually relayed to the foreground application underneath the grid? The grid is some kind of custom view or bitmap hosted b...

Android - Permissions for multiprocess

Image
Android's multiprocess is used to indicate if a component can be hosted in the process space of the application requesting the component. The documentation claims that a request isn't necessarily honored at all times and works only with some permissions.    This is usually requested by application developers willing to have their component execute in other application's process space. This presents a security concern, a third party application without the knowledge of multiprocess could request for a component like starting an activity. The target activity would be created and resumed in the context of the calling process space and ends up having access to memory etc. Android's framework has a permission model to deal with this security concern but sadly isn't well documented. The intention is perhaps to demotivate application developers from using this feature.   The permissions model and this feature is similar to android:process documented here . andro...

Android - Couldn't capture screenshot

Image
   Screen capture of quite a few android applications after updates have started failing. Attempts to use developer tools like ddms, Android Studio too doesn't help. On device screen capture ( power + volume down ) fails claiming either limited storage space or denial by the app or organization. This is noticeable in Netflix. Screen capture works fine in all sections of the app but fails only in the playback view. This kind of rules out limited storage or device specific issues. Netflix has some explicit logic to disable screen capture during playback which makes sense as they probably want to protect their content. This is even more applicable for applications like Snapchat where in the message is destroyed and users shouldn't be able to capture the screen contents.    So how does this work? Turns out, Android has a public API FLAG_SECURE for windows. Application developers can request for the window to be secure upon activity creation. protected void...

Android - Google Drive like Page Indicators

Image
    The recent updates to Google apps in Android have a brand logo along with an intro pages. These highlight the features across pages. Like many view pager implementations, it has a page indicators. The indicators are highlighted based on the current focus page. Android doesn't offer an out of box PageIndicator API to work with ViewPagers. Google drive (2.3.357.23.34) uses a set of images hosted under a LinearLayout for page indicators.    One way to achieve this is by having a custom linear layout add a number of child ImageViews based on the number of pages returned by the ViewPager's adapter getCount(). This has to be updated any time the adapter is invalidated or a data set change is requested. Besides, the custom linear layout has a register for an OnPageChangeListener to get the index of the active page and set an appropriate image resource for active and inactive page indicators.

Android - Device Default theme and styles

    Android's approach to Device specific default themes and styles makes life easy for application developers targeting API level 14 and above. Android's style customization offers OEM to have their own look and feel. This was done by adding a new theme, DeviceDefault starting from Android 4.0 API (level 14). This theme is what enables OEMs to have their own native look and feel. An OEM wanting to have their own progress bar styles across the device can do so. Google’s Nexus devices uses unmodified Holo themes as the device default theme.     This new theme helps developers to target the device’s native theme with all OEM customizations intact without having to develop OEM specific application etc. Application developers can override these device default styles for their own requirements.  <style name="AppProgressBarStyle" parent="@android:style/Widget.DeviceDefault.ProgressBar">     ...     ...     ...  </st...

Android - Derived Style adding on to Parent style's value

   Android's style framework offers ability to override values defined by a parent style. In fact, it even lets the child style to completely remove the definition of an property from the parent's style . But there are cases when the child style would just want to add on to the values defined in the parent style. The requirement is equivalent to something like the following in a programming language like Java,  public class Parent {      public int getValue() {          return 5;      } }  public class Child extends Parent {      public int getValue() {          return 2 + super.getValue();      } }     Child class's logic is able to use the Parent class's value and return an appropriate one. Unfortunately, android's xml scheme for styles doesn't support this. The only other workaround is to extract the parent style's property value...

Android - Delete a style attribute from a parent style

   Android's style framework is quite powerful and offers different customization options without having to change the source code. Developers could just extend base style and override existing attributes or provide new ones.   A custom style based on TextAppearance.StatusBar.EventContent.Title might want to change the text style,     <style name="TextAppearance.StatusBar.EventContent.Title">         <item name="textColor">#ffffff</item>         <item name="fontFamily">sans-serif-light</item>         <item name="textSize">@dimen/notification_title_text_size</item>         <item name="textStyle">bold</item>     </style>     <style name="TextAppearance.StatusBar.EventContent.Title. Italic ">         <item name="textStyle"> italic </item>     <...

Android - Netflix like Pause video on Status Bar Expansion

Image
      Netflix app for Android (Official and Kindle Fire) has a feature to pause the video playback when the status bar is expanded. Different apps including non-media apps would like to know as to when the status bar is expanded or collapsed. One approach is to constantly poll for this but being notified is the best possible approach. Unfortunately, Android SDK doesn't offer any API to register a callback for status bar event updates. So how is Netflix notified of status bar updates?      One possibility is for the application to listen for window focus events. In Android world, each and every Activity has a corresponding window. This is why Activity has a callback,  onWindowFocusChanged . The callback is passed a boolean to indicate focus gain or loss. Netflix most likely is listening for this event on the window corresponding to the playback. public void onWindowFocusChanged( boolean hasFocus) { if ( hasFocus ) { resumePlayback(); ...

Android - getButtonDrawable for CompoundButton

   Android UI Toolkit's widgets often have helper methods to get the values that are or have been set via xml or runtime code etc. ImageButton has helper APIs to set and get drawable via setImageDrawable and getDrawable. This facilitates run time updates to previously set drawable and could be done via Canvas and Paint. Few applications might want to redraw the image like adding blur effects based on some run time conditions. Unfortunately, the ability to extract previously set drawable resource isn't available across all widgets. CompoundButton is one such widget which has a setButtonDrawable but has a getButtonDrawable only from API level 23.    Application developers targeting previous android versions had to workaround by hand picking platform default resources into their application project and keeping a reference of the drawable for further updates. This wouldn't always work especially when OEMs decide to change the default images for the CompoundButton li...

Android - Activity Persistency across reboots

     Android's approach to memory management required an ability to save application state as and when user pauses the application. In some cases, the state can't be truly restored like a persistent socket connection. The connection is lost upon a kill of the backgrounded application by low memory killer. Few applications request persistency via Manifest ( android:persistent ) but this works only for system applications and not third party applications.     So third party applications have been limited via onSaveInstance and onRestoreInstanceState callbacks in Activity, Fragments etc. They would need to book keep if they had any active socket connections and restore them once they are hosted in a new process. This restore worked only as long as the device wasn't rebooted. The saved data was stored in-memory and didn't offer any way to restore after a device reboot. This had been the case for quite a few Android versions until recently where in the saved data ...

Android - Detect Application Update via Play Store

     Android application developers would in some cases want a logic to be executed every time the application is updated via Play store or even when a new version is side loaded. In some cases, the logic needs to be executed only on upgrades and not when the user downgrades the application for different reasons.      Unfortunately, Android SDK doesn't offer an API to detect application updates. However, Android guarantees that the application specific user data wouldn't be erased. This is what lets user login work even after the application is upgraded. Few data is stored in Shared Preferences and this too wouldn't be deleted upon an update.    Developers can just keep track of the application version in the Shared Preference and query the same on application start up to check if the current version is same as the last known book kept version. If not, it would be a new version. This can be used to even detect an upgrade or downgrade. ...

Android - HBO Now like Content Subscription

Image
 Few apps like HBO Now have started offering subscriptions via Play store and this approach when used by content distributors help manage active subscriptions with ease.  This can be enabled via Play Developer Subscriptions API . A SubscriptionPurchase resource indicates the status of a user's subscription purchase. {   "kind": "androidpublisher#subscriptionPurchase",   "startTimeMillis": long,   "expiryTimeMillis": long,   "autoRenewing": boolean }