Intro to Android for iOS developers

Preview:

DESCRIPTION

Curious about Android, but never found the time to look into it? Come to this session for an accelerated introduction. We will look at the basic structure of an Android app, then deep dive into two aspects that differentiate Android from iOS: layout and intents. How does the layout system deal with the myriad of Android devices? How do intents facilitate deep integration among Android apps?

Citation preview

Intro to Androidfor iOS developers

Chiu-Ki Chan@chiuki

@chiuki@chiuki

@chiuki@chiuki

Hello WorldLayouts

Intents & Components

Hello World

@chiuki

@chiuki

ViewController

@chiuki

@chiuki

@chiuki

xib

@chiuki

@chiuki

@chiuki

@chiuki

@chiuki

IBOutlet

@chiuki

@chiuki@chiuki

Center<TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" />

@chiuki

@chiuki@chiuki

Button<Button android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="@string/add" />

@chiuki

LinearLayout

@chiuki

@chiuki@chiuki

LinearLayout<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" > <TextView android:id="@+id/count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="128sp" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/add" android:onClick="add" /></LinearLayout>

@chiuki@chiuki

IBAction<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" > <TextView android:id="@+id/count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="128sp" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/add" android:onClick="add" /></LinearLayout>

@chiuki@chiuki

IBActionpublic class MainActivity extends Activity { private TextView countView; private int count = 0;

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); countView = (TextView) findViewById(R.id.count); updateCount(); }

public void add(View v) { count += 1; updateCount(); }

private void updateCount() { countView.setText(String.valueOf(count)); }}

android:onClick="add"

@chiuki@chiuki

Update viewpublic class MainActivity extends Activity { private TextView countView; private int count = 0;

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); countView = (TextView) findViewById(R.id.count); updateCount(); }

public void add(View v) { count += 1; updateCount(); }

private void updateCount() { countView.setText(String.valueOf(count)); }}

@chiuki

@chiuki

@chiuki

RelativeLayout

@chiuki

@chiuki

@chiuki

@chiuki

@chiuki

<RelativeLayout> <TextView android:id="@+id/count" android:layout_centerInParent="true" /> <Button android:id="@+id/reset" android:layout_below="@id/count" android:layout_centerHorizontal="true" android:text="@string/reset" /> <Button android:layout_below="@id/count" android:layout_toLeftOf="@id/reset" android:text="@string/subtract" /> <Button android:layout_below="@id/count" android:layout_toRightOf="@id/reset" android:text="@string/add" /></RelativeLayout>

@chiuki

<RelativeLayout> <TextView android:id="@+id/count" android:layout_centerInParent="true" /> <Button android:id="@+id/reset" android:layout_below="@id/count" android:layout_centerHorizontal="true" android:text="@string/reset" /> <Button android:layout_below="@id/count" android:layout_toLeftOf="@id/reset" android:text="@string/subtract" /> <Button android:layout_below="@id/count" android:layout_toRightOf="@id/reset" android:text="@string/add" /></RelativeLayout>

@chiuki

<RelativeLayout> <TextView android:id="@+id/count" android:layout_centerInParent="true" /> <Button android:id="@+id/reset" android:layout_below="@id/count" android:layout_centerHorizontal="true" android:text="@string/reset" /> <Button android:layout_below="@id/count" android:layout_toLeftOf="@id/reset" android:text="@string/subtract" /> <Button android:layout_below="@id/count" android:layout_toRightOf="@id/reset" android:text="@string/add" /></RelativeLayout>

@chiuki

<RelativeLayout> <TextView android:id="@+id/count" android:layout_centerInParent="true" /> <Button android:id="@+id/reset" android:layout_below="@id/count" android:layout_centerHorizontal="true" android:text="@string/reset" /> <Button android:layout_toLeftOf="@id/reset" android:text="@string/subtract" /> <Button android:layout_below="@id/count" android:layout_toRightOf="@id/reset" android:text="@string/add" /></RelativeLayout>

@chiuki

<RelativeLayout> <TextView android:id="@+id/count" android:layout_centerInParent="true" /> <Button android:id="@+id/reset" android:layout_below="@id/count" android:layout_centerHorizontal="true" android:text="@string/reset" /> <Button android:layout_below="@id/count" android:layout_toLeftOf="@id/reset" android:text="@string/subtract" /> <Button android:layout_below="@id/count" android:layout_toRightOf="@id/reset" android:text="@string/add" /></RelativeLayout>

@chiuki@chiuki

Device Preview

@chiuki@chiuki

Bigger text on tablets

Resource Folders

@chiuki@chiuki

textSize<TextView android:id="@+id/count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="128sp" />

res/layout/activity_main.xml

@chiuki@chiuki

res/values/dimens.xml<TextView android:id="@+id/count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="@dimen/counter_size" />

res/layout/activity_main.xml

<dimen name="counter_size" value="128sp" />

res/values/dimens.xml

@chiuki@chiuki

res/values-sw600dp/dimens.xml<TextView android:id="@+id/count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="@dimen/counter_size" />

res/layout/activity_main.xml

<dimen name="counter_size" value="128sp" />

<dimen name="counter_size" value="256sp" />

res/values/dimens.xml

res/values-sw600dp/dimens.xml

@chiuki@chiuki

Resource Folders

Type Variation

layoutvalues

drawablemenu

Language & Region: en, fr, fr-rCA, jaScreen size: small, large, sw600dp, h400dpScreen orientation: port, landScreen density: ldpi, mdpi, hdpi, xhdpi, nodpi, tvdpiPlatform version: v4, v11, v14UI mode: car, desk, television, appliance

http://developer.android.com/guide/topics/resources/providing-resources.html

@chiuki@chiuki

Resource Folders

Type Variation

layoutvalues

drawablemenu

Language & Region: en, fr, fr-rCA, jaScreen size: small, large, sw600dp, h400dpScreen orientation: port, landScreen density: ldpi, mdpi, hdpi, xhdpi, nodpi, tvdpiPlatform version: v4, v11, v14UI mode: car, desk, television, appliance

http://developer.android.com/guide/topics/resources/providing-resources.html

res/values-sw600dp/dimens.xml

@chiuki@chiuki

Resource Folders

Type Variation

layoutvalues

drawablemenu

Language & Region: en, fr, fr-rCA, jaScreen size: small, large, sw600dp, h400dpScreen orientation: port, landScreen density: ldpi, mdpi, hdpi, xhdpi, nodpi, tvdpiPlatform version: v4, v11, v14UI mode: car, desk, television, appliance

http://developer.android.com/guide/topics/resources/providing-resources.html

res/drawable-hdpi/ic_launcher.png

@chiuki@chiuki

Resource Folders

Type Variation

layoutvalues

drawablemenu

Language & Region: en, fr, fr-rCA, jaScreen size: small, large, sw600dp, h400dpScreen orientation: port, landScreen density: ldpi, mdpi, hdpi, xhdpi, nodpi, tvdpiPlatform version: v4, v11, v14UI mode: car, desk, television, appliance

http://developer.android.com/guide/topics/resources/providing-resources.html

res/drawable-hdpi/ic_launcher.png @2x

@chiuki@chiuki

Resource Folders

Type Variation

layoutvalues

drawablemenu

Language & Region: en, fr, fr-rCA, jaScreen size: small, large, sw600dp, h400dpScreen orientation: port, landScreen density: ldpi, mdpi, hdpi, xhdpi, nodpi, tvdpiPlatform version: v4, v11, v14UI mode: car, desk, television, appliance

http://developer.android.com/guide/topics/resources/providing-resources.html

res/layout-ja/name.xml

Activity Lifecycle

@chiuki@chiuki

onCreate()

Activity Lifecycle

@chiuki@chiuki

onCreate()

Activity Lifecycle

@chiuki@chiuki

onCreate() viewDidLoad:

Activity Lifecycle

@chiuki@chiuki

onCreate() viewDidLoad:

onStart()

Activity Lifecycle

@chiuki@chiuki

onCreate() viewDidLoad:

onStart()onResume()

Activity Lifecycle

@chiuki@chiuki

onCreate() viewDidLoad:

onStart()onResume()

viewWillAppear:viewDidAppear:

Activity Lifecycle

@chiuki@chiuki

onCreate() viewDidLoad:

onStart()onResume()

viewWillAppear:viewDidAppear:

onPause()

Activity Lifecycle

@chiuki@chiuki

onCreate() viewDidLoad:

onStart()onResume()

viewWillAppear:viewDidAppear:

onPause()onStop()

Activity Lifecycle

@chiuki@chiuki

onCreate() viewDidLoad:

onStart()onResume()

viewWillAppear:viewDidAppear:

onPause()onStop()

viewWillDisappear:viewDidDisappear:

Activity Lifecycle

@chiuki@chiuki

onCreate() viewDidLoad:

onStart()onResume()

viewWillAppear:viewDidAppear:

onPause()onStop()

viewWillDisappear:viewDidDisappear:

onDestroy()

Activity Lifecycle

@chiuki@chiuki

onCreate() viewDidLoad:

onStart()onResume()

viewWillAppear:viewDidAppear:

onPause()onStop()

viewWillDisappear:viewDidDisappear:

onDestroy() viewDidUnload:

Activity Lifecycle

@chiuki@chiuki

onCreate() viewDidLoad:

onStart()onResume()

viewWillAppear:viewDidAppear:

onPause()onStop()

viewWillDisappear:viewDidDisappear:

onDestroy() viewDidUnload:

Activity Lifecycle

@chiuki@chiuki

Visibility

More Activities

@chiuki@chiuki

startActivity (explicit)Intent intent = new Intent(this, NumberActivity.class);intent.putExtra("count", count);startActivity(intent);

@chiuki@chiuki

startActivity (explicit)Intent intent = new Intent(this, NumberActivity.class);intent.putExtra("count", count);startActivity(intent);

@chiuki@chiuki

startActivity (explicit)Intent intent = new Intent(this, NumberActivity.class);intent.putExtra("count", count);startActivity(intent);

@chiuki@chiuki

startActivity (implicit)Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://twitter.com/chiuki"));startActivity(intent);

@chiuki@chiuki

startActivity (implicit)Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://twitter.com/chiuki"));startActivity(intent);

@chiuki@chiuki

startActivity (implicit)Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://twitter.com/chiuki"));startActivity(intent);

@chiuki@chiuki

startActivity (implicit)Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://twitter.com/chiuki"));startActivity(intent);

@chiuki@chiuki

Register your Activity<activity android:name=".YourActivity"> <intent-filter>   <action android:name="android.intent.action.VIEW" />    <category android:name="android.intent.category.DEFAULT" />    <category android:name="android.intent.category.BROWSABLE" />   <data android:scheme="http" android:host="twitter.com" />  </intent-filter></activity>

AndroidManifest.xml

Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://twitter.com/chiuki"));startActivity(intent);

Info.plist

@chiuki@chiuki

IntentFilter: Action<activity android:name=".YourActivity"> <intent-filter>   <action android:name="android.intent.action.VIEW" />    <category android:name="android.intent.category.DEFAULT" />    <category android:name="android.intent.category.BROWSABLE" />   <data android:scheme="http" android:host="twitter.com" />  </intent-filter></activity>

AndroidManifest.xml

Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://twitter.com/chiuki"));startActivity(intent);

@chiuki@chiuki

IntentFilter: Data<activity android:name=".YourActivity"> <intent-filter>   <action android:name="android.intent.action.VIEW" />    <category android:name="android.intent.category.DEFAULT" />    <category android:name="android.intent.category.BROWSABLE" />   <data android:scheme="http" android:host="twitter.com" />  </intent-filter></activity>

AndroidManifest.xml

Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://twitter.com/chiuki"));startActivity(intent);

@chiuki@chiuki

IntentFilter: Category<activity android:name=".YourActivity"> <intent-filter>   <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" />    <category android:name="android.intent.category.BROWSABLE" />   <data android:scheme="http" android:host="twitter.com" />  </intent-filter></activity>

AndroidManifest.xml

Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://twitter.com/chiuki"));startActivity(intent);

@chiuki@chiuki

IntentFilter: Category<activity android:name=".YourActivity"> <intent-filter>   <action android:name="android.intent.action.VIEW" />    <category android:name="android.intent.category.DEFAULT" />    <category android:name="android.intent.category.BROWSABLE" />   <data android:scheme="http" android:host="twitter.com" />  </intent-filter></activity>

AndroidManifest.xml

Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://twitter.com/chiuki"));startActivity(intent);

@chiuki@chiuki

Intent Data<activity android:name=".YourActivity"> <intent-filter>   <action android:name="android.intent.action.VIEW" />    <category android:name="android.intent.category.DEFAULT" />    <category android:name="android.intent.category.BROWSABLE" />   <data android:scheme="http" android:host="twitter.com" />  </intent-filter></activity>

Uri uri = getIntent().getData();

AndroidManifest.xml

YourActivity.java

@chiuki@chiuki

startActivityForResultprivate static final int REQUEST_CODE_CAMERA = 1;Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);startActivityForResult(intent, REQUEST_CODE_CAMREA);

protected void onActivityResult( int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_CAMERA && resultCode == RESULT_OK) { Bitmap bitmap = (Bitmap) data.getExtras().get("data"); }}

@chiuki@chiuki

startActivityForResultprivate static final int REQUEST_CODE_CAMERA = 1;Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);startActivityForResult(intent, REQUEST_CODE_CAMERA);

protected void onActivityResult( int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_CAMERA && resultCode == RESULT_OK) { Bitmap bitmap = (Bitmap) data.getExtras().get("data"); }}

@chiuki@chiuki

Providing ResultIntent data = new Intent();data.putExtra("data", bitmap);setResult(RESULT_OK, data);finish();

protected void onActivityResult( int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_CAMERA && resultCode == RESULT_OK) { Bitmap bitmap = (Bitmap) data.getExtras().get("data"); }}

@chiuki@chiuki

Intent DataIntent data = new Intent();data.putExtra("data", bitmap);setResult(RESULT_OK, data);finish();

protected void onActivityResult( int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_CAMERA && resultCode == RESULT_OK) { Bitmap bitmap = (Bitmap) data.getExtras().get("data"); }}

@chiuki@chiuki

Result CodeIntent data = new Intent();data.putExtra("data", bitmap);setResult(RESULT_OK, data);finish();

protected void onActivityResult( int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_CAMERA && resultCode == RESULT_OK) { Bitmap bitmap = (Bitmap) data.getExtras().get("data"); }}

@chiuki@chiuki

Share intent

Intent intent = new Intent(Intent.ACTION_SEND);

intent.putExtra(Intent.EXTRA_SUBJECT, subject);intent.putExtra(Intent.EXTRA_TEXT, message);

intent.setType("image/*");Uri uri = Uri.fromFile(new File(path));intent.putExtra(Intent.EXTRA_STREAM, uri);

@chiuki@chiuki

IntentFilter: Type<activity android:name=".YourActivity"> <intent-filter>   <action android:name="android.intent.action.ACTION_SEND" />    <category android:name="android.intent.category.DEFAULT" />   <data android:mimeType="image/*" />  </intent-filter></activity>

AndroidManifest.xml

Intent intent = new Intent(Intent.ACTION_SEND);intent.setType("image/*");

@chiuki@chiuki

Intent Data

String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);String message = intent.getStringExtra(Intent.EXTRA_TEXT);Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);

YourActivity.java

Intent intent = new Intent(Intent.ACTION_SEND);

intent.putExtra(Intent.EXTRA_SUBJECT, subject);intent.putExtra(Intent.EXTRA_TEXT, message);

intent.setType("image/*");Uri uri = Uri.fromFile(new File(path));intent.putExtra(Intent.EXTRA_STREAM, uri);

Beyond Activities

@chiuki@chiuki

Service BroadcastReceiver

ContentProvider Notification

@chiuki@chiuki

Service

Look ma, no UI!

@chiuki@chiuki

Service

Long-running

@chiuki@chiuki

BroadcastReceiver

Respond

@chiuki@chiuki

BroadcastReceiver

Respond

Battery low

Wifi connected

Incoming SMSApp installed

Screen off

@chiuki@chiuki

ContentProvider

Provide data to other apps

@chiuki@chiuki

ContentProvider

Provide data to other apps

Contacts

Images Music

Calendar

@chiuki@chiuki

ContentProvider

Internal data(unless you need SQLite interface)

@chiuki@chiuki

Notification

Notify

@chiuki@chiuki

Notify

@chiuki@chiuki

Notification

Communicate with background Service

@chiuki@chiuki

Background Service

Case study

@chiuki

Email Outbox

@chiuki

@chiuki@chiuki

Notification

@chiuki@chiuki

AlarmService

@chiuki@chiuki

Connectivity change

Summary

@chiuki@chiuki

Summary

Hello WorldLayoutsResource FoldersActivity LifecycleIntents & ComponentsCase Study

@chiuki@chiuki

Thank you!

http://eepurl.com/lR5uDhttp://blog.sqisland.comhttp://twitter.com/chiuki