CSE 461: Introduction to Computer Communication Networks, Spring 2012
  CSE Home   About Us   Search   Contact Info 
 
Course Home
  Home
Administration
  Overview
  Course email
  Anonymous feedback
  View feedback
 
Assignment Utilities
  Home Virtual Machines
  Homework Turnin
  Class GoPost Forum
  Gradebook
 
Most Everything
  Schedule
  Hw/Project List
    Project 5: Android Programming Notes

Here are some notes about dealing with Android/Eclipse that might be helpful. You should expect to have to look some things up, even after carefully reading these notes.

  • You might find it useful to use the debugger, adb, from the command line. adb lives in the platform-tools directory of your Android SDK directory.
    • adb shell logs in to the phone and gives you a shell with limited capabilities. I used it to look at what files existed.
    • adb pull filename fetches a file from the phone to your debugging machine.
    • add push localfile phonefile retrieves a file from the phone.
    See the Android debugger page for even more.

  • Your implementation probably uses a config file to help initialize a running instance. Including that file in your Eclipse project requires a trick:
    • Put the file in the Assets folder of the Eclipse Android project.
    • Eclipse/Android normally compresses whatever it finds in the Assets folder, but doesn't uncompress it when you try to read the file on the phone. To avoid the compression, give your config file a final extent of png, as in jz.cse.config.ini.png.
    • The problem now is getting the config file to the instance of the OS your code creates (because you don't want Android-specific code in your OS). The config file must have some name in the phone's file system, so presumably you could just pass that to the OS, but I couldn't find what that name might be. (I didn't spend much time on it, though.) You might might be able to.

      What I ended up doing is modifying my OS.boot() interface to take an InputStream argument, and then passed it getAssets().openFd(CONFIGFILENAME).createInputStream(), which was the only way I found to give it a useful reference to the config file.

    • To edit your now-.png config file in Eclipse, drag-and-drop it onto the editor pane. (Double-clicking on it causes Eclipse to be smart, and try to treat it as an image file.)

  • Similarly, you need to put your photo gallery (folder) somewhere. I put it on the SD card. The SD card has file path /sdcard on the phone. I know that the Gallery app will notice it if it's there. I don't know if it will notice it if it's somewhere substantially different.

  • The Gallery photo viewer seems to index the photo files. The symptom is that when you add a file to your gallery, then bring up the Gallery viewer, you don't see your new photo. To cause the Gallery viewer to reindex (which you should do whenever you change the contents of your gallery directory):
      // Try to update gallery viewer
        sendBroadcast(new Intent(
            Intent.ACTION_MEDIA_MOUNTED,
            Uri.parse("file://" + Environment.getExternalStorageDirectory())));
    
    (This assumes your gallery directory is on the SD card.)

  • You need permissions in your AndroidManifest.xml file. The full set I used is:
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        
    <uses-feature android:name="android.hardware.camera" />
    

  • Make sure you call SNetDB461.registerMember() for both the instance and the root as soon as you've created the SNetDB461 object.

  • You invoke other apps, and Activities other then the main one in your own app, using Intents. See this page.

  • Big images can cause your Android project to run out of memory. To force the camera to give you a not-so-big image, invoke it this way:
     Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
     startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
    
    You then retrieve the image the camera captured in your onActivityResult(int requestCode, int resultCode, Intent data) handler, like this:
    Bitmap photoBmp = (Bitmap)data.getExtras().get("data");
    
    Note: CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE is an integer that you define.

  • You can invoke the Gallery app, to allow the user to choose a photo, using this:
    Intent intent = new Intent(Intent.ACTION_PICK,
              android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    intent.setType("image/*");
    startActivityForResult(intent, CHOOSE_PICTURE_ACTIVITY_REQUEST_CODE);
    
    You then retrieve the path to the photo the user selected (in your OnActivityResult() method) using this code. (There may be easier ways than this, but this is what I used.)
    Uri selectedImage = data.getData();
    String[] filePathColumn = {MediaStore.Images.Media.DATA};
    
    Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
    cursor.moveToFirst();
    
    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
    String filePath = cursor.getString(columnIndex);
    cursor.close();
    
    That selected file path is in variable filePath.

Computer Science & Engineering
University of Washington
Box 352350
Seattle, WA  98195-2350
(206) 543-1695 voice, (206) 543-2969 FAX
[comments to zahorjan at cs.washington.edu]