Sunday, September 22, 2013

Pending Intent

https://allaudin.github.io/pending-intent/- A good reference

A PendingIntent is a token that you give to another application (e.g. Notification Manager, Alarm Manager or other 3rd party applications), which allows this other application to use the permissions of your application to execute a predefined piece of code.

For Example, if we want to start our Service(which requires some special  permission like gps, action battery change etc), through AlarmManager which will trigger that service some-point in future at regular interval.
Then we create a pending intent for our service and we give this intent to other application viz. in this case is AlarmManager Now AlarmManager will use the permission(gps, vibrate, etc) of our service to execute code.
Intent intent = new Intent(this, MyService.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 234324243, intent, 0);
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
        + (i * 1000), pendingIntent);
If you give the foreign application an Intent, and that application sends/broadcasts the Intent you gave, they will execute the Intent with their own permissions. But if you instead give the foreign application a PendingIntent you created using your own permission, that application will execute the contained Intent using your application's permission.
A PendingIntent has defined Activity, Broadcast or Service  within it, and those can be sent to other applications to use it.
I can define my Intent (Activity, BroadcastReceiver or Service) and can send to other application to use it. 

Why PendingIntent is required ?

If I create Intent,
Intent bIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

and sending "bIntent" to other application , which is not having permission (android.permission.BLUETOOTH_ADMIN).

So, When I do, 
startActivity(bIntent);

It will never launch bluetooth enabling Activity.

If we use PendingIntent, the application (which use PendingIntent) no need to have permission. But the application which creates PendingIntent must have required permission for Intents.

PendingIntent can be created using it's static methods getActivity(), getBroadcast() and getService().

Let's see sample for PendingIntent,

public class IParcel implements Parcelable
{

    PendingIntent pIntent = null;
   
    public IParcel(PendingIntent pi)
    {
        pIntent = pi;
    }
   
    public IParcel(Parcel in)
    {
        pIntent = (PendingIntent)in.readValue(null);
    }
   
    public static Parcelable.Creator<IParcel> CREATOR = new Parcelable.Creator<IParcel>(){

        @Override
        public IParcel createFromParcel(Parcel source) {
            // TODO Auto-generated method stub
            return new IParcel(source);
        }

        @Override
        public IParcel[] newArray(int size) {
            // TODO Auto-generated method stub
            return null;
        }
       
    };
  
    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // TODO Auto-generated method stub
        dest.writeValue(pIntent);
       
    }
   
}

public class FirstApp extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
    
        Intent myIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        PendingIntent pIntent = PendingIntent.getActivity(this, 0, myIntent,PendingIntent.FLAG_ONE_SHOT);//FLAG_ONE_SHOT - only once pIntent can use the myIntent
     
        IParcel ip = new IParcel(pIntent);
    
        Intent sndApp = new Intent();
        sndApp.setComponent(new ComponentName("com.myapp", "com.myapp.SecondApp"));
        sndApp.putExtra("obj",ip);
        startActivity(sndApp);
        }

}

public class SecondApp extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

       IParcel pc = getIntent().getExtras().getParcelable("obj");
       if(pc != null){
               pc.pIntent.send(); // this will launch the bluetooth enabling activity
       } 
       }
}

Sunday, August 4, 2013

Abstract vs interface

  1. An abstract class is good if you think you will plan on using inheritance since it provides a common base class implementation(common methods shared between subclasses) to derived classes.
  2. An abstract class is also good if you want to be able to declare non-public members. In an interface, all methods must be public.
  3. If you think you will need to add methods in the future, then an abstract class is a better choice. Because if you add new method headings to an interface, then all of the classes that already implement that interface will have to be changed to implement the new methods. That can be quite a hassle.
  4. Interfaces are a good choice when you think that the API will not change for a while.
  5. Interfaces are also good when you want to have something similar to multiple inheritance, since you can implement multiple interfaces.

Thursday, July 18, 2013

Coordinating activities

When one activity starts another, they both experience lifecycle transitions. The first activity pauses and stops (though, it won't stop if it's still visible in the background), while the other activity is created. In case these activities share data saved to disc or elsewhere, it's important to understand that the first activity is not completely stopped before the second one is created. Rather, the process of starting the second one overlaps with the process of stopping the first one.
The order of lifecycle callbacks is well defined, particularly when the two activities are in the same process and one is starting the other. Here's the order of operations that occur when Activity A starts Acivity B:
  1. Activity A's onPause() method executes.
  2. Activity B's onCreate()onStart(), and onResume() methods execute in sequence. (Activity B now has user focus.)
  3. Then, if Activity A is no longer visible on screen, its onStop() method executes.
This predictable sequence of lifecycle callbacks allows you to manage the transition of information from one activity to another. For example, if you must write to a database when the first activity stops so that the following activity can read it, then you should write to the database during onPause() instead of duringonStop().