0

I am used to developing standalone applications, ones that you click on, it runs, and when you are done, you exit.

I am now interested in tackling a new type (not sure if that's the right word) of app, and was wondering how I should go about it. I am not sure what to research, and would appreciate your advice to help me get the ball rolling. I'll give you an idea about what I have in mind.

My app would need to perform a special action in the dialer. When the user dials a number and is in the middle of a call, I would like the user to be able to press the Menu key, and find an option to scroll through all their contacts (either the stock app, or my own list which I grab from the contacts stored in the phone), and select one. Upon selection, that contact's number is pasted into the dialer (keep in mind, in the middle of a call).

I certainly don't expect an answer telling me how to do this exactly, I just need some guidance as I have never written an app of this nature before. On top of that, is it even possible to do what I want to do?

Thank you.

capcom
  • 3,257
  • 12
  • 40
  • 50

3 Answers3

3

You need to go through Android Service or IntentService. A Service is an application component that can perform long-running operations in the background and does not provide a user interface(UI).

The following example is taken from android blog which is an implementation of the Service class

public class HelloService extends Service {
  private Looper mServiceLooper;
  private ServiceHandler mServiceHandler;

  // Handler that receives messages from the thread
  private final class ServiceHandler extends Handler {
      public ServiceHandler(Looper looper) {
          super(looper);
      }
      @Override
      public void handleMessage(Message msg) {
          // Normally we would do some work here, like download a file.
          // For our sample, we just sleep for 5 seconds.
          long endTime = System.currentTimeMillis() + 5*1000;
          while (System.currentTimeMillis() < endTime) {
              synchronized (this) {
                  try {
                      wait(endTime - System.currentTimeMillis());
                  } catch (Exception e) {
                  }
              }
          }
          // Stop the service using the startId, so that we don't stop
          // the service in the middle of handling another job
          stopSelf(msg.arg1);
      }
  }

  @Override
  public void onCreate() {
    // Start up the thread running the service.  Note that we create a
    // separate thread because the service normally runs in the process's
    // main thread, which we don't want to block.  We also make it
    // background priority so CPU-intensive work will not disrupt our UI.
    HandlerThread thread = new HandlerThread("ServiceStartArguments",
            Process.THREAD_PRIORITY_BACKGROUND);
    thread.start();

    // Get the HandlerThread's Looper and use it for our Handler 
    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
      Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();

      // For each start request, send a message to start a job and deliver the
      // start ID so we know which request we're stopping when we finish the job
      Message msg = mServiceHandler.obtainMessage();
      msg.arg1 = startId;
      mServiceHandler.sendMessage(msg);

      // If we get killed, after returning from here, restart
      return START_STICKY;
  }

  @Override
  public IBinder onBind(Intent intent) {
      // We don't provide binding, so return null
      return null;
  }

  @Override
  public void onDestroy() {
    Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); 
  }
}

On the other hand, The same thing can be achieved using IntentService, which is a base class for Services that handle asynchronous requests on demand.

public class HelloIntentService extends IntentService {

  /** 
   * A constructor is required, and must call the super IntentService(String)
   * constructor with a name for the worker thread.
   */
  public HelloIntentService() {
      super("HelloIntentService");
  }

  /**
   * The IntentService calls this method from the default worker thread with
   * the intent that started the service. When this method returns, IntentService
   * stops the service, as appropriate.
   */
  @Override
  protected void onHandleIntent(Intent intent) {
      // Normally we would do some work here, like download a file.
      // For our sample, we just sleep for 5 seconds.
      long endTime = System.currentTimeMillis() + 5*1000;
      while (System.currentTimeMillis() < endTime) {
          synchronized (this) {
              try {
                  wait(endTime - System.currentTimeMillis());
              } catch (Exception e) {
              }
          }
      }
  }
}

You can also go through SO post https://stackoverflow.com/a/4353653/432903

Community
  • 1
  • 1
prayagupa
  • 30,204
  • 14
  • 155
  • 192
2

If your app isn't mainly written in javascript/webview/phonegap, then all you have to do is look at the Service class. That class and the linked documents tell you everything you need to know.

jettero
  • 835
  • 2
  • 13
  • 26
  • Thanks I'll look into it! I plan to write it in Java. Never even heard of webview and phonegap, but they seem interesting. – capcom Aug 21 '12 at 03:08
  • @jettero : So how, if the user is in the middle of a call, is a `Service` going to intercept the `MENU` button? – Squonk Aug 21 '12 at 03:13
  • @Squonk Well I don't need it to intercept the Menu button. I was saying that on the menu button press, in addition to options like enabling/disabling speakerphone, putting the call on mute, stuff like that, is an option to choose a number from a list, and paste it into the dialer. – capcom Aug 21 '12 at 03:21
  • @capcom : My point is that the stock / built-in functionality of Android uses the standard application components (plus underlying native code). In other words, you can't re-write how the built-in phone app works in order to add an extra menu option. – Squonk Aug 21 '12 at 03:36
  • @Squonk I see. Well, is it possible then to create an app which would be activated based on a certain incoming call? Say the number 123456789 is calling, my app will pick up the call instead? I need some way to get a custom number into the dialer pad in the middle of a call, that's all. The custom number could even be saved to the clipboard or something. Thanks. – capcom Aug 21 '12 at 11:43
  • @capcom : You can create a `BroadcastReceiver` which 'listens' for the `TelephonyManager` intent action `ACTION_PHONE_STATE_CHANGED`. If the call state has changed to 'ringing' then the `Intent` contains extra data with the calling phone number. – Squonk Aug 21 '12 at 20:29
1

maybe you can use an IntentFilter so you can get a system notify when the user uses a dialer. and you should learn the Service component which can work in background in android.

TaoZang
  • 1,690
  • 2
  • 15
  • 15