Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
PROGRAMMING IN ANDROID IOANNIS (JOHN) PAPAVASILEIOU OCTOBER 24 2013 [email protected] WHAT IS IT • Software platform • Operating system • Key apps • Developers: • Google • Open Handset Alliance • Open Source (http://source.an droid.com/) SOFTWARE STACK DESIGN • Android ≠ Linux!!! • The kernel is based on Linux kernel version 3.x (source Wikipedia) • Written in C/C++ • Apps written in Java • Use of Dalvik VM • Runs .dex files (dalvic executables) API CAPABILITIES • Rich UI components • Threads and Background processing • Full network stack (Http, JSON) • Database and file system access • Access to hardware (Camera, Phone, GPS, sensors..) Many of the APIs provided map 1:1 to the underlying HAL crossing of process boundaries & call of system services code Includes window and notification managers Media services for playing and Interface that allows recording media the Android system Kernel, includes to call device drivers device drivers and memory management Source: http://source.android.com/devices/im ages/system-architecture.png LOW LEVEL ARCHITECTURE APP FUNDAMENTALS Every app lives in its own security sandbox: • Based on a multi-user linux system different user every app is a • Every app has a userID and files related to each ID are not visible to others • Apps with same ID can share files and processes • User has to grand permision to apps in order to access device data (ext. storage, camera, contacts, etc.) • Every app runs its own Linux process • Each process has it’s own Java VM APPLICATION COMPONENTS Every app may have: • Activities • A single screen with a UI. E.g. compose, read, list e-mails • Services • Run in the background to perform long-running operations. E.g. play music, fetch data over the network • Content Providers • Manage a shared set of app data. Other apps can query or modify the data. E.g. contacts • Broadcast Receivers • Respond to a system-wide broadcast announcement. E.g. screen turned off, low-battery. May initiate services or notifications ACTIVITIES • The basis of android applications • A single Activity defines a single viewable screen • the actions, not the layout • Can have multiple per application • Each is a separate entity • They have a structured life cycle • Different events in their life happen either via the user touching buttons or programmatically ACTIVITY LIFECYCLE The system can drop the activity from memory by just killing the process It might not reach this point! ACTIVITY RESTART • When there is a configuration change the app will be restarted by the system • Screen orientation • keyboard availability • Language • Etc. • To save the state of the Activity the developer has to use the onSaveInstanceState() method. • onCreate() or onRestoreInstancestate() will give you access to the restored state • We can prevent the restart of the activity by handling the configuration change manually • Android will save text that exists in text fields • onPause() is guaranteed to be called in any case SERVICES • Run in the background • Can continue even if Activity that started it dies • Should be used if something needs to be done while the user is not interacting with application • Otherwise, a thread is probably more applicable • Should create a new thread in the service to do work in, since the service runs in the main thread • Can be bound to an application • In which case will terminate when all applications bound to it unbind • Allows multiple applications to communicate with it via a common interface • Needs to be declared in manifest file • Like Activities, has a structured life cycle SERVICES LIFECYCLE One component calls startService() One component calls bindService(), It can communicate with the Ibinder interface One component calls stopService() or service calls To stop it calls stopSelf() unbindService(), Multiple clients can bind to the same service PROJECT COMPONENTS • src – your source code • gen – auto-generated code (usually just R.java) • Included libraries • Resources • Drawables (like .png images) • Layouts (define the UI) • Values (like strings) • Manifest file R CLASS Auto-generated: you shouldn’t edit it Contains IDs of the project resources Enforces good software engineering Use findViewById and Resources object to get access to the resources • Ex. Button buttonInfo = (Button)findViewById(R.id.buttonInfo); buttonInfo.setOnClickListener(buttonInfoClickListener); • Ex. helloStr = getResources().getString(R.string.hello)); STRINGS Nice way to localize apps: • res/values/strings.xml • res/values-en/strings.xml • res/values-fr/strings.xml • res/values-ja/strings.xml Application wide available strings Promotes good software engineering UI components made in the UI editor should have text defined in strings.xml Strings are just one kind of ‘Value’ there are many others AndroidManifest.Xml Central configuration file for your application • Permissions required from the app: • • E.g. access contacts, internet, vibration, camera, phone history, DB access Contains characteristics about your application • • Activities • Services • Content providers • Broadcast receivers Defines external libraries, like Google Maps API MANIFEST FILE EXAMPLE <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=http://schemas.android.com/apk/res/android package="com.abimed.ecg“ android:versionCode="5“ android:versionName="1.2.2"> <uses-sdk android:minSdkVersion="8"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.READ_CONTACTS"/> <uses-permission android:name="android.permission.WRITE_CONTACTS"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <application android:label="@string/app_name“ android:icon="@drawable/logo“ android:debuggable="false"> <uses-library android:name="com.google.android.maps"/> <activity android:name="com.abimed.ecg.EcgActivity“ android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name="com.abimed.ecg.Preferences" android:label="@string/set_preferences"/> android:name="com.abimed.ecg.About" android:label="@string/aboutActivity"/> <activity <activity android:name="com.abimed.ecg.Report" android:label="@string/reportActivity"/> <activity android:name="com.abimed.ecg.GraphInfo" android:label="@string/graphInfoActivity"/> <activity android:name=".patients.Patients" android:label="@string/patients"/> <activity android:name=".patients.ViewPatient" android:label="@string/patient"/> <activity android:name=".patients.PatientInfo" android:theme="@android:style/Theme.NoTitleBar"/> <activity android:name=".patients.PatientEdit" android:theme="@android:style/Theme.NoTitleBar"/> </application> </manifest> TOOLS TO DEVELOP • Phone • Eclipse ( http://www.eclipse.org/downloads/ ) • Android Plugin (ADT) • Android SDK ( http://developer.android.com/sdk/index.html ) • Install everything except Additional SDK Platforms, unless you want to • Through the SDK Manager we can create Android Virtual Devices HELLO WORLD LAYOUTS • Declare UI elements in XML • Separates presentation from actual code • Declare multiple layouts depending on: • • Orientation Screen size, etc. • Visualize easy to debug • Eclipse has nice Drag n Drop editor • Instantiate layout elements at runtime • Fast and easy when the layout is simple: • • Has a few View elements Has only a surface vew like GLSurfaceView HELLO WORLD LAYOUT <!-- mainLayout.xml - -> <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> Only one root <EditText android:id="@+id/edit_message" android:layout_weight="1" element android:layout_width="0dp" android:layout_height="wrap_content" Additional elements android:hint=“Enter a message" /> <Button as children android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=“Send “ android:onClick="sendMessage" /> </LinearLayout> MAIN ACTIVITY public class MainActivity extends Activity { public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.mainLayout); // Make sure we're running on Honeycomb or higher to use ActionBar APIs if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { // Show the Up button in the action bar. getActionBar().setDisplayHomeAsUpEnabled(true); } } /** Called when the user clicks the Send button */ public void sendMessage(View view) { Intent intent = new Intent(this, DisplayMessageActivity.class); EditText editText = (EditText) findViewById(R.id.edit_message); String message = editText.getText().toString(); intent.putExtra(EXTRA_MESSAGE, message); startActivity(intent); } } DISPLAY MESSAGE ACTIVITY public class DisplayMessageActivity extends Activity { @SuppressLint("NewApi") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Get the message from the intent Intent intent = getIntent(); String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE); // Create the text view TextView textView = new TextView(this); textView.setTextSize(40); textView.setText(message); // Set the text view as the activity layout setContentView(textView); } } INTENTS Send user to another App: • Implicit intent: • • Uri number = Uri.parse("tel:5551234"); Intent callIntent = new Intent(Intent.ACTION_DIAL, number); • Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountai n+View,+California"); callIntent = new Intent(Intent.ACTION_VIEW, location); startActivity(callIntent); When multiple apps can handle the intent APP CHOOSER Intent intent = new Intent(Intent.ACTION_SEND); ... // Always use string resources for UI text. // This says something like "Share this photo with" String title = getResources().getString(R.string.chooser_title); // Create and start the chooser Intent chooser = Intent.createChooser(intent, title); startActivity(chooser); STORAGE OPTIONS.. SHARED PREFERENCES • • Store key-value sets Good for small sets public class Calc extends Activity { public static final String PREFS_NAME = "MyPrefsFile"; @Override protected void onCreate(Bundle state){ super.onCreate(state); ... // Restore preferences SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); boolean silent = settings.getBoolean("silentMode", false); setSilent(silent); } @Override protected void onStop(){ super.onStop(); // We need an Editor object to make preference changes. // All objects are from android.context.Context SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); editor.putBoolean("silentMode", mSilentMode); // Commit the edits! editor.commit(); } } FILE STORAGE Internal External • Always available • • Files accesible only • by the app • When the app is uninstalled, files are deleted • Not always available World-readable When app is uninstalled, files will be deleted if the directory is gotten from getExternalFilesDir() INTERNAL STORAGE String FILENAME = “myfile.txt"; String string = "hello world!"; FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE); fos.write(string.getBytes()); fos.close(); • When there is a need to cache some files use method: File createTempFile (String prefix, String suffix) EXTERNAL STORAGE <manifest ... > <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> ... </manifest> /* Checks if external storage is available for read and write */ public boolean isExternalStorageWritable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { return true; } return false; } /* Checks if external storage is available to at least read */ public boolean isExternalStorageReadable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { return true; } return false; } public File getAlbumStorageDir(Context context, String albumName) { // Get the directory for the app's private pictures directory. File file = new File(context.getExternalFilesDir( Environment.DIRECTORY_PICTURES), albumName); if (!file.mkdirs()) { Log.e(LOG_TAG, "Directory not created"); } return file; } CREATE DATABASE public class DictionaryOpenHelper extends SQLiteOpenHelper { private static final int DATABASE_VERSION = 2; private static final String DICTIONARY_TABLE_NAME = "dictionary"; private static final String DICTIONARY_TABLE_CREATE = "CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" + KEY_WORD + " TEXT, " + KEY_DEFINITION + " TEXT);"; DictionaryOpenHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(DICTIONARY_TABLE_CREATE); } } PUT INFO INTO THE DATABASE / Gets the data repository in write mode SQLiteDatabase db = mDbHelper.getWritableDatabase(); // Create a new map of values, where column names are the keys ContentValues values = new ContentValues(); values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id); values.put(FeedEntry.COLUMN_NAME_TITLE, title); values.put(FeedEntry.COLUMN_NAME_CONTENT, content); // Insert the new row, returning the primary key value of the new row long newRowId; newRowId = db.insert( FeedEntry.TABLE_NAME, FeedEntry.COLUMN_NAME_NULLABLE, values); SENSORS • Types: • Motion sensors • Environmental sensors • Position sensors • Sensor Framework: • • • • Get available sensors Get sensor capabilities Acquire raw data for a given minimum rate Register for sensor event listeners MAGNETOMETER AVAILABILITY CHECK private SensorManager mSensorManager; ... mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); if (mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){ // Success! There's a magnetometer. } else { // Failure! No magnetometer. } GET DATA EVENTS FROM THE LIGHT SENSOR public class SensorActivity extends Activity implements SensorEventListener { private SensorManager mSensorManager; private Sensor mLight; @Override public final void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); } @Override public final void onAccuracyChanged(Sensor sensor, int accuracy) { // Do something here if sensor accuracy changes. } @Override public final void onSensorChanged(SensorEvent event) { // The light sensor returns a single value. // Many sensors return 3 values, one for each axis. float lux = event.values[0]; // Do something with this sensor value. } @Override protected void onResume() { super.onResume(); mSensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { super.onPause(); mSensorManager.unregisterListener(this); } } CONNECTIVITY Several APIs to let the app connect and interact with other devices: • Bluetooth • NFC • Wi-Fi P2P • USB • SIP USER LOCATION <manifest ... > <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> ... </manifest> // Acquire a reference to the system Location Manager LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); // Define a listener that responds to location updates LocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) { // Called when a new location is found by the network location provider. makeUseOfNewLocation(location); } public void onStatusChanged(String provider, int status, Bundle extras) {} public void onProviderEnabled(String provider) {} public void onProviderDisabled(String provider) {} }; // Register the listener with the Location Manager to receive location updates locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); TOAST Context context = getApplicationContext(); CharSequence text = "Hello toast!"; int duration = Toast.LENGTH_SHORT; Toast toast = Toast.makeText(context, text, duration); toast.show(); SEND SMS <manifest ... > <uses-permission android:name="android.permission.SEND_SMS"/> ... </manifest> /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); btnSendSMS = (Button) findViewById(R.id.btnSendSMS); txtPhoneNo = (EditText) findViewById(R.id.txtPhoneNo); txtMessage = (EditText) findViewById(R.id.txtMessage); btnSendSMS.setOnClickListener(new View.OnClickListener() { public void Onclick(View v) { String phoneNo = txtPhoneNo.getText().toString(); String message = txtMessage.getText().toString(); if (phoneNo.length()>0 && message.length()>0) sendSMS(phoneNo, message); else Toast.makeText(getBaseContext(), "Please enter both phone number and message.",Toast.LENGTH_SHORT).show(); }}); } SEND SMS private void sendSMS(String phoneNumber, String message) { SmsManager sms = SmsManager.getDefault(); sms.sendTextMessage(phoneNumber, null, message, null, null); } GOOGLE LOCATION SERVICES • Fused location provider: • • Gives the bests location according to the needs • “high accuracy”, “low power”, etc. Geofencing APIs: • • App will receive notifications when the user enters specific geographic boundaries Activity recognition: • • • • • • In a vehicle On a bicycle On foot Still Tilting Unknown MY APP THANKS!