Wednesday, 24 July 2013

Drive Trace Android Application


http://ford.challengepost.com/submissions/16641-drive-trace-application?utm_campaign=ford-personalized-fuel-efficiency-app-challenge_20130325&utm_content=submission_visible_in_gallery&utm_medium=email&utm_source=transactional




Drive Trace application helps driver learn, compare and share information about his driving style and thereby help him to optimize the fuel usage. 

In on-drive mode, the application interacts with driver through Sync AppLink for trip creation or continuation and records per trip start and end location, fuel consumption, mileage and other details along with real-time vehicle data through OpenXC. It analyzes driving style through concrete algorithms and raises alerts on the go. Alerts can be enabled on configurable frequency to help driver unlearn the driving habits that lead to aggressive driving or over-idling. 

In off-drive mode, driver can view per trip details and effortlessly compare and analyze mileage, aggression & idling trends for selected trips. The application also supports managing trips and sharing of analysis graphs on e-mail, Bluetooth or on any social networking sites.

Tuesday, 16 July 2013

ADB Over WiFi.

ADB Over WiFi

Are you an Android developer ? If yes, you certainly use ADB (Android Debug Bridge) to do various things like:

  • Start a shell on the target device.
  • Install/Uninstall some packages/ apps.
  • Monitor the state of the device (memory used, cpu used etc.)
  • Push/Pull some files to/from the target device.
  • Debug Android applications.
Most developers connect their device to their computer using a USB cable and that sucks because:
  • It is not ergonomic.
  • It is ugly.
  • You probably need that cable to plug your device to an electric outlet while you are at work.
  • You may not have a USB cable at all!
Anyway, for those of you who want to connect to your device wirelessly using ADB, I have some good news for you: it is possible and it is easy.
First, let’s talk about how ADB works and then let’s dig into that very straightforward solution (or if you are busy just jump to the second paragraph).
How does ADB work?
ADB is a tool that includes three components:
  • A daemon: It is a background process hosted by the target device.
  • A client: It runs on your development machine. This is where you will be issuing your commands.
  • A server: It acts as a Proxy between the client and the daemon. It runs as a background process on machine.
As you can guess, there is a two way communication going on between the server and the daemon. That communication happens over a medium which can be of two sorts: USB or TCP. Aha, you get it know? If we want to connect to our device over wifi then we just have to switch the transport mode from USB to TCP. Let’s do that!
The solution: Switching ADB transport mode from USB to TCPIP
  1. Before switching to TCP, we’ll need to grab the IP address of the device. To do that, we can either go to the phone settings or use the command line tool netcfg
    view sourceprint?
    adb shell netcfg
  2. Once you are in possession of the device’s IP address (let’s say it’s: 192.168.65.150), you can switch to TCP mode by doing: 
    view sourceprint?
    adb tcpip
     One thing to remember is that you can only choose a port number within the range of [5555...5585] (the reason being that ADB Server only works with these ports). So for instance you could do: 
    view source
    print?
    adb tcpip 5555
  3. Stop ADB Server (we’ll restart it later by issuing any ADB command): 
    view sourceprint?
    adb kill-server
  4. Set ADBHOST to your IP address: 
    view sourceprint?
    ADBHOST=192.168.65.150 adb devices
  5. Make sure your device is connected
the last part of the last command should print the device that you are trying to connect to.
What to do if you don’t have a USB cable from the beginning? (rooting required)
If you don’t have a USB cable at first, then you need to root your device. (can void warranty)
Than run the following command on your device: 
      setprop service.adb.tcp.port 5555
Now you need to stop/restart the adb daemon: 
      stop adbd
      start adbd
How to switch back to USB transport mode? 
      adb usb
But there is one caveat
This only works since Android 4.0 (ICS). If you have to develop/hack on other Android versions then you need to root that device (in order to use ADB in unsecure mode).
That’s all folks, I hope that you are now using debug bridge over the air :)

Thursday, 20 June 2013

[Solved] - Nexus 7 Doesn't Show Up As Media Device (MTP)

Solution To Nexus 7 Doesn't Show Up As Media Device (MTP)

1.       Plug the Nexus 7 into your computer with the USB cable.
2.       Open Device Manager.
3.       Find "Android Device" near the top and expand the node. Double click on "Android Composite ADB Interface".
4.       In the properties window that pops up, uninstall the driver (chose to delete the current driver as well).

5.       Unplug the tablet and plug it back in.

Scaling images to given width and height with maintaining it's aspect ratio in android


Scaling images to given width and height with maintaining it's aspect ratio in android 


Following code can be used to scale images to given width and height with maintaining it's aspect ratio

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;

public class BitmapSizeHelper {

public static enum ScalingLogic {
CROP, FIT
}

public static Bitmap getBitmapFromResources(Resources res, int resId,
int dstWidth, int dstHeight, ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth,
options.outHeight, dstWidth, dstHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId,
options);

return unscaledBitmap;

}

public static Bitmap getBitmapFromPath(int targetW, int targetH,
String photopath, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {

Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(photopath, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth,
options.outHeight, dstWidth, dstHeight, scalingLogic);
Bitmap bitmap = BitmapFactory.decodeFile(photopath, options);

return bitmap;

}

public static int calculateSampleSize(int srcWidth, int srcHeight,
int dstWidth, int dstHeight, ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float) srcWidth / (float) srcHeight;
final float dstAspect = (float) dstWidth / (float) dstHeight;

if (srcAspect > dstAspect) {
return srcWidth / dstWidth;
} else {
return srcHeight / dstHeight;
}
} else {
final float srcAspect = (float) srcWidth / (float) srcHeight;
final float dstAspect = (float) dstWidth / (float) dstHeight;

if (srcAspect > dstAspect) {
return srcHeight / dstHeight;
} else {
return srcWidth / dstWidth;
}
}
}

public static Bitmap createScaledBitmap(Bitmap unscaledBitmap,
int dstWidth, int dstHeight, ScalingLogic scalingLogic) {
Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(),
unscaledBitmap.getHeight(), dstWidth, dstHeight, scalingLogic);
Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(),
unscaledBitmap.getHeight(), dstWidth, dstHeight, scalingLogic);
Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(),
dstRect.height(), Config.ARGB_8888);
Canvas canvas = new Canvas(scaledBitmap);
canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(
Paint.FILTER_BITMAP_FLAG));

return scaledBitmap;
}

public static Rect calculateSrcRect(int srcWidth, int srcHeight,
int dstWidth, int dstHeight, ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.CROP) {
final float srcAspect = (float) srcWidth / (float) srcHeight;
final float dstAspect = (float) dstWidth / (float) dstHeight;

if (srcAspect > dstAspect) {
final int srcRectWidth = (int) (srcHeight * dstAspect);
final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth,
srcHeight);
} else {
final int srcRectHeight = (int) (srcWidth / dstAspect);
final int scrRectTop = (int) (srcHeight - srcRectHeight) / 2;
return new Rect(0, scrRectTop, srcWidth, scrRectTop
+ srcRectHeight);
}
} else {
return new Rect(0, 0, srcWidth, srcHeight);
}
}

public static Rect calculateDstRect(int srcWidth, int srcHeight,
int dstWidth, int dstHeight, ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float) srcWidth / (float) srcHeight;
final float dstAspect = (float) dstWidth / (float) dstHeight;

if (srcAspect > dstAspect) {
return new Rect(0, 0, dstWidth, (int) (dstWidth / srcAspect));
} else {
return new Rect(0, 0, (int) (dstHeight * srcAspect), dstHeight);
}
} else {
return new Rect(0, 0, dstWidth, dstHeight);
}
}
}

Now we can use ablove code in two ways:

1.  If we have any image with any size and we want to show it completely inside a fixed size of imageview we can do it like:

                        Drawable drawable = Drawable.createFromPath(brandPrimaryImagePath);
if(null!= drawable){
Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
Bitmap scaledBitmap =  BitmapSizeHelper.createScaledBitmap(bitmap, x, y, BitmapSizeHelper.ScalingLogic.FIT);
                        }

where xy are the width and height of imageview respectively.


2. If we have any image with any size and we want to show it cropped inside a fixed size of imageview we can do it like:

                        Drawable drawable = Drawable.createFromPath(brandPrimaryImagePath);
if(null!= drawable){
Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
Bitmap scaledBitmap =  BitmapSizeHelper.createScaledBitmap(bitmap, xy, BitmapSizeHelper.ScalingLogic.CROP);
                        }

where xare the width and height of imageview respectively.

Friday, 24 May 2013

Adding New System Service in Android


To create a custom system service in android following steps are required

  1. Create service in framework
  2. Register service in SystemServer
  3. Create a .aidl interface of the service in framework
  4. Register .aidl interface in build system
  5. Create a manager for the service in framework
  6. Leverage the features of the service from service manager 
  7. Register the service manager in ContextImpl
  8. Register name of service manager in Context (abstract class)
After performing the above steps we need to build the new SDK for using the features of service through service manager.


1. Create service in framework

We need to create a service (Not an android service) in directory /frameworks/base/services/java/com/android/server/ where other system service are placed.

example code:

/*DemoService.java */
package com.android.server;
import android.content.Context;
import android.os.Handler;
import android.os.IDemoService;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.util.Log;

public class DemoService extends IDemoService.Stub {
    private static final String TAG = "DemoService";
    private DemoWorkerThread mWorker;
    private DemoWorkerHandler mHandler;
    private Context mContext;
    public DemoService(Context context) {
        super();
        mContext = context;
   mWorker = new DemoWorkerThread("DemoServiceWorker");
        mWorker.start();
        Log.i(TAG, "Spawned worker thread");
    }

    public void setData(int val) {
        Log.i(TAG, "setData " + val);
        Message msg = Message.obtain();
        msg.what = DemoWorkerHandler.MESSAGE_SET;
        msg.arg1 = val;
        mHandler.sendMessage(msg);
    }

    private class DemoWorkerThread extends Thread {
        public DemoWorkerThread(String name) {
            super(name);
        }
        public void run() {
            Looper.prepare();
            mHandler = new DemoWorkerHandler();
            Looper.loop();
        }
    }

    private class DemoWorkerHandler extends Handler {
        private static final int MESSAGE_SET = 0;
        @Override
        public void handleMessage(Message msg) {
            try {
                if (msg.what == MESSAGE_SET) {
          Log.i(TAG,"set message received:"+msg.arg1);
                }
            } catch (Exception e) {
               // Log, don't crash!
          Log.e(TAG, "Exception in handleMessage");
            }
        }
    }
}


2. Register service in SystemServer
We need to register our service in /frameworks/base/services/java/com/android/server/SystemServer.javawhere other system service are registered.
/*SystemService.java*/
/*
 * go to function "@Override public void run()"
 * ........
 * Add following block after line "if (factoryTest !=
 * SystemServer.FACTORY_TEST_LOW_LEVEL) {" 
 */

try {
    Slog.i(TAG, "Starting Demo Service");
    ServiceManager.addService("demo", new DemoService(context));
    Slog.i(TAG, "Demo Service Started");
} catch (Throwable e) {
    Slog.e(TAG, "Failure starting DemoService Service", e);
}




3. Create a .aidl interface of the service in framework
A service can expose set of functions that can be access by other process/application, by esposing them in .aidl file.
To expose the functions of our DemoService we need to declare them in .aidl file in any existing directory or any new directory in framework 
Note: The directory represent the package structure so if we want to add our service manager in any existing package we have to put our .aidl in that directory other wise our new directory.
(here we will be creating our .aidl in framework's existing directory for simplicity, as creating new directory in framework is little complex which we will discuss later)
So we need to create IDemoService.aidl in direcotry 

/*
 * aidl file :
 * frameworks/base/core/java/android/os/IDemoService.aidl
 * This file contains definitions of functions which are
 * exposed by service.
 */
package android.os;
/**{@hide}*/
interface IDemoService {
        void setData(int val);
}


4. Register .aidl interface in build system

We need to register our service's aidl interface in frameworks/base/Android.mk
Note: here we don't have to add entry of any aidl files for parcelables if we use any in our IDemoService.aidl.

/*
 * open frameworks/base/Android.mk and add line in red 
 * color mentioned below which contains location of
 * our .aidl file.
 */
...
core/java/android/os/IPowerManager.aidl \
core/java/android/os/IDemoService.aidl \
core/java/android/os/IRemoteCallback.aidl \
...


5. Create a manager for the service in framework
There are two approaches to create the  our service manager either singleton or a normal class.
Note: If we create a normal class if we use that class from application we will end up with multiple instances of our service manager (still those different instances will contain same static instance of our system service), And than to provide single instance of our service manager we need to register our service manager in /frameworks/base/core/java/android/app/ContextImpl.java and 
so to optimized and simple we will see with singleton

Below is the sample code for a Singleton manager class:  

/**
* /framework/base/core/java/android/os/DemoProxy.java
* It will be available in framework through import android.os.DemoProxy;
*/
import android.os.IBinder;
import android.os.IDemoService;
import android.os.RemoteException;
import android.util.Log;
/**
 * Use this Singleton class to call the functionality of DemoService
 * @author shridutt.kothari
 * It is a like a ServiceFetcher for the ContextImpl.
 */
public class DemoProxy {
     private static final String TAG = "DemoProxy";
     private final IDemoService mDemoService;
     private static DemoProxy demoProxy;
 
     /** Get a handle to the DemoService.
      * @return the DemoService, or null.
      */
     public static synchronized DemoProxy getDemoProxy() {
            if(DemoProxy == null) {
            IBinder binder = android.os.ServiceManager.getService("demo");
                    if(binder != null) {
     IDemoService managerService = IDemoService.Stub.asInterface(binder);
                            demoProxy = new DemoProxy(managerService);
                    } else {
                           Log.e(TAG, "DemoService binder is null");
                    }
            }
            return demoProxy;
     }
 
     /**
      * Use {@link #getDemoProxy} to get the demoProxy instance.
      */
     DemoProxy(IDemoService demoService) {
          if(demoService == null){
            throw new IllegalArgumentException("demo service is null");
          }
          mDemoService = demoService;
     }
     /**
      * Sets the value in demoService 
      * @param arg
      */
     public void setData(int arg){
         try{
            Log.d(TAG, "Going to call service from framework proxy");
            mDemoService.setData(arg);
            Log.d(TAG, "Service called successfully from framework proxy");
         } catch (Exception e) {
            Log.d(TAG, "FAILED to call service from framework proxy");
            e.printStackTrace();
         }
     }
     /**
     * Get the binder of IDemoService.
     */
     public IDemoService getDemoService(){
            mDemoService;
     }
     
}
Now 3rd party apps can call getDemoService().setData(); method.

6. Leverage the features of the service from service manager 
We see in above code snippet setData (int arg) method is to leverage the feature of our custom service, As we have called mDemoService.setData(arg); inside setData method of our service manager (i.e. DemoProxy)


7. Register the service manager in ContextImpl


Now applications will be able to get the instance of our service manager with the DemoProxy.getDemoProxy(); But if our service manager is not a singleton class we need to register it in ContextImpl so that applications can get instance of service manger like Context.getSystemService("service_name");

Now our service, aidl of service, service manager all things are created, so we need to write following code in /frameworks/base/core/java/android/app/ContextImpl.java file in the static block: 

/**
 * In /frameworks/base/core/java/android/app/ContextImpl.java
 * inside the static block we need to register our ServiceFetcher like this:
 */
registerService(DEMO_SERVICE , new ServiceFetcher() {
        public Object createService(ContextImpl ctx) {
        return DemoProxy.getDemoProxy(); 
/**
 * Or we can create new object of it, if DemoProxy is not a singleton class.
 * see other registered Services for example.
 */
}});


8. Register name of the our service manager in Context (abstract class)

Now we need to add entry of DEMO_SERVICE as a constant in file


/** inside /frameworks/base/core/java/android/content/Context.java. */
/**
 * Use with {@link #getSystemService} to retrieve a
 * {@link android.os.DemoProxy} for using DemoService
 *
 * @see #getSystemService
 * @hide
 */
 public static final String DEMO_SERVICE = "demo";

After all the above steps we just need to build our custom 
sdk and than, we can use the service manager in applications like:


DemoProxy dm= (DemoProxy) getApplicatioContext().getSystemService(Context.DEMO_SERVICE);