SlideShare ist ein Scribd-Unternehmen logo
1 von 31
Downloaden Sie, um offline zu lesen
Advanced Android Development
review of gReporter open-source project:
GPS, Audio / Photo Capture, SQLite, HTTP File Upload and more!


Nathan Freitas, Oliver+Coady
nathan@olivercoady.com
Android Platform Basics
Platform Features

• Application framework enabling reuse and replacement of components
• Dalvik virtual machine optimized for mobile devices
• Integrated browser based on the open source WebKit engine
• Optimized graphics powered by a custom 2D graphics library; 3D graphics
  based on the OpenGL ES 1.0 specification (hardware acceleration optional)
• SQLite for structured data storage
• Media support for common audio, video, and still image formats (MPEG4, H.264,
  MP3, AAC, AMR, JPG, PNG, GIF)
• GSM Telephony (hardware dependent)
• Bluetooth, EDGE, 3G, and WiFi (hardware dependent)
• Camera, GPS, compass, and accelerometer (hardware dependent)
• Rich development environment including a device emulator, tools for debugging,
  memory and performance profiling, and a plugin for the Eclipse IDE
What’s in an App?

                                        Libraries
                       Other
     Default            Other           Service
                           Other
                      Activities
     Activity          Activities
                        Activities
                                        Content

                    Android Manifest


   Drawable     Layouts        Values   Assets
Manifest

 <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?>
 <manifest xmlns:android=quot;http://schemas.android.com/apk/res/androidquot;
       package=quot;com.openideals.inaugreportquot;
       android:versionCode=quot;1quot;
       android:versionName=quot;1.0.0quot;>

        <uses-permission android:name=quot;android.permission.ACCESS_FINE_LOCATIONquot; />
     <uses-permission android:name=quot;android.permission.ACCESS_COARSE_LOCATIONquot; />
     <uses-permission android:name=quot;android.permission.INTERNETquot; />
     <uses-permission android:name=quot;android.permission.READ_PHONE_STATEquot;/>



     <application android:icon=quot;@drawable/iconquot; android:label=quot;@string/app_namequot;>
         <activity android:name=quot;.InaugReportMainActivityquot;
                   android:label=quot;@string/app_namequot;>
             <intent-filter>
                 <action android:name=quot;android.intent.action.MAINquot; />
                 <category android:name=quot;android.intent.category.LAUNCHERquot; />
             </intent-filter>
         </activity>

          <activity android:name=quot;com.openideals.android.geo.LocationFinderActivityquot; android:label=quot;@string/view_location_finderquot;/>
         <activity android:name=quot;.ReportFormActivityquot; android:label=quot;@string/view_report_formquot;/>
          <activity android:name=quot;com.openideals.android.ui.InternalWebViewquot; android:label=quot;@string/internal_web_viewquot; />
           <activity android:name=quot;com.openideals.android.geo.GeoRSSMapViewquot; android:label=quot;@string/geo_map_viewquot; />

          <uses-library android:name=quot;com.google.android.mapsquot; />



     </application>
 </manifest>
Layout                                                      <RelativeLayout
                                                                    xmlns:android=quot;http://schemas.android.com/apk/res/androidquot;
                                                                    android:layout_width=quot;fill_parentquot; android:layout_height=quot;wrap_contentquot;
                                                                    android:padding=quot;10dpquot; android:layout_marginTop=quot;10pxquot; >
                                                                    	   	      	
<?xml version=quot;1.0quot; encoding=quot;utf-8quot;?>
                                                                    	   	      	
<ScrollView
                                                                    	   	      	         <Button android:id=quot;@+id/btnReportFormSubmitquot;
xmlns:android=quot;http://schemas.android.com/apk/res/androidquot;
                                                                             android:layout_width=quot;100pxquot;
android:id=quot;@+id/scrollReportFormquot;
                                                                             android:layout_height=quot;wrap_contentquot;
android:layout_width=quot;fill_parentquot;
                                                                              android:background=quot;@drawable/submitquot;
android:layout_height=quot;fill_parentquot;
                                                                              android:layout_margin=quot;10spquot;
 android:background=quot;@drawable/inaug_report_no_seal_quot;>

                                                                                 />
<LinearLayout
android:id=quot;@+id/layoutReportFormquot;
                                                                    	       	      	       <Button android:id=quot;@+id/btnReportFormCancelquot;
android:label=quot;Text Reportquot;
                                                                        	   	      android:layout_width=quot;100pxquot;
android:layout_width=quot;fill_parentquot;
                                                                                  android:layout_height=quot;wrap_contentquot;
android:layout_height=quot;wrap_contentquot;
                                                                                  android:background=quot;@drawable/cancelquot;
android:orientation=quot;verticalquot; android:gravity=quot;topquot;
                                                                                  android:layout_toRightOf=quot;@+id/btnReportFormSubmitquot;
android:padding=quot;6.0spquot;>
                                                                                  android:layout_margin=quot;10spquot;
                                                                                />
     <TextView android:id=quot;@+id/labelTitlequot;
                                                                                 </RelativeLayout>
               android:layout_width=quot;wrap_contentquot;
               android:layout_height=quot;wrap_contentquot;
               android:text=quot;Title:quot;/>

     <EditText android:id=quot;@+id/entryTitlequot;
               android:layout_width=quot;fill_parentquot;
               android:layout_height=quot;wrap_contentquot;
               android:background=quot;@android:drawable/editbox_backgroundquot;
              />

    <TextView android:id=quot;@+id/labelReportquot;
               android:layout_width=quot;wrap_contentquot;
               android:layout_height=quot;wrap_contentquot;
	       	      	       android:paddingTop=quot;10dpquot;
               android:text=quot;Your Report:quot;/>

     <EditText android:id=quot;@+id/entryReportquot;
               android:layout_width=quot;fill_parentquot;
               android:layout_height=quot;wrap_contentquot;
               android:background=quot;@android:drawable/editbox_backgroundquot;
               android:lines=quot;5quot;
               />
Activity
                                                        	
                                                                /** Called when the activity is first created. */
                                                                @Override
                                                                public void onCreate(Bundle savedInstanceState) {
                                                                    super.onCreate(savedInstanceState);
package com.openideals.inaugreport;

                                                                     setContentView(R.layout.reportform);
import   android.app.Activity;
import   android.app.ProgressDialog;
                                                                    ((Button)findViewById(R.id.btnReportFormSubmit)).setOnClickListener(this);
import   android.content.Intent;
                                                                    ((Button)findViewById(R.id.btnReportFormCancel)).setOnClickListener(this);
import   android.location.Location;
import   android.os.Bundle;
import   android.os.Handler;
                                                                }
import   android.util.Log;
import   android.view.View;
import   android.view.View.OnClickListener;
import   android.widget.ArrayAdapter;
import   android.widget.Button;
import   android.widget.CheckBox;
                                                                                        	         	     Toast.makeText(getBaseContext(), quot;There was
import   android.widget.Spinner;
                                                                                       a problem submitting your report. Wait a second, and then
import   android.widget.TextView;
                                                                                       try again!quot;, Toast.LENGTH_LONG).show();
import   android.widget.Toast;

import com.openideals.android.geo.LocationFinderActivity;
import com.openideals.android.ui.HorizontalSlider;
import com.openideals.android.ui.HorizontalSlider.OnProgressChangeListener;



	
	                                                           private void showMain ()
}                                                           	      {
                                                            	      	      Intent iMain = new Intent(this, LocationFinderActivity.class);

                                                                           startActivity(iMain);
                                                            	          }
Android Application Examples
gReporter:
         open-source
         geotagging
         media capture
         report client

         for the Android Platform




http://openideals.com/greporter
gReporter: what is it?

                     • Android client application


                     • Captures text, audio and photo


                     • Finds device location via GPS or Network


                     • Submits captured data + location
                       coordinates to any configured server via
                       HTTP


                     • Displays page of submitted reports or other
                       info


                     • Released under Apache License
Main Menu / LocationManager

              • Three Button Main Menu


              • Activates LocationManager for GPS or Network-
                based location lookup


              • Uses a single PNG background image


              • Uses “toast” dialogs to display updated location
                information from callback
Main Menu / LocationManager
           Locator.xml
            <Button android:id=quot;@+id/btnSubmitAudioquot;
                                                                                 ((Button)findViewById(R.id.btnSubmit
                      android:layout_width=quot;wrap_contentquot;
                                                                                 Audio)).setOnClickListener(this);
                      android:layout_height=quot;wrap_contentquot;
                      android:layout_alignParentRight=quot;truequot;
                                                                                     	
                   	     android:layout_gravity=quot;centerquot;
                  android:text=quot;Record &amp; Submit Audio Reportquot;
                      android:padding=quot;10spquot;/>



                LocationFormActivity.java
                 public void startGPS ()
                     {
                         //---use the LocationManager class to obtain GPS locations---
                     	 if (lm == null)
                     	{
                     		        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

                 	              locationListener = new MyLocationListener();
                 	
                 	              if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER))
                 	              {
                 	              	     Log.i(TAG, quot;starting up GPS location provider...quot;);
                 	       	             lm.requestLocationUpdates(
                 	       	                 LocationManager.GPS_PROVIDER,
                 	       	                 LOCATION_UPDATE_TIME, LOCATION_UPDATE_DISTANCE, locationListener);
                 	       	
                 	       	             currentLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                 	       	             updateLocation (currentLocation);
                 	              }
                 	
                 	              if (lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
                 	              {
                 	       	         ...
                 	              }
                     	   }
                     }
Settings and Text Report Forms

                                 • Basic forms with text
                                   field, input boxes, drop-
                                   downs are all possible


                                 • Values of forms are
                                   either stored in local
                                   sqlite database or
                                   submitted to the server


                                 • on G1 form editing is
                                   always in landscape /
                                   horizontal mode
Settings “Person” Form

                                                                              personform.xml
                                                                               <TextView android:id=quot;@+id/labelFirstNamequot;

                                                                               android:layout_width=quot;wrap_contentquot;

                                                                               android:layout_height=quot;wrap_contentquot;
                                                                                             android:text=quot;First Namequot;/>

                                                                                   <EditText android:id=quot;@+id/entryFirstNamequot;

                                                                               android:layout_width=quot;fill_parentquot;

                                                                               android:layout_height=quot;wrap_contentquot;

                                                                               android:background=quot;@android:drawable/
                                                                               editbox_backgroundquot;
                                                                                            />




PersonFormActivity.java
if (event.getId()==R.id.btnReportFormSubmit)
	   	    {
String firstname = ((TextView)findViewById(R.id.entryFirstName)).getText().toString();
String lastname = ((TextView)findViewById(R.id.entryLastName)).getText().toString();
String email = ((TextView)findViewById(R.id.entryEmail)).getText().toString();
String submitUrl = ((TextView)findViewById(R.id.entrySubmitUrl)).getText().toString();
String displayUrl = ((TextView)findViewById(R.id.entryViewUrl)).getText().toString();
	     	     }
Text Report
                                                                                         reportform.xml
                                                                                             <TextView android:id=quot;@+id/labelReportquot;
                                                                                                        android:layout_width=quot;wrap_contentquot;
                                                                                                        android:layout_height=quot;wrap_contentquot;
                                                                                         	       	      	       android:paddingTop=quot;10dpquot;
                                                                                                        android:text=quot;Your Report:quot;/>

                                                                                             <EditText android:id=quot;@+id/entryReportquot;
                                                                                                       android:layout_width=quot;fill_parentquot;
                                                                                                       android:layout_height=quot;wrap_contentquot;
                                                                                                       android:background=quot;@android:drawable/
                                                                                         editbox_backgroundquot;
                                                                                                       android:lines=quot;5quot;
                                                                                                       />




                                                                                     ReportFormActivity.java
	   public   void onClick(View v) {
	   	        if (v.getId()==R.id.btnReportFormSubmit)
	   	        {
                                                                                    String reportTitle =
	   	        	      progressDialog = ProgressDialog.show(ReportFormActivity.this,
                                                                                    ((TextView)findViewById(R.id.entryTitle)).getText().toStrin
	   	        	      	            quot;Submitting Reportquot;,
                                                                                    g();
	   	        	      	            quot;Please wait...quot;,
                                                                                     	            String reportText =
	   	        	      	            true);
                                                                                    ((TextView)findViewById(R.id.entryReport)).getText().toStri
	   	        	      	
                                                                                    ng();
	   	        	      Handler handler = new Handler();
                                                                                     	
	   	        	
                                                                                     	            boolean reportAccepted =
	   	        	      handler.postDelayed(this, 1000);
                                                                                    Reporter.submitTextReport(reportTitle, reportText);
	   	        	
                                                                                     	
	   	        }
	   	        else if (v.getId()==R.id.btnReportFormCancel)
	   	        {
	   	        	      showMain ();
	   	        }
}
Audio Recording / File System

               • Audio recording through built-in device microphone
                 in 3GP format


               • Captured to SD card storage


               • Playback review / re-record overwrite


               • Audio upload to server via HTTP Post
Audio Recording / File System
               reportaudioform.xml
               <ScrollView xmlns:android=quot;http://schemas.android.com/apk/res/androidquot;
               android:id=quot;@+id/scrollReportFormquot; android:layout_width=quot;fill_parentquot;
               android:layout_height=quot;fill_parentquot;
                android:background=quot;@drawable/bgquot;>

               <LinearLayout android:id=quot;@+id/layoutReportFormquot; android:label=quot;Text Reportquot;
               android:layout_width=quot;fill_parentquot; android:layout_height=quot;wrap_contentquot;
               android:orientation=quot;verticalquot; android:gravity=quot;topquot; android:padding=quot;6.0spquot;>

                 <TextView android:id=quot;@+id/labelPhotoHeaderquot; android:layout_width=quot;fill_parentquot;
               android:layout_height=quot;wrap_contentquot; android:text=quot;...quot;/>

                   <RelativeLayout
                     xmlns:android=quot;http://schemas.android.com/apk/res/androidquot;
                     android:layout_width=quot;fill_parentquot; android:layout_height=quot;wrap_contentquot;
                     android:padding=quot;10dpquot; android:layout_marginTop=quot;10pxquot;>




               private void setStatus (String status)
               	      {
               	      	      ((TextView)findViewById(R.id.labelAudioStatus)).setText(status);

               	        }
               	




                  Toast.makeText(getBaseContext(), quot;Thank you. Your report has been accepted!quot;,
               Toast.LENGTH_LONG).show();
Audio Recording / File System (cont’d)
               private String startRecording (String filename)
               	      {
               	      	      setStatus (quot;Recording...quot;);
               	      	
               	      	      ((TextView)findViewById(R.id.btnRecordAudio)).setText(quot;Stopquot;);
               	      	
               	      	      String path = null;
               	      	
               	      	      if (currentAudioFile != null)
               	      	      {
               	      	      	      path = currentAudioFile;
               	      	      }
               	      	      else
               	      	      {
               	      	      	       path = quot;/sdcard/quot; + filename + file_ext;
               	      	      }
               	      	
               	      	      mRecorder = new MediaRecorder();
               	      	      mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
               	      	      mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
               	      	      mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
               	      	      mRecorder.setOutputFile(path);
               	      	      mRecorder.prepare();
                                                              private void playRecording (String path)
               	      	      mRecorder.start();
                                                              	      {
               	      	
                                                              	      	      setStatus (quot;Playing...quot;);
               	      	      return path;
                                                              	      	
                                                              	      	      try
               	      }
                                                              	      	      {
                                                              	      	      	      mMediaPlayer = new MediaPlayer();
                                                                          mMediaPlayer.setDataSource(path);
                                                                          mMediaPlayer.prepare();
                                                                          mMediaPlayer.start();
                                                              	      	      }
                                                              	      	      catch (IOException e)
                                                              	      	      {
                                                              	      	      	      e.printStackTrace();
                                                              	      	      }
                                                              	      }
Photo Capture & Display

                 • Capture of photo from built-in camera


                 • Captured in JPEG format at screen-size
                   resolution (480x320)


                 • Compressed from 3MP format on capture


                 • Stored on local SD card (also accessible via USB
                   mount or card reader)


                 • Upload to server via HTTP Post
Photo Capture & Display

             reportphotoform.xml
                  <ImageView android:id=quot;@+id/previewphotoquot; android:layout_width=quot;wrap_contentquot;
                           android:layout_height=quot;wrap_contentquot;
                           android:layout_gravity=quot;topquot;/>



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

                         currentPhotoPath = this.getIntent().getStringExtra(quot;photofilequot;);

                        setContentView(R.layout.reportphotoform);

                        ((Button)findViewById(R.id.btnTakePicture)).setOnClickListener(this);
              	            ((Button)findViewById(R.id.btnReportFormSubmit)).setOnClickListener(this);
                        ((Button)findViewById(R.id.btnReportFormCancel)).setOnClickListener(this);

                    if (currentPhotoPath != null)
                    {
                  	    Toast.makeText(getBaseContext(), quot;Ready to send photo: quot; + currentPhotoPath,
              Toast.LENGTH_LONG).show();
                  	
                  	
              ((ImageView)findViewById(R.id.previewphoto)).setImageURI(Uri.parse(currentPhotoPath));
                  	
                    }
                  }
Photo Capture & Display (cont’d)
                                                                        camera.xml
                                                                         <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?>
                                                                         <LinearLayout xmlns:android=quot;http://schemas.android.com/apk/res/
                                                                         androidquot;
                                                                              android:orientation=quot;verticalquot;
                                                                         android:layout_width=quot;fill_parentquot;
                                                                              android:layout_height=quot;fill_parentquot;
                                                                         android:background=quot;@drawable/bgquot;>
                                                                         <SurfaceView android:id=quot;@+id/surfacequot;
                                                                         android:layout_width=quot;fill_parentquot; android:layout_height=quot;10dipquot;
                                                                         android:layout_weight=quot;1quot;>
                                                                         </SurfaceView>
                                                                         </LinearLayout>



ImageCaptureActivity:
preview setup                                          photo capture
public void surfaceChanged(SurfaceHolder holder, int   public   void onPreviewFrame(byte[] data, Camera c) {
format, int w, int h)                                  	
{                                                      	        if (!sizeSet)
Log.e(getClass().getSimpleName(), quot;surfaceChangedquot;);   	        {
if (isPreviewRunning) {                                	        	      Log.i(getClass().getSimpleName(), quot;preview frame
  camera.stopPreview();                                RAW: quot;   + data);
}                                                      	        	
                                                       	        	      Camera.Parameters params = c.getParameters();
camera.setPreviewDisplay(holder);                      	        	      params.setPictureFormat(PixelFormat.JPEG);
camera.startPreview();                                 	        	      params.setPictureSize(PHOTO_WIDTH,PHOTO_HEIGHT);
isPreviewRunning = true;                               	        	      c.setParameters(params);
}                                                      	        	
                                                       	        	      sizeSet = true;
                                                       	        }
                                                       }
Photo Capture & Display (cont’d)
               Camera.PictureCallback mPictureCallbackJpeg= new Camera.PictureCallback() {

               public void onPictureTaken(byte[] data, Camera c) {

                   Log.e(getClass().getSimpleName(), quot;PICTURE CALLBACK JPEG: data.length = quot; + data.length);
                   String filename = timeStampFormat.format(new Date());

                   String baseDir = quot;/sdcard/quot;;

                 if (new File(quot;/sdcard/dcim/Camera/quot;).exists())
                 {
               	        baseDir = quot;/sdcard/dcim/Camera/quot;;
                 }

                   currentPhotoFile = baseDir + filename + quot;.jpgquot;;

                   try
                   {
               	         FileOutputStream file = new FileOutputStream(new File(currentPhotoFile));
               	         file.write(data);
               	
               	         sendPicture();
                 }
                  catch (Exception e){
               	         e.printStackTrace();
                 }
               }
               };

               Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback() {
               public void onShutter() {
               Log.e(getClass().getSimpleName(), quot;SHUTTER CALLBACKquot;);

               Camera.Parameters params = camera.getParameters();
               params.setPictureFormat(PixelFormat.JPEG);
               params.setPictureSize(PHOTO_WIDTH,PHOTO_HEIGHT);
               camera.setParameters(params);

               } };
Menu Dialog Options

                   @Override
               	      public boolean onCreateOptionsMenu(Menu menu) {
                       super.onCreateOptionsMenu(menu);

                         MenuItem mItem = menu.add(0, 1, Menu.NONE, quot;Aboutquot;);
                         MenuItem mItem2 = menu.add(0, 2, Menu.NONE, quot;Settingsquot;);
                        MenuItem mItem3 = menu.add(0, 3, Menu.NONE, quot;Reportsquot;);

                        mItem.setIcon(R.drawable.ic_menu_about);
                        mItem2.setIcon(R.drawable.ic_menu_register);
                        mItem3.setIcon(R.drawable.ic_menu_reports);

                         return true;
                   }




               public   boolean onMenuItemSelected(int featureId, MenuItem item) {
               	        	
               	        	       super.onMenuItemSelected(featureId, item);
               	        	
               	        	       if (item.getItemId() == 1)
               	        	       	      showCredits();
               	        	       else if (item.getItemId() == 2)
               	        	       	      showRegistration();
               	        	       else if (item.getItemId() == 3)
               	        	       {
               	        	       	
               	        	       	      showWebView ();
               	        	       }
               	        	
                          return true;
               	        }
Embedded Web “Reports” View
              private void showWebView ()
                  {
                  	 Intent iReportForm = new Intent(this, InternalWebView.class);
                  	
                  	 String reportDisplayUrl =
              PreferenceDB.getInstance(this).getPref(GReporterConstants.PREFKEY_REPORT_DISPLAY_URL);
                  	
                  	 iReportForm.putExtra(quot;urlquot;, reportDisplayUrl);
                  	
                      startActivity(iReportForm);
                  	
                  }



              <WebView
                     android:id=quot;@+id/webviewquot;
                 	 android:layout_width=quot;fill_parentquot;
                 	 android:layout_height=quot;fill_parentquot;
                 	 android:layout_weight=quot;1quot;
                 	 />




             mWebView = (WebView) findViewById(R.id.webview);

                     WebSettings webSettings = mWebView.getSettings();
                     webSettings.setSavePassword(false);
                     webSettings.setSaveFormData(false);
                     webSettings.setJavaScriptEnabled(true);
                     webSettings.setSupportZoom(false);

                     mWebView.setWebChromeClient(new MyWebChromeClient());

                     mWebView.loadUrl(url);
PreferencesDB - SQLite
    public class PreferenceDB    {

    	      private static final String CREATE_TABLE_PREFS = quot;create table prefs (pref_id integer primary key autoincrement, quot;
    	      	      	      + quot;prefkey text not null, prefval text not null);quot;;

    	
    	      private static final String PREFS_TABLE = quot;prefsquot;;
    	      private static final String DATABASE_NAME = quot;prefsdbquot;;
    	      private static final int DATABASE_VERSION = 2;



                                                                          public   boolean insertPref(String key, String value) {
@Override                                                                 	        	
       public void onCreate(SQLiteDatabase db) {                          	        	      deletePref(key);
       	     try                                                          	        	
       	     {                                                            	        	      SQLiteDatabase db = mOpenHelper.getWritableDatabase();
       	     	      db.execSQL(CREATE_TABLE_PREFS);                       	        	
       	     }                                                            	        	      ContentValues values = new ContentValues();
       	     catch (Exception e)                                          	        	      values.put(quot;prefkeyquot;, key);
       	     {                                                            	        	      values.put(quot;prefvalquot;, value);
       	     	      Log.i(DATABASE_NAME,quot;tables already existquot;);          	        	
       	     }                                                            	        	
       }                                                                  	        	      boolean resp = (db.insert(PREFS_TABLE, null, values) > 0);
                                                                          	        	
                                                                          	        	      return resp;
                                                                          	        }

             Cursor   c = db.query(PREFS_TABLE, new String[] {quot;prefvalquot;    }, quot;prefkey=?quot;, new String[] {key}, null, null, null);
             	        	      	
             	        	      	      int numRows = c.getCount();
             	        	      	
             	        	      	      if (numRows > 0)
             	        	      	      {
             	        	      	      c.moveToFirst();
             	        	      	      result = c.getString(0);
             	        	      	      }
             	        	      	
             	        	      	      c.close();
PhoneGap: Browser-based Apps
PhoneGap Sample




                WORDPRESS   FANCY
Splash Screen
                  MOBILE    MENUS!
PhoneGap

           <resources>
               <string name=quot;helloquot;>Hello World, PhoneGap</string>
               <string name=quot;app_namequot;>OpenIdeals</string>
           <string name=quot;urlquot;>file:///android_asset/index.html</string>
           </resources>




           <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?>
           <LinearLayout xmlns:android=quot;http://schemas.android.com/apk/res/androidquot;
               android:orientation=quot;verticalquot;
               android:layout_width=quot;fill_parentquot;
               android:layout_height=quot;fill_parentquot;
               >
                       <WebView android:id=quot;@+id/appViewquot;
                       android:layout_height=quot;wrap_contentquot;
                       android:layout_width=quot;fill_parentquot;
                       />	
           </LinearLayout>




           <meta http-equiv=quot;refreshquot; content=quot;3;url=http://openideals.com/quot;>
           </head>
           <body>
           <a href=quot;http://openideals.com/quot;><img src=quot;default.pngquot; id=quot;splashquot;></a>
           </body>
           </html>
Other Development Resources
OpenIntents.org




           http://www.openintents.org
PhoneGap.com

 • PhoneGap is a development tool that allows web developers to take
   advantage of the core features in the iPhone, Android, and Blackberry
   SDK using JavaScript.

Weitere ähnliche Inhalte

Was ist angesagt?

Being Epic: Best Practices for Android Development
Being Epic: Best Practices for Android DevelopmentBeing Epic: Best Practices for Android Development
Being Epic: Best Practices for Android DevelopmentReto Meier
 
Android Tutorials - Powering with Selection Widget
Android Tutorials - Powering with Selection WidgetAndroid Tutorials - Powering with Selection Widget
Android Tutorials - Powering with Selection WidgetPrajyot Mainkar
 
Architecting your Splunk deployment
Architecting your Splunk deploymentArchitecting your Splunk deployment
Architecting your Splunk deploymentSplunk
 
Android Screen Containers & Layouts
Android Screen Containers & LayoutsAndroid Screen Containers & Layouts
Android Screen Containers & LayoutsVijay Rastogi
 
Have Better Toys
Have Better ToysHave Better Toys
Have Better Toysapotonick
 
User Experience is dead. Long live the user experience!
User Experience is dead. Long live the user experience!User Experience is dead. Long live the user experience!
User Experience is dead. Long live the user experience!Greg Bell
 
Beginning Native Android Apps
Beginning Native Android AppsBeginning Native Android Apps
Beginning Native Android AppsGil Irizarry
 
Recommended material components : Android Bangkok 2019
Recommended material components : Android Bangkok 2019Recommended material components : Android Bangkok 2019
Recommended material components : Android Bangkok 2019Minseo Chayabanjonglerd
 
Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101Johnny Sung
 
Taking Your Content Mobile
Taking Your Content MobileTaking Your Content Mobile
Taking Your Content MobileJeremy Johnson
 
Alloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLonAlloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLonFokke Zandbergen
 
Make Cross-platform Mobile Apps Quickly - SIGGRAPH 2014
Make Cross-platform Mobile Apps Quickly - SIGGRAPH 2014Make Cross-platform Mobile Apps Quickly - SIGGRAPH 2014
Make Cross-platform Mobile Apps Quickly - SIGGRAPH 2014Gil Irizarry
 
Alfresco Forms Service Deep Dive
Alfresco Forms Service Deep DiveAlfresco Forms Service Deep Dive
Alfresco Forms Service Deep DiveAlfresco Software
 
Health News & Articles | Healthy Living
Health News & Articles | Healthy LivingHealth News & Articles | Healthy Living
Health News & Articles | Healthy Livingseemlygown2854
 
PLAT-14 Forms Config, Customization, and Extension
PLAT-14 Forms Config, Customization, and ExtensionPLAT-14 Forms Config, Customization, and Extension
PLAT-14 Forms Config, Customization, and ExtensionAlfresco Software
 
Android Application that makes use of RSS Feed.pptx
Android Application that makes use of RSS Feed.pptxAndroid Application that makes use of RSS Feed.pptx
Android Application that makes use of RSS Feed.pptxvishal choudhary
 

Was ist angesagt? (20)

Being Epic: Best Practices for Android Development
Being Epic: Best Practices for Android DevelopmentBeing Epic: Best Practices for Android Development
Being Epic: Best Practices for Android Development
 
Android Tutorials - Powering with Selection Widget
Android Tutorials - Powering with Selection WidgetAndroid Tutorials - Powering with Selection Widget
Android Tutorials - Powering with Selection Widget
 
Architecting your Splunk deployment
Architecting your Splunk deploymentArchitecting your Splunk deployment
Architecting your Splunk deployment
 
Android Screen Containers & Layouts
Android Screen Containers & LayoutsAndroid Screen Containers & Layouts
Android Screen Containers & Layouts
 
Front End on Rails
Front End on RailsFront End on Rails
Front End on Rails
 
Have Better Toys
Have Better ToysHave Better Toys
Have Better Toys
 
Aloha Presentation #t3con10
Aloha Presentation #t3con10Aloha Presentation #t3con10
Aloha Presentation #t3con10
 
User Experience is dead. Long live the user experience!
User Experience is dead. Long live the user experience!User Experience is dead. Long live the user experience!
User Experience is dead. Long live the user experience!
 
I os 11
I os 11I os 11
I os 11
 
Beginning Native Android Apps
Beginning Native Android AppsBeginning Native Android Apps
Beginning Native Android Apps
 
Recommended material components : Android Bangkok 2019
Recommended material components : Android Bangkok 2019Recommended material components : Android Bangkok 2019
Recommended material components : Android Bangkok 2019
 
Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101
 
Taking Your Content Mobile
Taking Your Content MobileTaking Your Content Mobile
Taking Your Content Mobile
 
Alloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLonAlloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLon
 
Make Cross-platform Mobile Apps Quickly - SIGGRAPH 2014
Make Cross-platform Mobile Apps Quickly - SIGGRAPH 2014Make Cross-platform Mobile Apps Quickly - SIGGRAPH 2014
Make Cross-platform Mobile Apps Quickly - SIGGRAPH 2014
 
Alfresco Forms Service Deep Dive
Alfresco Forms Service Deep DiveAlfresco Forms Service Deep Dive
Alfresco Forms Service Deep Dive
 
Training On Angular Js
Training On Angular JsTraining On Angular Js
Training On Angular Js
 
Health News & Articles | Healthy Living
Health News & Articles | Healthy LivingHealth News & Articles | Healthy Living
Health News & Articles | Healthy Living
 
PLAT-14 Forms Config, Customization, and Extension
PLAT-14 Forms Config, Customization, and ExtensionPLAT-14 Forms Config, Customization, and Extension
PLAT-14 Forms Config, Customization, and Extension
 
Android Application that makes use of RSS Feed.pptx
Android Application that makes use of RSS Feed.pptxAndroid Application that makes use of RSS Feed.pptx
Android Application that makes use of RSS Feed.pptx
 

Ähnlich wie Advanced Android gReporter

21 android2 updated
21 android2 updated21 android2 updated
21 android2 updatedGhanaGTUG
 
android level 3
android level 3android level 3
android level 3DevMix
 
Building apps for multiple devices
Building apps for multiple devicesBuilding apps for multiple devices
Building apps for multiple devicesTerry Ryan
 
Design Patterns for Tablets and Smartphones
Design Patterns for Tablets and SmartphonesDesign Patterns for Tablets and Smartphones
Design Patterns for Tablets and SmartphonesMichael Galpin
 
Разработка приложений для Android Honeycomb: ActionBar & Fragments
Разработка приложений для Android Honeycomb: ActionBar & FragmentsРазработка приложений для Android Honeycomb: ActionBar & Fragments
Разработка приложений для Android Honeycomb: ActionBar & FragmentsAlexey Ustenko
 
Android Workshop
Android WorkshopAndroid Workshop
Android WorkshopJunda Ong
 
Introduction To Google Android (Ft Rohan Bomle)
Introduction To Google Android (Ft Rohan Bomle)Introduction To Google Android (Ft Rohan Bomle)
Introduction To Google Android (Ft Rohan Bomle)Fafadia Tech
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basicsAnton Narusberg
 
Non Conventional Android Programming En
Non Conventional Android Programming EnNon Conventional Android Programming En
Non Conventional Android Programming Enguest9bcef2f
 
Non Conventional Android Programming (English)
Non Conventional Android Programming (English)Non Conventional Android Programming (English)
Non Conventional Android Programming (English)Davide Cerbo
 
Client-side JavaScript Vulnerabilities
Client-side JavaScript VulnerabilitiesClient-side JavaScript Vulnerabilities
Client-side JavaScript VulnerabilitiesOry Segal
 
Introduction to Android Fragments
Introduction to Android FragmentsIntroduction to Android Fragments
Introduction to Android FragmentsSergi Martínez
 
Mobile Software Engineering Crash Course - C03 Android
Mobile Software Engineering Crash Course - C03 AndroidMobile Software Engineering Crash Course - C03 Android
Mobile Software Engineering Crash Course - C03 AndroidMohammad Shaker
 
Lecture #1 Creating your first android project
Lecture #1  Creating your first android projectLecture #1  Creating your first android project
Lecture #1 Creating your first android projectVitali Pekelis
 
Android the Agile way
Android the Agile wayAndroid the Agile way
Android the Agile wayAshwin Raghav
 

Ähnlich wie Advanced Android gReporter (20)

21 android2 updated
21 android2 updated21 android2 updated
21 android2 updated
 
android level 3
android level 3android level 3
android level 3
 
Building apps for multiple devices
Building apps for multiple devicesBuilding apps for multiple devices
Building apps for multiple devices
 
Design Patterns for Tablets and Smartphones
Design Patterns for Tablets and SmartphonesDesign Patterns for Tablets and Smartphones
Design Patterns for Tablets and Smartphones
 
Developing in android
Developing in androidDeveloping in android
Developing in android
 
Разработка приложений для Android Honeycomb: ActionBar & Fragments
Разработка приложений для Android Honeycomb: ActionBar & FragmentsРазработка приложений для Android Honeycomb: ActionBar & Fragments
Разработка приложений для Android Honeycomb: ActionBar & Fragments
 
Android Workshop
Android WorkshopAndroid Workshop
Android Workshop
 
Introduction To Google Android (Ft Rohan Bomle)
Introduction To Google Android (Ft Rohan Bomle)Introduction To Google Android (Ft Rohan Bomle)
Introduction To Google Android (Ft Rohan Bomle)
 
Layout
LayoutLayout
Layout
 
Layouts in android
Layouts in androidLayouts in android
Layouts in android
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basics
 
Non Conventional Android Programming En
Non Conventional Android Programming EnNon Conventional Android Programming En
Non Conventional Android Programming En
 
Non Conventional Android Programming (English)
Non Conventional Android Programming (English)Non Conventional Android Programming (English)
Non Conventional Android Programming (English)
 
Client-side JavaScript Vulnerabilities
Client-side JavaScript VulnerabilitiesClient-side JavaScript Vulnerabilities
Client-side JavaScript Vulnerabilities
 
Android Development
Android DevelopmentAndroid Development
Android Development
 
Introduction to Android Fragments
Introduction to Android FragmentsIntroduction to Android Fragments
Introduction to Android Fragments
 
Mobile Software Engineering Crash Course - C03 Android
Mobile Software Engineering Crash Course - C03 AndroidMobile Software Engineering Crash Course - C03 Android
Mobile Software Engineering Crash Course - C03 Android
 
Android Intro
Android IntroAndroid Intro
Android Intro
 
Lecture #1 Creating your first android project
Lecture #1  Creating your first android projectLecture #1  Creating your first android project
Lecture #1 Creating your first android project
 
Android the Agile way
Android the Agile wayAndroid the Agile way
Android the Agile way
 

Kürzlich hochgeladen

JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard37
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityWSO2
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMKumar Satyam
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 

Kürzlich hochgeladen (20)

JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 

Advanced Android gReporter

  • 1. Advanced Android Development review of gReporter open-source project: GPS, Audio / Photo Capture, SQLite, HTTP File Upload and more! Nathan Freitas, Oliver+Coady nathan@olivercoady.com
  • 3. Platform Features • Application framework enabling reuse and replacement of components • Dalvik virtual machine optimized for mobile devices • Integrated browser based on the open source WebKit engine • Optimized graphics powered by a custom 2D graphics library; 3D graphics based on the OpenGL ES 1.0 specification (hardware acceleration optional) • SQLite for structured data storage • Media support for common audio, video, and still image formats (MPEG4, H.264, MP3, AAC, AMR, JPG, PNG, GIF) • GSM Telephony (hardware dependent) • Bluetooth, EDGE, 3G, and WiFi (hardware dependent) • Camera, GPS, compass, and accelerometer (hardware dependent) • Rich development environment including a device emulator, tools for debugging, memory and performance profiling, and a plugin for the Eclipse IDE
  • 4. What’s in an App? Libraries Other Default Other Service Other Activities Activity Activities Activities Content Android Manifest Drawable Layouts Values Assets
  • 5. Manifest <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?> <manifest xmlns:android=quot;http://schemas.android.com/apk/res/androidquot; package=quot;com.openideals.inaugreportquot; android:versionCode=quot;1quot; android:versionName=quot;1.0.0quot;> <uses-permission android:name=quot;android.permission.ACCESS_FINE_LOCATIONquot; /> <uses-permission android:name=quot;android.permission.ACCESS_COARSE_LOCATIONquot; /> <uses-permission android:name=quot;android.permission.INTERNETquot; /> <uses-permission android:name=quot;android.permission.READ_PHONE_STATEquot;/> <application android:icon=quot;@drawable/iconquot; android:label=quot;@string/app_namequot;> <activity android:name=quot;.InaugReportMainActivityquot; android:label=quot;@string/app_namequot;> <intent-filter> <action android:name=quot;android.intent.action.MAINquot; /> <category android:name=quot;android.intent.category.LAUNCHERquot; /> </intent-filter> </activity> <activity android:name=quot;com.openideals.android.geo.LocationFinderActivityquot; android:label=quot;@string/view_location_finderquot;/> <activity android:name=quot;.ReportFormActivityquot; android:label=quot;@string/view_report_formquot;/> <activity android:name=quot;com.openideals.android.ui.InternalWebViewquot; android:label=quot;@string/internal_web_viewquot; /> <activity android:name=quot;com.openideals.android.geo.GeoRSSMapViewquot; android:label=quot;@string/geo_map_viewquot; /> <uses-library android:name=quot;com.google.android.mapsquot; /> </application> </manifest>
  • 6. Layout <RelativeLayout xmlns:android=quot;http://schemas.android.com/apk/res/androidquot; android:layout_width=quot;fill_parentquot; android:layout_height=quot;wrap_contentquot; android:padding=quot;10dpquot; android:layout_marginTop=quot;10pxquot; > <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?> <ScrollView <Button android:id=quot;@+id/btnReportFormSubmitquot; xmlns:android=quot;http://schemas.android.com/apk/res/androidquot; android:layout_width=quot;100pxquot; android:id=quot;@+id/scrollReportFormquot; android:layout_height=quot;wrap_contentquot; android:layout_width=quot;fill_parentquot; android:background=quot;@drawable/submitquot; android:layout_height=quot;fill_parentquot; android:layout_margin=quot;10spquot; android:background=quot;@drawable/inaug_report_no_seal_quot;> /> <LinearLayout android:id=quot;@+id/layoutReportFormquot; <Button android:id=quot;@+id/btnReportFormCancelquot; android:label=quot;Text Reportquot; android:layout_width=quot;100pxquot; android:layout_width=quot;fill_parentquot; android:layout_height=quot;wrap_contentquot; android:layout_height=quot;wrap_contentquot; android:background=quot;@drawable/cancelquot; android:orientation=quot;verticalquot; android:gravity=quot;topquot; android:layout_toRightOf=quot;@+id/btnReportFormSubmitquot; android:padding=quot;6.0spquot;> android:layout_margin=quot;10spquot; /> <TextView android:id=quot;@+id/labelTitlequot; </RelativeLayout> android:layout_width=quot;wrap_contentquot; android:layout_height=quot;wrap_contentquot; android:text=quot;Title:quot;/> <EditText android:id=quot;@+id/entryTitlequot; android:layout_width=quot;fill_parentquot; android:layout_height=quot;wrap_contentquot; android:background=quot;@android:drawable/editbox_backgroundquot; /> <TextView android:id=quot;@+id/labelReportquot; android:layout_width=quot;wrap_contentquot; android:layout_height=quot;wrap_contentquot; android:paddingTop=quot;10dpquot; android:text=quot;Your Report:quot;/> <EditText android:id=quot;@+id/entryReportquot; android:layout_width=quot;fill_parentquot; android:layout_height=quot;wrap_contentquot; android:background=quot;@android:drawable/editbox_backgroundquot; android:lines=quot;5quot; />
  • 7. Activity /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); package com.openideals.inaugreport; setContentView(R.layout.reportform); import android.app.Activity; import android.app.ProgressDialog; ((Button)findViewById(R.id.btnReportFormSubmit)).setOnClickListener(this); import android.content.Intent; ((Button)findViewById(R.id.btnReportFormCancel)).setOnClickListener(this); import android.location.Location; import android.os.Bundle; import android.os.Handler; } import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; Toast.makeText(getBaseContext(), quot;There was import android.widget.Spinner; a problem submitting your report. Wait a second, and then import android.widget.TextView; try again!quot;, Toast.LENGTH_LONG).show(); import android.widget.Toast; import com.openideals.android.geo.LocationFinderActivity; import com.openideals.android.ui.HorizontalSlider; import com.openideals.android.ui.HorizontalSlider.OnProgressChangeListener; private void showMain () } { Intent iMain = new Intent(this, LocationFinderActivity.class); startActivity(iMain); }
  • 9. gReporter: open-source geotagging media capture report client for the Android Platform http://openideals.com/greporter
  • 10. gReporter: what is it? • Android client application • Captures text, audio and photo • Finds device location via GPS or Network • Submits captured data + location coordinates to any configured server via HTTP • Displays page of submitted reports or other info • Released under Apache License
  • 11. Main Menu / LocationManager • Three Button Main Menu • Activates LocationManager for GPS or Network- based location lookup • Uses a single PNG background image • Uses “toast” dialogs to display updated location information from callback
  • 12. Main Menu / LocationManager Locator.xml <Button android:id=quot;@+id/btnSubmitAudioquot; ((Button)findViewById(R.id.btnSubmit android:layout_width=quot;wrap_contentquot; Audio)).setOnClickListener(this); android:layout_height=quot;wrap_contentquot; android:layout_alignParentRight=quot;truequot; android:layout_gravity=quot;centerquot; android:text=quot;Record &amp; Submit Audio Reportquot; android:padding=quot;10spquot;/> LocationFormActivity.java public void startGPS () { //---use the LocationManager class to obtain GPS locations--- if (lm == null) { lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); locationListener = new MyLocationListener(); if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) { Log.i(TAG, quot;starting up GPS location provider...quot;); lm.requestLocationUpdates( LocationManager.GPS_PROVIDER, LOCATION_UPDATE_TIME, LOCATION_UPDATE_DISTANCE, locationListener); currentLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); updateLocation (currentLocation); } if (lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { ... } } }
  • 13. Settings and Text Report Forms • Basic forms with text field, input boxes, drop- downs are all possible • Values of forms are either stored in local sqlite database or submitted to the server • on G1 form editing is always in landscape / horizontal mode
  • 14. Settings “Person” Form personform.xml <TextView android:id=quot;@+id/labelFirstNamequot; android:layout_width=quot;wrap_contentquot; android:layout_height=quot;wrap_contentquot; android:text=quot;First Namequot;/> <EditText android:id=quot;@+id/entryFirstNamequot; android:layout_width=quot;fill_parentquot; android:layout_height=quot;wrap_contentquot; android:background=quot;@android:drawable/ editbox_backgroundquot; /> PersonFormActivity.java if (event.getId()==R.id.btnReportFormSubmit) { String firstname = ((TextView)findViewById(R.id.entryFirstName)).getText().toString(); String lastname = ((TextView)findViewById(R.id.entryLastName)).getText().toString(); String email = ((TextView)findViewById(R.id.entryEmail)).getText().toString(); String submitUrl = ((TextView)findViewById(R.id.entrySubmitUrl)).getText().toString(); String displayUrl = ((TextView)findViewById(R.id.entryViewUrl)).getText().toString(); }
  • 15. Text Report reportform.xml <TextView android:id=quot;@+id/labelReportquot; android:layout_width=quot;wrap_contentquot; android:layout_height=quot;wrap_contentquot; android:paddingTop=quot;10dpquot; android:text=quot;Your Report:quot;/> <EditText android:id=quot;@+id/entryReportquot; android:layout_width=quot;fill_parentquot; android:layout_height=quot;wrap_contentquot; android:background=quot;@android:drawable/ editbox_backgroundquot; android:lines=quot;5quot; /> ReportFormActivity.java public void onClick(View v) { if (v.getId()==R.id.btnReportFormSubmit) { String reportTitle = progressDialog = ProgressDialog.show(ReportFormActivity.this, ((TextView)findViewById(R.id.entryTitle)).getText().toStrin quot;Submitting Reportquot;, g(); quot;Please wait...quot;, String reportText = true); ((TextView)findViewById(R.id.entryReport)).getText().toStri ng(); Handler handler = new Handler(); boolean reportAccepted = handler.postDelayed(this, 1000); Reporter.submitTextReport(reportTitle, reportText); } else if (v.getId()==R.id.btnReportFormCancel) { showMain (); } }
  • 16. Audio Recording / File System • Audio recording through built-in device microphone in 3GP format • Captured to SD card storage • Playback review / re-record overwrite • Audio upload to server via HTTP Post
  • 17. Audio Recording / File System reportaudioform.xml <ScrollView xmlns:android=quot;http://schemas.android.com/apk/res/androidquot; android:id=quot;@+id/scrollReportFormquot; android:layout_width=quot;fill_parentquot; android:layout_height=quot;fill_parentquot; android:background=quot;@drawable/bgquot;> <LinearLayout android:id=quot;@+id/layoutReportFormquot; android:label=quot;Text Reportquot; android:layout_width=quot;fill_parentquot; android:layout_height=quot;wrap_contentquot; android:orientation=quot;verticalquot; android:gravity=quot;topquot; android:padding=quot;6.0spquot;> <TextView android:id=quot;@+id/labelPhotoHeaderquot; android:layout_width=quot;fill_parentquot; android:layout_height=quot;wrap_contentquot; android:text=quot;...quot;/> <RelativeLayout xmlns:android=quot;http://schemas.android.com/apk/res/androidquot; android:layout_width=quot;fill_parentquot; android:layout_height=quot;wrap_contentquot; android:padding=quot;10dpquot; android:layout_marginTop=quot;10pxquot;> private void setStatus (String status) { ((TextView)findViewById(R.id.labelAudioStatus)).setText(status); } Toast.makeText(getBaseContext(), quot;Thank you. Your report has been accepted!quot;, Toast.LENGTH_LONG).show();
  • 18. Audio Recording / File System (cont’d) private String startRecording (String filename) { setStatus (quot;Recording...quot;); ((TextView)findViewById(R.id.btnRecordAudio)).setText(quot;Stopquot;); String path = null; if (currentAudioFile != null) { path = currentAudioFile; } else { path = quot;/sdcard/quot; + filename + file_ext; } mRecorder = new MediaRecorder(); mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); mRecorder.setOutputFile(path); mRecorder.prepare(); private void playRecording (String path) mRecorder.start(); { setStatus (quot;Playing...quot;); return path; try } { mMediaPlayer = new MediaPlayer(); mMediaPlayer.setDataSource(path); mMediaPlayer.prepare(); mMediaPlayer.start(); } catch (IOException e) { e.printStackTrace(); } }
  • 19. Photo Capture & Display • Capture of photo from built-in camera • Captured in JPEG format at screen-size resolution (480x320) • Compressed from 3MP format on capture • Stored on local SD card (also accessible via USB mount or card reader) • Upload to server via HTTP Post
  • 20. Photo Capture & Display reportphotoform.xml <ImageView android:id=quot;@+id/previewphotoquot; android:layout_width=quot;wrap_contentquot; android:layout_height=quot;wrap_contentquot; android:layout_gravity=quot;topquot;/> PhotoFormActivity /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); currentPhotoPath = this.getIntent().getStringExtra(quot;photofilequot;); setContentView(R.layout.reportphotoform); ((Button)findViewById(R.id.btnTakePicture)).setOnClickListener(this); ((Button)findViewById(R.id.btnReportFormSubmit)).setOnClickListener(this); ((Button)findViewById(R.id.btnReportFormCancel)).setOnClickListener(this); if (currentPhotoPath != null) { Toast.makeText(getBaseContext(), quot;Ready to send photo: quot; + currentPhotoPath, Toast.LENGTH_LONG).show(); ((ImageView)findViewById(R.id.previewphoto)).setImageURI(Uri.parse(currentPhotoPath)); } }
  • 21. Photo Capture & Display (cont’d) camera.xml <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?> <LinearLayout xmlns:android=quot;http://schemas.android.com/apk/res/ androidquot; android:orientation=quot;verticalquot; android:layout_width=quot;fill_parentquot; android:layout_height=quot;fill_parentquot; android:background=quot;@drawable/bgquot;> <SurfaceView android:id=quot;@+id/surfacequot; android:layout_width=quot;fill_parentquot; android:layout_height=quot;10dipquot; android:layout_weight=quot;1quot;> </SurfaceView> </LinearLayout> ImageCaptureActivity: preview setup photo capture public void surfaceChanged(SurfaceHolder holder, int public void onPreviewFrame(byte[] data, Camera c) { format, int w, int h) { if (!sizeSet) Log.e(getClass().getSimpleName(), quot;surfaceChangedquot;); { if (isPreviewRunning) { Log.i(getClass().getSimpleName(), quot;preview frame camera.stopPreview(); RAW: quot; + data); } Camera.Parameters params = c.getParameters(); camera.setPreviewDisplay(holder); params.setPictureFormat(PixelFormat.JPEG); camera.startPreview(); params.setPictureSize(PHOTO_WIDTH,PHOTO_HEIGHT); isPreviewRunning = true; c.setParameters(params); } sizeSet = true; } }
  • 22. Photo Capture & Display (cont’d) Camera.PictureCallback mPictureCallbackJpeg= new Camera.PictureCallback() { public void onPictureTaken(byte[] data, Camera c) { Log.e(getClass().getSimpleName(), quot;PICTURE CALLBACK JPEG: data.length = quot; + data.length); String filename = timeStampFormat.format(new Date()); String baseDir = quot;/sdcard/quot;; if (new File(quot;/sdcard/dcim/Camera/quot;).exists()) { baseDir = quot;/sdcard/dcim/Camera/quot;; } currentPhotoFile = baseDir + filename + quot;.jpgquot;; try { FileOutputStream file = new FileOutputStream(new File(currentPhotoFile)); file.write(data); sendPicture(); } catch (Exception e){ e.printStackTrace(); } } }; Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback() { public void onShutter() { Log.e(getClass().getSimpleName(), quot;SHUTTER CALLBACKquot;); Camera.Parameters params = camera.getParameters(); params.setPictureFormat(PixelFormat.JPEG); params.setPictureSize(PHOTO_WIDTH,PHOTO_HEIGHT); camera.setParameters(params); } };
  • 23. Menu Dialog Options @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); MenuItem mItem = menu.add(0, 1, Menu.NONE, quot;Aboutquot;); MenuItem mItem2 = menu.add(0, 2, Menu.NONE, quot;Settingsquot;); MenuItem mItem3 = menu.add(0, 3, Menu.NONE, quot;Reportsquot;); mItem.setIcon(R.drawable.ic_menu_about); mItem2.setIcon(R.drawable.ic_menu_register); mItem3.setIcon(R.drawable.ic_menu_reports); return true; } public boolean onMenuItemSelected(int featureId, MenuItem item) { super.onMenuItemSelected(featureId, item); if (item.getItemId() == 1) showCredits(); else if (item.getItemId() == 2) showRegistration(); else if (item.getItemId() == 3) { showWebView (); } return true; }
  • 24. Embedded Web “Reports” View private void showWebView () { Intent iReportForm = new Intent(this, InternalWebView.class); String reportDisplayUrl = PreferenceDB.getInstance(this).getPref(GReporterConstants.PREFKEY_REPORT_DISPLAY_URL); iReportForm.putExtra(quot;urlquot;, reportDisplayUrl); startActivity(iReportForm); } <WebView android:id=quot;@+id/webviewquot; android:layout_width=quot;fill_parentquot; android:layout_height=quot;fill_parentquot; android:layout_weight=quot;1quot; /> mWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = mWebView.getSettings(); webSettings.setSavePassword(false); webSettings.setSaveFormData(false); webSettings.setJavaScriptEnabled(true); webSettings.setSupportZoom(false); mWebView.setWebChromeClient(new MyWebChromeClient()); mWebView.loadUrl(url);
  • 25. PreferencesDB - SQLite public class PreferenceDB { private static final String CREATE_TABLE_PREFS = quot;create table prefs (pref_id integer primary key autoincrement, quot; + quot;prefkey text not null, prefval text not null);quot;; private static final String PREFS_TABLE = quot;prefsquot;; private static final String DATABASE_NAME = quot;prefsdbquot;; private static final int DATABASE_VERSION = 2; public boolean insertPref(String key, String value) { @Override public void onCreate(SQLiteDatabase db) { deletePref(key); try { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); db.execSQL(CREATE_TABLE_PREFS); } ContentValues values = new ContentValues(); catch (Exception e) values.put(quot;prefkeyquot;, key); { values.put(quot;prefvalquot;, value); Log.i(DATABASE_NAME,quot;tables already existquot;); } } boolean resp = (db.insert(PREFS_TABLE, null, values) > 0); return resp; } Cursor c = db.query(PREFS_TABLE, new String[] {quot;prefvalquot; }, quot;prefkey=?quot;, new String[] {key}, null, null, null); int numRows = c.getCount(); if (numRows > 0) { c.moveToFirst(); result = c.getString(0); } c.close();
  • 27. PhoneGap Sample WORDPRESS FANCY Splash Screen MOBILE MENUS!
  • 28. PhoneGap <resources> <string name=quot;helloquot;>Hello World, PhoneGap</string> <string name=quot;app_namequot;>OpenIdeals</string> <string name=quot;urlquot;>file:///android_asset/index.html</string> </resources> <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?> <LinearLayout xmlns:android=quot;http://schemas.android.com/apk/res/androidquot; android:orientation=quot;verticalquot; android:layout_width=quot;fill_parentquot; android:layout_height=quot;fill_parentquot; > <WebView android:id=quot;@+id/appViewquot; android:layout_height=quot;wrap_contentquot; android:layout_width=quot;fill_parentquot; /> </LinearLayout> <meta http-equiv=quot;refreshquot; content=quot;3;url=http://openideals.com/quot;> </head> <body> <a href=quot;http://openideals.com/quot;><img src=quot;default.pngquot; id=quot;splashquot;></a> </body> </html>
  • 30. OpenIntents.org http://www.openintents.org
  • 31. PhoneGap.com • PhoneGap is a development tool that allows web developers to take advantage of the core features in the iPhone, Android, and Blackberry SDK using JavaScript.