Showing posts with label Android. Show all posts
Showing posts with label Android. Show all posts

Saturday, October 27, 2012

Show Dialog in Android After Device Boot Is Finished

What to do if you want to show an alert dialog right after the device boot is finished? You receive ACTION_BOOT_COMPLETED but you can't show an alert dialog from the broadcast receiver if you don't have any activities. Thus, what you need is to create one. But if you want your users to see only the dialog, your activity must be completely transparent.

1. Transparent activity style.
First, you need to create a transparent activity. Add this style to styles.xml:

Any activity that has this style as a theme will be transparent.

2. Activity with a simple dialog.
Now lets create an activity that will show a simple dialog:
public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("Message")
               .setTitle("Title")
               .setCancelable(false)
               .setPositiveButton("OK", new DialogInterface.OnClickListener()
               {
                   public void onClick(DialogInterface dialog, int id) 
                   {
                       MainActivity.this.finish();
                   }
               });
  
  
        AlertDialog alert = builder.create();
        alert.show();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}
3. Broadcast receiver.
Obviously you need a broadcast receiver that handles ACTION_BOOT_COMPLETED broadcast (note that you need a permission to receive the broadcast):
public class OnBootReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {  
        Intent startIntent = new Intent(context, MainActivity.class);
        startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(startIntent);
    }
}
4. Android manifest
In your manifest you must assign the created style for your activity and register the broadcast receiver. It should look something like this (note that you need a permission to receive the broadcast):


    
    

    
        
            
                

                
            
        
        
        
            
                
            
        
    


That's pretty much all you need to show a dialog after the device's boot is complete. Source code can be obtained from Github.

Monday, October 22, 2012

Get the APK's Code Size in Android

In the early version of my DELTA Statistics application for Android I collected code size of an installed application. When a lot of statistics about an installed application is easy to get, code size slightly more complicated.

 Step by step:
  1. Download IPackageStatsObserver.aidl and PackageStats.aild. You can get them from here.
  2. Create new package in your project and name it android.content.pm.
  3. Add IPackageStatsObserver.aidl and PackageStats.aild to the created package. You can do it by right-clicking on the package name and choosing Import option. Then select File System and click Next. Browse to the folder where you downloaded .aidl files, check the files you need and click Finish.
  4. Check that Eclipse automatically generated IPackageStatsObserver.java in gen.android.content.pm. Mine has some warning but trying to fix them is just a waist of time.
  5. Now we can get code size of application. In the example below I collect code size of all the installed applications. When I first wrote it I got a weird bug. Sometimes code size was 0 for the last N applications. N was different practically all the time, so, I though that it was a concurrency issue. As I understand, getPackageSizeInfo() method is invoked in another thread and because of that for loop can end before all the values of code size have been computed. To solve this problem I included a semaphore that is acquired at each loop iteration and is released after code size has been computed. It guarantees that getPackageSizeInfo() will finish before the next loop iteration will start.
    context = getApplicationContext();
    final PackageManager packageManager = context.getPackageManager();
    List<ApplicationInfo> installedApplications = 
        packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
    
    // Semaphore to handle concurrency
    final Semaphore codeSizeSemaphore = new Semaphore(1, true);
    
    // Code size will be here
    long codeSize = 0;
    
    for (ApplicationInfo appInfo : installedApplications)
    {
        try
        {
            codeSizeSemaphore.acquire();
        }
        catch (InterruptedException e)
        {
            e.printStackTrace(System.err);
        }
        
        // Collect some other statistics
        
        // Collect code size
        try 
        {
            Method getPackageSizeInfo = 
                packageManager.getClass().getMethod("getPackageSizeInfo", 
                                                    String.class,
                                                    IPackageStatsObserver.class);
            
            getPackageSizeInfo.invoke(packageManager, appInfo.packageName, 
                                      new IPackageStatsObserver.Stub()
            {
                // Examples in the Internet usually have this method as @Override.
                // I got an error with @Override. Perfectly works without it.
                public void onGetStatsCompleted(PackageStats pStats, boolean succeedded) 
                    throws    RemoteException
                {
                    codeSize = pStats.codeSize;
                    codeSizeSemaphore.release();
                }
            });
        }
        catch (Exception e)
        {
            e.printStackTrace(System.err);
        }
    }
    

Friday, September 28, 2012

DELTA Statistics

I really want to write about my new Android applications that collects statistics for my DELTA research project at the USF. It is my first serious experience with Android (before I worked more with JNI and native code) and especially with Beta testing. What I want to do is to cover some Android features that I used and also to talk about my application's design.

So, that what comes to mind:
  1. Alarms in Android (how to schedule alarms and do something when you receive them).
  2. Background services and WakeLocks.
  3. Alerts in Android.
  4. Text file handling (saving, etc.).
  5. Sending data with HTTP post request.
  6. Custom notifications.
  7. How to catch when device goes asleep (doesn't look very big but I am really exited about this because I did not find any information on in).
I think I will just divide everything in 8 posts (don't know how I will write all this...): these seven above and one about general design ideas I had in mind when I wrote the application.

Tuesday, September 4, 2012

Get Cause of Exception

Got a weird InvocationTargetException in Android. Why nobody told me to call getCause() method first and not to google it for half an hour? Happened to be a security violation (did not have a required permission) and a simple fix.