2012年11月21日 星期三

ADT Updates Problem

When Updating ADT in Eclipse, I get the problem.

At last I found that it is due to admin right program in Windows 7.  I need to run Eclipse as administrator in order to successfully upgated ADT in Eclipse.

Check Time for the program


 long count = System.currentTimeMillis();
   :
   : // Your code to measure time
   :
count = System.currentTimeMillis() - count;
Log.d("Graph draw","Time (ms): " + count);

2012年11月12日 星期一

Android Buld-in Content Providers

http://developer.android.com/reference/android/provider/package-summary.html

Here are a few of the providers listed on that documentation page:
Browser
CallLog
Contacts
  People
  Phones
  Photos
  Groups
MediaStore
  Audio
    Albums
    Artists
    Genres
    Playlists
  Images
    Thumbnails
  Video
Settings

Android Resources Directory

/res/values/strings.xml
                 /colors.xml
                 /dimens.xml
                 /attrs.xml
                 /styles.xml
/drawable/*.png
                /*.jpg
                /*.gif
                /*.9.png
/anim/*.xml
/layout/*.xml
/raw/*.*
/xml/*.xml
/assets/*.*/*.*

􀀁 mccAAA: AAA is the mobile country code
􀀁 mncAAA: AAA is the carrier/network code
􀀁 en-rUS: Language and region
􀀁 small, normal, large, xlarge: Screen size
􀀁 long, notlong: Screen type
􀀁 port, land: Portrait or landscape
􀀁 car, desk: Type of docking
􀀁 night, notnight: Night or day
􀀁 ldpi, mdpi, hdpi, xhdpi, nodpi: Screen density
􀀁 notouch, stylus, finger: What kind of screen
􀀁 keysexposed, keyssoft, keyshidden: What kind of keyboard
􀀁 nokeys, qwerty, 12key: How many keys
􀀁 navexposed, navhidden: Navigation keys hidden or exposed
􀀁 nonav, dpad, trackball, wheel: The type of navigation device
􀀁 v3, v4, v7: API level

\res\layout
\res\layout-port
\res\layout-land
\res\layout-en
\res\layout-mcc312-mnc222-en-rUS
\res\layout-ldpi
\res\layout-hdpi
\res\layout-car

Android Assets

Android offers one more directory where you can keep files to be included in the package: /assets. It’s at the same level as /res, meaning it’s not part of the /res subdirectories. The files in /assets do not generate IDs in R.java; you must specify the file path to read them. The file path is a relative path starting at /assets.

String getStringFromAssetFile(Activity activity) {
 AssetManager am = activity.getAssets();
 InputStream is = am.open("test.txt");
 String s = convertStreamToString(is);
 is.close();
 return s;
}

Android Resources - RAW

Android also allows raw files in addition to arbitrary XML files. These raw resources, placed in /res/raw, are raw file resources such as audio, video, or text files that require localization or references through resource IDs.

String getStringFromRawFile(Activity activity)
throws IOException {
 Resources r = activity.getResources();
 InputStream is = r.openRawResource(R.raw.test);
 String myText = convertStreamToString(is);
 is.close();
 return myText;
}
String convertStreamToString(InputStream is)
throws IOException {
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 int i = is.read();
 while (i != -1) {
  baos.write(i);
  i = is.read();
 }
 return baos.toString()
}

Android Resources - Arbitrary XML

Android allows arbitrary XML files as resources.

XML files that need to be read in this fashion are stored under the /res/xml subdirectory.

<rootelem1>
<subelem1>
Hello World from an xml sub element
</subelem1>
</rootelem1>

Resources res = activity.getResources();
XmlResourceParser xpp = res.getXml(R.xml.test);

private String getEventsFromAnXMLFile(Activity activity)
throws XmlPullParserException, IOException {
 StringBuffer sb = new StringBuffer();
 Resources res = activity.getResources();
 XmlResourceParser xpp = res.getXml(R.xml.test);
 xpp.next();
 int eventType = xpp.getEventType();
 while (eventType != XmlPullParser.END_DOCUMENT) {
  if(eventType == XmlPullParser.START_DOCUMENT) {
   sb.append("******Start document");
  }
  else if(eventType == XmlPullParser.START_TAG) {
   sb.append("\nStart tag "+xpp.getName());
  }
  else if(eventType == XmlPullParser.END_TAG) {
   sb.append("\nEnd tag "+xpp.getName());
  }
  else if(eventType == XmlPullParser.TEXT) {
   sb.append("\nText "+xpp.getText());
  }
  eventType = xpp.next();
 }//eof-while
 sb.append("\n******End document");
 return sb.toString();
}//eof-function

Android Resources - Color-Drawable

In Android, an image is one type of a drawable resource. Android supports another drawable resource called a color-drawable resource; it’s essentially a colored rectangle.

<resources>
<drawable name="red_rectangle">#f00</drawable>
<drawable name="blue_rectangle">#0000ff</drawable>
<drawable name="green_rectangle">#f0f0</drawable>
</resources>

// Get a drawable
ColorDrawable redDrawable = (ColorDrawable)
               activity.getResources().getDrawable(R.drawable.red_rectangle);
//Set it as a background to a text view
textView.setBackgroundDrawable(redDrawable);

<TextView android:layout_width="fill_parent"
                   android:layout_height="wrap_content"
                   android:textAlign="center"
                   android:background="@drawable/red_rectangle"/>

To achieve the rounded corners in your Drawable, you can use the currently undocumented <shape> tag. However, this tag needs to reside in a file by itself in the /res/drawable directory.

<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#f0600000"/>
<stroke android:width="3dp" color="#ffff8080"/>
<corners android:radius="13dp" />
<padding android:left="10dp" android:top="10dp"
android:right="10dp" android:bottom="10dp" />
</shape>

// Get a drawable
GradientDrawable roundedRectangle = (GradientDrawable)
                activity.getResources().getDrawable(R.drawable.my_rounded_rectangle);

//Set it as a background to a text view
textView.setBackgroundDrawable(roundedRectangle);

Android Resources - Dimension

px: Pixels
in: Inches
mm: Millimeters
pt: Points
dp: Density-independent pixels based on a 160-dpi (pixel density per inch) screen (dimensions adjust to screen density)
sp: Scale-independent pixels (dimensions that allow for user sizing; helpful for use in fonts)


<resources>
<dimen name="mysize_in_pixels">1px</dimen>
<dimen name="mysize_in_dp">5dp</dimen>
<dimen name="medium_size">100sp</dimen>
</resources>

Android Resources - Color

#RGB
#ARGB
#RRGGBB
#AARRGGBB


<resources>
<color name="red">#f00</color>
<color name="blue">#0000ff</color>
<color name="green">#f0f0</color>
<color name="main_back_ground_color">#ffffff00</color>
</resources>


http://code.google.com/android/reference/android/R.color.html

Android Resources - plurals

<resources…>
<plurals name="eggs_in_a_nest">
<item quantity="one">There is 1 egg</item>
<item quantity="other">There are %d eggs</item>
</plurals>
</resources>

Resources res = my_activity.getResources();
String s1 = res.getQuantityString(R.plurals.eggs_in_a_nest, 0,0);
String s2 = res.getQuantityString(R.plurals.eggs_in_a_nest, 1,1);
String s3 = res.getQuantityString(R.plurals.eggs_in_a_nest, 2,2);
String s4 = res.getQuantityString(R.plurals.eggs_in_a_nest, 10,10);

Android Application Lifecycle

protected void onCreate(Bundle savedInstanceState);
protected void onStart();
protected void onRestart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestroy();

Android Fundamental Components

View
Views are user interface (UI) elements that form the basic building blocks of a user interface. A view could be a button, label, text field, or many other UI elements.  Views are also used as containers for views, which means that there's usually a hierarchy of views in the UI. In the end, everything you see is a view.

Activity
An activity is a user interface concept. An activity usually represents a single screen in your application. It generally contains one or more views, but it doesn’t have to. An activity is pretty much like it sounds—something that helps the user do one thing—and that one thing could be viewing data, creating data, or editing data. Most Android applications have several activities within them.

Intent
An intent generically defines an “intention” to do some work. Intents encapsulate several concepts, so the best approach to understanding them is to see examples of their use.

You can use intents to perform the following tasks:
􀀁 Broadcast a message.
􀀁 Start a service.
􀀁 Launch an activity.
􀀁 Display a web page or a list of contacts.
􀀁 Dial a phone number or answer a phone call.
Intents are not always initiated by your application—they’re also used by the system to notify your application of specific events (such as the arrival of a text message).

Intents can be explicit or implicit. If you simply say that you want to display a URL, the system will decide what component will fulfill the intention. You can also provide specific information about what should handle the intention. Intents loosely couple the action and action handler.

Content Provider
Data sharing among mobile applications on a device is common. Therefore, Android defines a standard mechanism for applications to share data (such as a list of contacts) without exposing the underlying storage, structure, and implementation. Through content providers, you can expose your data and have your applications use data from other applications.

Service
Services in Android resemble services you see in Windows or other platforms—they’re background processes that can potentially run for a long time. Android defines two types of services: local services and remote services. Local services are components that are only accessible by the application that is hosting the service. Conversely, remote services are services that are meant to be accessed remotely by other applications running on the device.  An example of a service is a component that is used by an e-mail application to poll for new messages. This kind of service might be a local service if the service is not used by other applications running on the device. If several applications use the service, then it would be implemented as a remote service. The difference is in startService() vs. bindService().  You can use existing services and also write your own services by extending the Service class.

2012年11月11日 星期日

Large Data Files in /mnt/sdcard/Android/data/com.cooliris.media/cache

Recently, I found that my sdcard become full suddenly. 
I remeber that I must have more than 1G left.  So I am looking for which directory are growing too quick. 

Finaly, I found that it is coming from /mnt/sdcard/Android/data/com.cooliris.media/cache. 

This directory contain more than 1G files.  So I delete them to free up the memory.

However, it is growing up quick to use up all the memory in my SDCARD.

At last I found our the reason.  It is coming from cache for my comic.  So I added .nomedia in all of my comic and the problem solved.  It is now only around 50M.


2012年11月9日 星期五

Memory Analyzer for Android Apps

To dump the heap, click on the icon Dump HPROF file. There are many tools for analyzing heap dumps but the one I'm most familiar is the Eclipse Memory Analyzer (MAT). Download it from http://www.eclipse.org/mat/.

MAT can't handle the DDMS heap dumps right away, but there is a converter tool in the Android SDK.

So simply run this command

C:\Android\android-sdk\tools>hprof-conv rawdump.hprof converteddump.hprof




Android Memory Information

adb shell dumpsys meminfo

adb shell dumpsys meminfo system


ActivityManager activityManager = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(memoryInfo);
Log.i(TAG, " memoryInfo.availMem " + memoryInfo.availMem + "\n" );
Log.i(TAG, " memoryInfo.lowMemory " + memoryInfo.lowMemory + "\n" );
Log.i(TAG, " memoryInfo.threshold " + memoryInfo.threshold + "\n" );
List<RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
Map<Integer, String> pidMap = new TreeMap<Integer, String>();
for (RunningAppProcessInfo runningAppProcessInfo : runningAppProcesses)
{
    pidMap.put(runningAppProcessInfo.pid, runningAppProcessInfo.processName);
}
Collection<Integer> keys = pidMap.keySet();
for(int key : keys)
{
    int pids[] = new int[1];
    pids[0] = key;
    android.os.Debug.MemoryInfo[] memoryInfoArray = activityManager.getProcessMemoryInfo(pids);
    for(android.os.Debug.MemoryInfo pidMemoryInfo: memoryInfoArray)
    {
        Log.i(TAG, String.format("** MEMINFO in pid %d [%s] **\n",pids[0],pidMap.get(pids[0])));
        Log.i(TAG, " pidMemoryInfo.getTotalPrivateDirty(): " + pidMemoryInfo.getTotalPrivateDirty() + "\n");
        Log.i(TAG, " pidMemoryInfo.getTotalPss(): " + pidMemoryInfo.getTotalPss() + "\n");
        Log.i(TAG, " pidMemoryInfo.getTotalSharedDirty(): " + pidMemoryInfo.getTotalSharedDirty() + "\n");
    }
}

Android Battery Monitor

package com.hong.monitor.battery;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
public class BatteryMonitorActivity extends Activity {

    private CheckBox ac,usb,charging;
 private TextView battery_level;
   

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        Intent batteryStatus = getApplicationContext().registerReceiver(null, ifilter);      
       
        // Are we charging / charged?
        int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
        boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL;

        // How are we charging?
        int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
        boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
        boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
       
        ac = (CheckBox) findViewById(R.id.ac);
        usb = (CheckBox) findViewById(R.id.usb);
        charging = (CheckBox) findViewById(R.id.charge);
       
        ac.setChecked(acCharge);
        usb.setChecked(usbCharge);
        charging.setChecked(isCharging);
       
        int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
        int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
        float batteryPct = level / (float)scale;
        int temp = batteryStatus.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1);
        int voltage = batteryStatus.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1);
        char c=186;

        int health = batteryStatus.getIntExtra(BatteryManager.EXTRA_HEALTH, -1);
       
        String shealth;
        switch(health) {
/*       
         case BatteryManager.BATTERY_HEALTH_COLD: // for level 11
          shealth = "Battery Cold";
         break;
*/       
         case BatteryManager.BATTERY_HEALTH_DEAD:
          shealth = "Battery Dead/";
          break;
         case BatteryManager.BATTERY_HEALTH_GOOD:
          shealth = "Battery Good/";
          break;
         case BatteryManager.BATTERY_HEALTH_OVERHEAT:
          shealth = "Battery Overheat/";
          break;
         case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
          shealth = "Battery Over Voltage/";
          break;
         case BatteryManager.BATTERY_HEALTH_UNKNOWN:
          shealth = "Battery Unknown/";
          break;
         case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
          shealth = "Battery Unspecified failure/";
          break;
         default:
          shealth = "Battery Other/";
        }
       
        battery_level = (TextView) findViewById(R.id.bat_level);
        battery_level.setText(shealth + level + "%/" + temp/10.0 + c + "C/" + voltage + "mV");
    }
    public class PowerConnectionReceiver extends BroadcastReceiver {   
     @Override   
     public void onReceive(Context context, Intent intent) {        
      int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);       
      boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL;           
      int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);    
     
      boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;       
      boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
            ac.setChecked(acCharge);
            usb.setChecked(usbCharge);
            charging.setChecked(isCharging);
          
      if(isCharging)
          Log.i("PowerConnectionReceiver", "Charging!");
      else
          Log.i("PowerConnectionReceiver", "Not Charging!");
     
      if(usbCharge)
          Log.i("PowerConnectionReceiver", "USB Charging!");
      if(acCharge)
       Log.i("PowerConnectionReceiver", "AC Charging!");
      Toast.makeText(getApplicationContext(),"ChargePlug: " + chargePlug,Toast.LENGTH_SHORT).show();
     }
    }
    public class BatteryLevelReceiver extends BroadcastReceiver {   
     @Override   
     public void onReceive(Context context, Intent battery) {  
      int level = battery.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
      int scale = battery.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
      float batteryPct = level / (float)scale;     
      Log.i("BatteryLevelReceiver", "Battery Level: " + batteryPct);
      Toast.makeText(getApplicationContext(),"Battery Level:" + batteryPct,Toast.LENGTH_SHORT).show();
     }
    }
   
}

2012年11月8日 星期四

How to get SD Card directory

The official method Environment.getExternalStorageDirectory() seems to be not working for some Phone as this method return primary memory.

“In devices with multiple ‘external’ storage directories (such as both secure app storage and mountable shared storage), this directory represents the ‘primary’ external storage that the user will interact with.”.


Searching in internet and found the following code can find the SD Card directory.

        File file = new File("/system/etc/vold.fstab");
        FileReader fr = null;
        BufferedReader br = null;
        try {
            fr = new FileReader(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            if (fr != null) {
                br = new BufferedReader(fr);
                String s = br.readLine();
                while (s != null) {
                    if (s.startsWith("dev_mount")) {
                        String[] tokens = s.split("\\s");
                        path = tokens[2]; //mount_point
                        if (!Environment.getExternalStorageDirectory().getAbsolutePath().equals(path)) {
                            break;
                        }
                    }
                    s = br.readLine();
                }
            }           
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fr != null) {
                    fr.close();
                }           
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }