SlideShare a Scribd company logo
Android
Intermediate
Ahmad Arif Faizin
What will we learn?
- Building UI (Responsive Design)
- AsyncTask (JSON Parsing)
- RecyclerView
- Intent
- Lifecycle
- Preferences
- SQLite
- Content Provider
- Background Task (Notification & Sync)
The master has failed
more times than the
beginner has even tried.
“
”
Sunshine Project Exercise
Sunshine Project
https://github.com/udacity/ud851-Sunshine
Toys Project
https://github.com/udacity/ud851-Exercises
Android Intermediatte IAK full
Android Intermediatte IAK full
Flow
1. Impot.ExerciseProject();
2. Shift*2 (TODO);
3. for (i=0; i<TODO.size();i++){TODO.execute();}
4. while (!Succed){try();}
5. Import.NextExerciseProject
LESSON 1
Make Sunshine Project
Exercise 1 - Create Layout
Exercise 1.1 - Create Layout
Flow
Flow
Exercise 1.2 - DisplayToyList
Add an ID
@ sebagai pembeda bahwa itu bukan String, tapi untuk
mencari/menambahkan isi di dalam Resource
+ sebagai tanda bahwa untuk menambahkan id baru, bukan
untuk mencari
tv_tv_names : nama id dalam bentuk Snake Case
snake_caseCamelCase
Make array of String
1. Create New JavaClass “ToyBox.java”
2. public static String[] getToyNames() {
return new String[] {
"Tazos",
“...........”
};
}
3. Panggil dalam MainActivity
String[] toyNames = ToyBox.getToyNames();
Show dummy Data
for (String toyName : toyNames) {
mToysListTextView.append(toyName + "nnn");
}
--------------- or ---------------
for (int i = 0; i<toyNames.lenght; i++) {
mToysListTextView.append(toyNames[i] + "nnn");
}
Make dummy Data
teks.SetText(“Halo”);
teks.SetText(“Akhirat”);
Output :
“Akhirat”
teks.append(“Halo”);
teks.append(“Akhirat”);
Output :
“HaloAkhirat”
Exercise 1.3 - Add Scrolling View
NOW IS YOUR
TIME...
>>Create Layout Sunshine Project
S.01-01
S.01-02
S.01-03
LESSON 2
Connect to Internet
Logging
Log.d(“string key”,”string isi”);
Log.e --> Error
Log.w --> Warning
Log.e --> Info
Log.d --> Debug
Log.v --> Verbose
T02.01-
Exercise-CreateLayout
T02.02-Exercise-AddMenu
- Buat resource “Menu”
- Add MenuItem
- Override onCreateOptionMenu kemudian inflate MenuItem
- Override onOptionItemSelected untuk EventHandling
T02.03-Exercise-DisplayUrl
https://api.github.com/search/repositories?q=android
&sort=stars
Make URLHTTP Request
T02.04-Exercise-
ConnectingToTheInternet
Add Permission
<uses-permission android:name="android.permission.INTERNET"/>
Then try to Run It..
NetworkOnMainThread
Exception
NetworkOnMainThread
Exception
Akses Network tidak boleh di Main Thread
Android Intermediatte IAK full
Android Intermediatte IAK full
Android Intermediatte IAK full
T02.05-
Exercise-CreateAsyncTask
T02.06-
Exercise-AddPolish
- Check if there is no connection
- Add progress bar
JSON FORMAT
Example of JSON Format
JSON Format
JSON Object
{ "key" : value}
JSON Array
[value, value, value]
Use https://jsonlint.com/ or https://jsonformatter.curiousconcept.com/
EXAMPLE OF JSON FORMAT
NOW IS YOUR
TIME...
>>Create Networking
Get API Key
Get Open Weather API Key
https://www.openweathermap.org/appid
Example Query:
http://api.openweathermap.org/data/2.5/forecast/daily?q=ambarawa&
mode=json&units=metric&cnt=7&APPID=93a3696714297ee5a9f6548
6aa8cb824
Supaya rapi pakai JSON Formatter / JSON Linter
S02.01-Exercise-Networking
S02.02-Exercise-Menus
S02.03-Exercise-Polish
Other Solution :
Library for HTTP Request
Source : http://stackoverflow.com/questions/16902716/comparison-of-android-
networking-libraries-okhttp-retrofit-and-volley
LESSON 3
RecyclerView
UI Evolution
UI Evolution
RecyclerView
Nice References ;
https://wirasetiawan29.wordpress.com/2016/03/04/viewholder-di-android/
https://medium.com/@ocittwo/recyclerview-dan-adapternya-ce6332a0833
RecyclerView vs ListView
+ ViewHolder Pattern
+ LayoutManager (Linear, Grid, Staggered)
+ Item animators and item decorators
+ More explicit click listeners
Quiz
Quiz Answer
RecyclerView
Source :
https://medium.com/@ocittwo/recyclerview-dan-adapternya-ce6332a0833
LinearLayoutManager GridLayoutManager StaggeredLayoutManager
T03.01-
Exercise-RecyclerViewLayout
1. Add Dependency in build.gradle(Module:app) >sync now
compile 'com.android.support:recyclerview-v7:25.3.1'
2. Add RecyclerView in xml with ID
T03.02-
Exercise-ViewHolder
1. Add Dependency in build.gradle(Module:app) >sync now
compile 'com.android.support:recyclerview-v7:25.3.1'
2. Add RecyclerView in xml with ID
3. Add item_list.xml design
4. Add Adapter.java
Make ViewHolder Class extends RecyclerView.ViewHolder
RecyclerView
Source :
https://medium.com/@ocittwo/recyclerview-dan-adapternya-ce6332a0833
RecyclerView
Source :
https://medium.com/@ocittwo/recyclerview-dan-adapternya-ce6332a0833
T03.03-
Exercise-RecyclerViewAdapter
4. Add Adapter.java
- Make ViewHolder Class extends RecyclerView.ViewHolder
- Make Adapter Class Extends
RecylerView.Adapter<RecyclerView.ViewHolder>
- Implement method
- onCreateViewHolder > untuk inflate layout_item
- onBindViewHolder > untuk proses tiap-tiap komponen
- getItemCount > jumlah list data
T03.04-Exercise-
WiringUpRecyclerView
1. Add Dependency in build.gradle(Module:app) >sync now
compile 'com.android.support:recyclerview-v7:25.3.1'
2. Add RecyclerView in xml with ID
3. Add item_list.xml design
4. Add Adapter.java then setAdapter
5. Add LayoutManager then setLayoutManager
T03.07-Exercise-
RecyclerViewClickHandling
1. Make ListItemClickListener
2. Implement OnClickListener in ViewHolder
My Way
1. Tambahkan pada Constructor Adapter
(int[] data, Context context)
2. Sehingga saat manggil Adapter jadi Adapter(dataAngka,this);
3. holder.cardview.setOnClickLister
NOW IS YOUR
TIME...
>>Create RecyclerView
S03.01-Exercise-RecyclerView
S03.02-Exercise-ClickHandling
LESSON 4
Intent
New Activity
Create Activity
Klik kanan pada package > new > activity > blank activity > OK
Change Launcher Activity
Move <intent-filter> in Android Manifest ke Activity yg pertama
Implisit Intent
Intent pindah =
new Intent (MainActivity.this, TujuanActivity.class);
context , class tujuan
startActivity(pindah);
PutExtra
Intent pindah =
new Intent (MainActivity.this, TujuanActivity.class)
pindah.putExtra(“key1”,”value1”);
pindah.putExtra(“key2”,2);
startActivity(pindah);
GetExtra
String data1 = getIntent().getStringExtra(“key1”);
String data1 = getIntent().getIntExtra(“key2”);
Explisit Intent
Intent.ACTION_DIAL/Intent.ACTION_CALL
Intent.ACTION_SEARCH
Intent.ACTION_SEND
Intent.ACTION_VIEW
Intent.ACTION_OPEN_DOCUMENT
AlarmClock.ACTION_SET_ALARM
MediaStore.ACTION_IMAGE_CAPTURE
More : https://developer.android.com/guide/components/intents-common.html
Intent Share
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("text/plain");
share.putExtra(Intent.EXTRA_SUBJECT, "ID-Networkers");
share.putExtra(Intent.EXTRA_TEXT, "http://idn.id");
startActivity(Intent.createChooser(share, "Share link!"));
Send to Frgament
NOW IS YOUR
TIME...
>>Create RecyclerView
S04.01-LaunchNewActivity
S04.02-DisplayDayForecast.
S04.03-AddMapAndSharing.
LESSON 5
LifeCycle
Get Data from API
http://openweathermap.org/appid
Example of API Request
http://api.openweathermap.org/data/2.5/forecast/daily?
q=ambarawa&mode=json&units=metric&cnt=7
&APPID=93a3696714297ee5a9f65486aa8cb824
Try to Rotate
Your App!
What happen?
T05a.01-Exercise-LogLifecycle
T05a.02-Exercise-PersistData
Save to instanceState
- Override Method onSaveInstanceState
- outstate.putString(“KEY”, “VALUE”);
di onCreate
- if (savedInstanceStated != null) {
String DataSimpanan = savedInstanceState.getString(“KEY”);
}
AsynctaskLoader
3 STEPS TO USE LOADER
T05a.02-Exercise-PersistData
Save to instanceState
https://classroom.udacity.com/courses/ud851/lessons/ed13cc93-
2861-43bf-b7ed-395a166ab975/concepts/29dfb358-58ec-4364-
8f1d-74488de38424
Why AsynctaskLoader?
T05b.02 -AddAsyncTaskLoader
T05b.03-PolishAsyncTask
Tips ketika di-rotate tetep
Manifest
android:configChanges="orientation|screenSize"
Activity
@Override
public void onConfigurationChanged(Configuration
newConfig) {
super.onConfigurationChanged(newConfig);
}
NOW IS YOUR
TIME...
>>Create RecyclerView
S05.01-Exercise-AsyncTaskLoader
LESSON 6
Preferences
Android Intermediatte IAK full
SharedPreferences
- Used for save setting
Format
”Key”,”Value”
Android Intermediatte IAK full
Android Intermediatte IAK full
T06.01-SetupTheActivity
T06.02-PreferenceFragment
How to use
Method 1
public static final String PREFS_NAME = "AOP_PREFS";
SharedPreferences pref= getSharedPreferences(PREFS_NAME,
Context.MODE_PRIVATE);
Method 2
SharedPreferences pref=
PreferenceManager.getDefaultSharedPreferences(context)
How to Use
How to Use
How to Input
SharedPreferences pref =
getApplicationContext().getSharedPreferences("MyChar", 0);
SharedPreferences.Editor editor = pref.edit();
editor.putString("KEY", “VALUE”);
editor.commit();
How to Get
SharedPreferences pref =
getApplicationContext().getSharedPreferences("MyChar", 0);
String karakter = pref.getString("KEY", “Default Value”);
Use @string / Constanta
for Key
>>Best Practice
T06.03-GetSharedPreferences
How to Get
How to Get
Use @string / Constanta
for Key
>>Best Practice
Use @string / Constanta
for Key
>>Best Practice
Use @string / Constanta
for Key
>>Best Practice
PR 2
- Model
- JSON
- Intent Kirim Data :
thumbnail gambar poster film
plot sinopsis (melalui pemanggilan overview di api)
rating pengguna (melalui pemanggilan vote_average di api)
tanggal rilis
T06.05-PreferenceChangeListener
How to Get
How to Getpublic boolean onPreferenceChange(Preference preference, Object newValue) {
Toast error = Toast.makeText(getContext(), "Please select a number between 0.1 and 3", Toast.LENGTH_SHORT);
String sizeKey = getString(R.string.pref_size_key);
if (preference.getKey().equals(sizeKey)) {
String stringSize = ((String) (newValue)).trim();
if (stringSize.equals("")) stringSize = "1";
try {
float size = Float.parseFloat(stringSize);
if (size > 3 || size <= 0) {
error.show();
return false;
}
} catch (NumberFormatException nfe) {
error.show();
return false;
}
}
return true;
}
NOW IS YOUR
TIME...
>>Create RecyclerView
S06.01-LaunchSettingsActivity
S06.02-SettingsFragment
S06.03-PolishingPreferences
LESSON 7
SQLite
LESSON 7
SQLite
Save it Offline!
+User Experience (Not waiting loading with Blank Screen)
+Battery Life
+Saving quota
+Reduce server load and network bandwith
+Run without internet connection area
Basic Database
Create TABLE
CREATE TABLE weather( _id INTEGER PRIMARY KEY, date TEXT
NOT NULL, min REAL NOT NULL, max REAL NOT NULL,
humidity REAL NOT NULL, pressure REAL NOT NULL);
Delete TABLE
DROP TABLE weather;
Basic Database
Basic Database
Insert row into TABLE
INSERT INTO weather VALUES(2,'20140626',17,21,0,1031);
INSERT INTO weather VALUES(3,'20140627',18,22,0,1055);
INSERT INTO weather VALUES(4,'20140628',18,21,10,1070);
Basic Database
Show Data from TABLE
SELECT * FROM weather;
SELECT * FROM weather WHERE date == 20140626;
SELECT _id,date,min,max FROM weather WHERE date >
20140625 AND date < 20140628;
SELECT * FROM weather WHERE min >= 18 ORDER BY max
ASC;
Basic Database
Update row in TABLE
UPDATE weather SET min = 0, max = 100 where date >=
20140626 AND date <= 20140627;
Delete row in TABLE
DELETE FROM weather WHERE humidity != 0;
Basic Database
INNER JOIN
https://en.wikipedia.org/wiki/Join_(SQL)#Inner_join
Delete row in TABLE
DELETE FROM weather WHERE humidity != 0;
WeatherContract.java
public static final String TABLE_NAME = "weather";
public static final String COLUMN_LOC_KEY = "location_id";
public static final String COLUMN_DATE = "date";
...
...
Contract
public class MovieContract {
public static final class MovieEntry implements BaseColumns {
//untuk sqlite
public static final String TABLE_NAME = "movie";
public static final String COLUMN_ID = "id";
public static final String COLUMN_JUDUL = "title";
public static final String COLUMN_POSTER = "poster_path";
}
}
Basic Database
SQLiteDbHelper
public class MovieDbHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "film.db";
private static final int DATABASE_VERSION = 1;
public MovieDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
SQLiteDbHelper
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
final String SQL_CREATE_WEATHER_TABLE =
"CREATE TABLE " + MovieContract.MovieEntry.TABLE_NAME + " (" +
MovieContract.MovieEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
MovieContract.MovieEntry.COLUMN_ID + " INTEGER NOT NULL, " +
MovieContract.MovieEntry.COLUMN_JUDUL + " TEXT NOT NULL, " +
MovieContract.MovieEntry.COLUMN_POSTER + " TEXT NOT NULL, " +
"UNIQUE (" + MovieContract.MovieEntry.COLUMN_JUDUL + ") ON CONFLICT REPLACE);";
sqLiteDatabase.execSQL(SQL_CREATE_WEATHER_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + MovieContract.MovieEntry.TABLE_NAME);
onCreate(sqLiteDatabase);
}
How to Use SQLite
T07.04-Exercise-
UpdateTheAdapter
NOW IS YOUR
TIME...
>>Create Database
LESSON 8
Content Provider
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
LESSON 9
Create Content Provider
Basic Database
Basic Database
1. Create ContentProvider Class
public class FilmContentProvider extends ContentProvider {
MovieDbHelper dbHelper;
@Override
public boolean onCreate() {
Context context = getContext();
dbHelper = new MovieDbHelper(context);
return true;
}
.
.
.
.
Basic Database
Basic Database
2. Android Manifest
<application>
.
.
.
.
<provider
android:name=".data.MovieContentProvider"
android:authorities="id.co.imastudio.popmov"
android:exported="false" />
</application>
Basic Database
Basic Database
3. DefineURI
ALL FILM
content://id.co.imastudio.recyclerview/listfilm
FILM WITH ID
content://id.co.imastudio.recyclerview/listfilm/#
Basic Database
Basic Database
4. Create URI
public class MovieContract {
public static final String AUTHORITY = "id.co.imastudio.popmov";
public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + AUTHORITY);
public static final String PATH_TASKS = "listfilm";
public static final class MovieEntry implements BaseColumns {
//Untuk Uri
public static final Uri CONTENT_URI =
BASE_CONTENT_URI.buildUpon().appendPath(PATH_TASKS).build();
//untuk sqlite
public static final String TABLE_NAME = "movie";
public static final String COLUMN_ID = "id";
public static final String COLUMN_JUDUL = "title";
public static final String COLUMN_POSTER = "poster_path";
}
}
Basic Database
Basic Database
Basic Database
Basic Database
5. Build URI Matcher
//2 membuat Uri Matcher
public static final int ALL_FILM = 100;
public static final int FILM_WITH_ID = 101;
private static final UriMatcher sUriMatcher = buildUriMatcher();
public static UriMatcher buildUriMatcher() {
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(MovieContract.AUTHORITY, MovieContract.PATH_TASKS, ALL_FILM);
uriMatcher.addURI(MovieContract.AUTHORITY, MovieContract.PATH_TASKS + "/#", FILM_WITH_ID);
return uriMatcher;
}
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
MovieContentProvider-Query
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[]
selectionArgs, @Nullable String sortOrder) {
final SQLiteDatabase db = dbHelper.getReadableDatabase();
int match = sUriMatcher.match(uri);
Cursor retCursor;
switch (match) {
case ALL_FILM:
retCursor = db.query(MovieContract.MovieEntry.TABLE_NAME,
projection, selection, selectionArgs, null, null, sortOrder);
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
retCursor.setNotificationUri(getContext().getContentResolver(), uri);
return retCursor;
}
MovieContentProvider-Insert
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
final SQLiteDatabase db = dbHelper.getWritableDatabase();
int match = sUriMatcher.match(uri);
Uri returnUri; // URI to be returned
switch (match) {
case ALL_FILM:
long id = db.insert(MovieContract.MovieEntry.TABLE_NAME, null, contentValues);
if ( id > 0 ) {
returnUri = ContentUris.withAppendedId(MovieContract.MovieEntry.CONTENT_URI, id);
} else {
throw new android.database.SQLException("Failed to insert row into " + uri);
}
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return returnUri;
MovieContentProvider-Delete
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
final SQLiteDatabase db = dbHelper.getWritableDatabase();
int numRowsDeleted;
if (null == selection) selection = "1";
switch (sUriMatcher.match(uri)) {
case ALL_FILM:
numRowsDeleted = dbHelper.getWritableDatabase().delete(
MovieContract.MovieEntry.TABLE_NAME,
selection,
selectionArgs);
db.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" + MovieContract.MovieEntry.TABLE_NAME + "'");
break;
case FILM_WITH_ID:
numRowsDeleted = db.delete(MovieContract.MovieEntry.TABLE_NAME, MovieContract.MovieEntry.COLUMN_ID + " = ?",
new String[]{String.valueOf(ContentUris.parseId(uri))});
db.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" + MovieContract.MovieEntry.TABLE_NAME + "'");
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
Insert Database
private void tambahkedatabase() {
ContentValues cv = new ContentValues();
cv.put(MovieContract.MovieEntry.COLUMN_ID, dataId);
cv.put(MovieContract.MovieEntry.COLUMN_JUDUL, dataJudul);
cv.put(MovieContract.MovieEntry.COLUMN_POSTER, dataPoster);
Log.d(TAG, "onResponse: "+ cv.get(MovieContract.MovieEntry.COLUMN_POSTER));
Uri uri = getContentResolver().insert(MovieContract.MovieEntry.CONTENT_URI, cv);
Toast.makeText(DetailActivity.this, "Uri :" + uri, Toast.LENGTH_SHORT).show();
}
Delete Database
private void hapusdaridatabase() {
getContentResolver().delete(MovieContract.MovieEntry.CONTENT_URI.buildUpon().appendPath(String.va
lueOf(dataId)).build(), null, null);
}
Basic Database
Basic Database
Basic Database
Basic Database
Using Loader to Load Data
getSupportLoaderManager().initLoader(ID_FILM_LOADER, null, this);
-----
@Override
public Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) {
switch (loaderId) {
case ID_FILM_LOADER:
Uri forecastQueryUri = FilmContract.FilmEntry.CONTENT_URI;
return new CursorLoader(this, forecastQueryUri, null, null, null, null);
default:
throw new RuntimeException("Loader Not Implemented: " + loaderId);
}
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if(data.getCount()>0) {
initAdapter(getMoviesFromCursor(data));
} else {
Toast.makeText(getActivity(), "Tidak Ada Favorite", Toast.LENGTH_LONG).show();
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
getMoviesFromCursor
private ArrayList<MovieModel> getMoviesFromCursor(Cursor cursor) {
ArrayList<MovieModel> movies = new ArrayList<>();
if (cursor != null) {
/*Log.e("cursor length","->"+cursor.getCount());
Log.e("column length","->"+cursor.getColumnCount());*/
if (cursor.moveToFirst()){
do{
MovieModel movie = new MovieModel();
movie.setId(cursor.getInt(cursor.getColumnIndex(MovieContract.MovieEntry.COLUMN_ID)));
movie.setJudul(cursor.getString(cursor.getColumnIndex(MovieContract.MovieEntry.COLUMN_JUDUL)));
movie.setPoster(cursor.getString(cursor.getColumnIndex(MovieContract.MovieEntry.COLUMN_POSTER)));
movies.add(movie);
}while(cursor.moveToNext());
}
}
return movies;
}
LESSON 10
Background Task
Notification
private NotificationManager mNotifyManager;
private int NOTIFICATION_ID = 0;
----
//dalam onCreate
mNotifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
----
private void tampilinNotification() {
NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("New Notification!")
.setContentText("Favorite berhasil ditambah.")
.setSmallIcon(R.drawable.ic_action_notif)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL)
//harus v4
Notification myNotification = notifyBuilder.build();
mNotifyManager.notify(NOTIFICATION_ID, myNotification);
}
Notification + Intent Masuk App
private void tampilinNotification() {
//masuk aplikasi
Intent notificationIntent = new Intent(this, TabActivity.class);
PendingIntent notificationPendingIntent = PendingIntent.getActivity(this,
NOTIFICATION_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("New Notification!")
.setContentText("Favorite berhasil ditambah.")
.setSmallIcon(R.drawable.ic_action_notif)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setContentIntent(notificationPendingIntent);
//harus v4
Notification myNotification = notifyBuilder.build();
mNotifyManager.notify(NOTIFICATION_ID, myNotification);
}
Notification + Action View Intent
private void tampilinNotification() {
//masuk web
Intent learnMoreIntent = new Intent(Intent.ACTION_VIEW, Uri
.parse("http://www.idn.id"));
PendingIntent learnMorePendingIntent = PendingIntent.getActivity
(this,NOTIFICATION_ID,learnMoreIntent,PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("New Notification!")
.setContentText("Favorite berhasil ditambah.")
.setSmallIcon(R.drawable.ic_action_notif)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.addAction(R.drawable.ic_info_black_24dp,"Learn More", learnMorePendingIntent);
//harus v4
Notification myNotification = notifyBuilder.build();
mNotifyManager.notify(NOTIFICATION_ID, myNotification);
Update Notification + BigPicture
private void updatenotification() {
Intent notificationIntent = new Intent(this, TabActivity.class);
PendingIntent notificationPendingIntent = PendingIntent.getActivity(this,
NOTIFICATION_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Bitmap androidImage = BitmapFactory
.decodeResource(getResources(),R.drawable.film);
NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("Update Notification!")
.setContentText("Favorite dihapus.")
.setSmallIcon(R.drawable.ic_action_notif)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(androidImage)
.setBigContentTitle("Notification Updated!"))
.setContentIntent(notificationPendingIntent);
//harus v4
Notification myNotification = notifyBuilder.build();
mNotifyManager.notify(NOTIFICATION_ID, myNotification);
Notification + Action Update
private static final String ACTION_UPDATE_NOTIFICATION ="id.co.imastudio.popmov.ACTION_UPDATE_NOTIFICATION";
----
private void tampilinNotification() {
//action
Intent updateintent = new Intent(ACTION_UPDATE_NOTIFICATION);
PendingIntent updatePendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, updateIntent, PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("New Notification!")
.setContentText("Favorite berhasil ditambah.")
.setSmallIcon(R.drawable.ic_action_notif)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.addAction(R.drawable.ic_sync_black_24dp, "Update", deletePendingIntent);
//harus v4
Notification myNotification = notifyBuilder.build();
mNotifyManager.notify(NOTIFICATION_ID, myNotification);
}
Receive Action Update
private NotificationReceiver mReceiver = new NotificationReceiver();
---
//dalam onCreate
registerReceiver(mReceiver,new IntentFilter(ACTION_UPDATE_NOTIFICATION));
---
public class NotificationReceiver extends BroadcastReceiver {
public NotificationReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action) {
case ACTION_UPDATE_NOTIFICATION:
updatenotification();
}
}
}
@Override
protected void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
Alarm Manager
private AlarmManager alarmManager;
---
//dalam onCreate
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
---
private void buatJadwalAlarm() {
Intent notificationIntent = new Intent(this, MyAlarmReceiver.class);
PendingIntent notifyPendingIntent = PendingIntent.getBroadcast(this,
NOTIFICATION_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
long triggerTime = SystemClock.elapsedRealtime()
+ AlarmManager.INTERVAL_FIFTEEN_MINUTES;
long repeatInterval = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
//If the Toggle is turned on, set the repeating alarm with a 15 minute interval
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
triggerTime, repeatInterval, notifyPendingIntent);
}
Alarm Manager Check
boolean alarmUp = (PendingIntent.getBroadcast(this, NOTIFICATION_ID, notificationIntent,
PendingIntent.FLAG_NO_CREATE) != null);
if (alarmUp){
Log.d(TAG, "setInexactRepeatingAlarm: Alarm tiap 30 detik nyala");
}
Make AlarmReceiver
1. Create New > Other > Receiver
<receiver
android:name=".MyAlarmReceiver"
android:enabled="true"
android:exported="false">
</receiver>
2. hapus throw new exception
3. Buat notifikasi contentintent di dalam onReceive
AlarmReceiver
public class MyAlarmReceiver extends BroadcastReceiver{
private int NOTIFICATION_ID = 1;
@Override
public void onReceive(Context context, Intent intent) {
NotificationManager mNotifyManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
//masuk aplikasi
Intent notificationIntent = new Intent(context, TabActivity.class);
PendingIntent notificationPendingIntent = PendingIntent.getActivity(context,
NOTIFICATION_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(context)
.setContentTitle("Sudah 15 menit!")
.setContentText("Cek aplikasinya.")
.setSmallIcon(R.drawable.ic_action_notif)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setAutoCancel(true)
.setContentIntent(notificationPendingIntent);
//harus v4
mNotifyManager.notify(NOTIFICATION_ID, notifyBuilder.build());
}
}
Job Scheduler
private JobScheduler mScheduler;
private int JOB_ID = 21;
---
//dalam onCreate
mScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
scheduleJob();
---
private void scheduleJob() {
ComponentName serviceName = new ComponentName(getPackageName(),
NotificationJobService.class.getName());
JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, serviceName);
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
builder.setRequiresCharging(true);
builder.setPeriodic(86400000);
JobInfo myJobInfo = builder.build();
mScheduler.schedule(myJobInfo);
Toast.makeText(DetailActivity.this, "ScheduleJob has been running", Toast.LENGTH_SHORT).show();
}
NotificationJobService
public class NotificationJobService extends JobService {
@Override
public boolean onStartJob(JobParameters params) {
//Set up the notification content intent to launch the app when clicked
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
PendingIntent contentPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainScreen.class),
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentTitle("JobService Coming")
.setContentText("Yeayy, just be happy, this only show when baterry charged")
.setContentIntent(contentPendingIntent)
.setSmallIcon(R.drawable.ic_home_black_24dp)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setAutoCancel(true);
manager.notify(0, builder.build());
Log.d(TAG, "onStartJob: called");
return false;
}
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
Basic Database
FilmSyncTask
public class FilmSyncTask {
synchronized public static void syncFilm(final Context context) {
// isi buat update data
}
}
FilmIntentService
public class FilmIntentService extends IntentService {
public FilmIntentService() {
super("FilmIntentService");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
FilmSyncTask.syncFilm(this);
}
}
---------- Manifest
<service
android:name=".sync.FilmIntentService"
android:exported="false" />
FilmSyncUtils
public class FilmSyncUtils {
public static void startImmediateSync(@NonNull final Context context) {
Intent intentToSyncImmediately = new Intent(context, FilmIntentService.class);
context.startService(intentToSyncImmediately);
}
}
----
FilmSyncUtils.startImmediateSync(this);
Basic Database
Basic Database
FilmFirebaseJobService
public class FilmFirebaseJobService extends JobService {
private AsyncTask<Void, Void, Void> mFetchWeatherTask;
@Override
public boolean onStartJob(final JobParameters jobParameters) {
mFetchWeatherTask = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
Context context = getApplicationContext();
FilmSyncTask.syncFilm(context);
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
jobFinished(jobParameters, false);
}
};
mFetchWeatherTask.execute();
return true;
}
@Override
public boolean onStopJob(JobParameters jobParameters) {
if (mFetchWeatherTask != null) {
mFetchWeatherTask.cancel(true);
}
return true;
}
}
<service
android:name=".sync.FilmFirebaseJobService"
android:exported="false">
<intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE"/>
</intent-filter>
</service>
FilmFirebaseJobService
static void scheduleFirebaseJobDispatcherSync(@NonNull final Context context) {
Driver driver = new GooglePlayDriver(context);
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(driver);
Job syncSunshineJob = dispatcher.newJobBuilder()
.setService(FilmFirebaseJobService.class)
.setTag(SUNSHINE_SYNC_TAG)
.setConstraints(Constraint.ON_ANY_NETWORK)
.setLifetime(Lifetime.FOREVER)
.setRecurring(true)
.setTrigger(Trigger.executionWindow(
SYNC_INTERVAL_SECONDS,
SYNC_INTERVAL_SECONDS + SYNC_FLEXTIME_SECONDS))
.setReplaceCurrent(true)
.build();
dispatcher.schedule(syncSunshineJob);
}
private static final int SYNC_INTERVAL_HOURS = 3;
private static final int SYNC_INTERVAL_SECONDS = (int)
TimeUnit.HOURS.toSeconds(SYNC_INTERVAL_HOURS);
private static final int SYNC_FLEXTIME_SECONDS =
SYNC_INTERVAL_SECONDS / 3;
private static boolean sInitialized;
private static final String SUNSHINE_SYNC_TAG =
"sunshine-sync";
Notification Manager
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
.setColor(ContextCompat.getColor(context, R.color.colorPrimary))
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentTitle("Data Film Anyar")
.setContentText("didelok gan!")
.setAutoCancel(true);
Intent detailIntentForToday = new Intent(context, MainActivity.class);
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(context);
taskStackBuilder.addNextIntentWithParentStack(detailIntentForToday);
PendingIntent resultPendingIntent = taskStackBuilder
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.setContentIntent(resultPendingIntent);
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(12234, notificationBuilder.build());
Notification Manager
Notification Manager
Notification Manager
Notification Manager
Notification Manager
Notification Manager
Notification Manager
FINAL PROJECT
Let's do it!
Final Project
- Grid Layout
- Sort by Popular , Top Rated, and Favorit
- Detail Screen (title, release date, movie poster, vote average,
and plot synopsis, trailer, and review)
- Mark it as a Favorite.
- Networking in background thread
- Content provider to save Favorit offline
Final Project
save app state and restores it via
onSaveInstanceState/onRestoreInstanceState.
For example,
When a list item is selected, it remains selected on rotation.
When an activity is displayed, the same activity appears on
rotation.
User text input is preserved on rotation.
Maintains list items positions on device rotation.
Final Project
You must make sure your app does not crash when there is no
network connection! You can see this StackOverflow post on
how to do this. If your app crashes when there is no network
connection, you will not pass the project.
Final Project ++
++
+Extend the favorites ContentProvider to store the movie
poster, synopsis, user rating, and release date, and display them
even when offline.
+ Implement sharing functionality to allow the user to share the
first trailer’s YouTube URL from the movie details screen.
Final Project
https://docs.google.com/document/d/1ZlN1fUsCSKuInLECcJkslI
qvpKlP7jWL2TP9m6UiA6I/pub?embedded=true#h.7sxo8jefdfll
http://stackoverflow.com/questions/1560788/how-to-check-
internet-access-on-android-inetaddress-never-times-out
About Me
From : Ambarawa
Phone : 085740482440
FB : fb.me/faizinarif
Instagram : arif_faizin
Github : github.com/arifaizin
Education :
• SDN Kupang 01 Ambarawa
• SMPN 2 Paciran Lamongan / PPSD
• SMAN 1 Ambarawa
• Universitas Diponegoro
• Pesantren Programmer
Now :
IMASTUDIO SEMARANG
IMAKIDZ
Ahmad
ARIF
Faizin

More Related Content

PPTX
The Best Way to Become an Android Developer Expert with Android Jetpack
PPTX
SgCodeJam24 Workshop
PPTX
08.1. Android How to Use Intent (explicit)
PDF
Android Workshop 2013
DOCX
Using intents in android
PDF
Sharper Better Faster Dagger ‡ - Droidcon SF
PDF
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
PDF
Android Lab
The Best Way to Become an Android Developer Expert with Android Jetpack
SgCodeJam24 Workshop
08.1. Android How to Use Intent (explicit)
Android Workshop 2013
Using intents in android
Sharper Better Faster Dagger ‡ - Droidcon SF
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
Android Lab

What's hot (20)

PPTX
The Anatomy of Apps - How iPhone, Android & Facebook Apps Consume APIs
PDF
Firebase for Apple Developers
PPTX
Getting Ready For Android Wear
PDF
Android studio
PPTX
Lightning Components Workshop
PDF
Distributed ID generator in ChatWork
PDF
Android Components
PDF
PROMAND 2014 project structure
PDF
Exploring CameraX from JetPack
PDF
Gradle for Android Developers
PDF
An Introduction to Django Web Framework
PDF
Rapid Application Development with SwiftUI and Firebase
PDF
Android best practices
TXT
Alfrescotomcat stderr.2013-03-05
PDF
Salesforce Lightning Tips & Tricks
PDF
Lesson 2. Connect Sunshine to the cloud, Lesson 3. New Activities and Intents
PDF
Ruby motion勉強会 2012年7月
PPTX
06. Android Basic Widget and Container
TXT
Catalina.2013 03-05
The Anatomy of Apps - How iPhone, Android & Facebook Apps Consume APIs
Firebase for Apple Developers
Getting Ready For Android Wear
Android studio
Lightning Components Workshop
Distributed ID generator in ChatWork
Android Components
PROMAND 2014 project structure
Exploring CameraX from JetPack
Gradle for Android Developers
An Introduction to Django Web Framework
Rapid Application Development with SwiftUI and Firebase
Android best practices
Alfrescotomcat stderr.2013-03-05
Salesforce Lightning Tips & Tricks
Lesson 2. Connect Sunshine to the cloud, Lesson 3. New Activities and Intents
Ruby motion勉強会 2012年7月
06. Android Basic Widget and Container
Catalina.2013 03-05
Ad

Similar to Android Intermediatte IAK full (20)

PPTX
Meteor Meet-up San Diego December 2014
PPTX
O365 DEVCamp Los Angeles June 16, 2015 Module 06 Hook into SharePoint APIs wi...
PPTX
Mobile App Development: Primi passi con NativeScript e Angular 2
PPTX
Timings API: Performance Assertion during the functional testing
PDF
Google I/O 2021 Recap
PPTX
Sst hackathon express
PDF
Hooking SharePoint APIs with Android
PPTX
Session - 1 Forms and Session management.pptx
PPTX
Monitoring Spark Applications
ODP
Apache Aries Blog Sample
PPTX
2013 - Back to the Future with Client/Server Development
PDF
Itb 2021 - Bulding Quick APIs by Gavin Pickin
PDF
React Native for multi-platform mobile applications
PDF
Android rest client applications-services approach @Droidcon Bucharest 2012
PDF
Spring boot microservice metrics monitoring
PDF
Spring Boot - Microservice Metrics Monitoring
PPTX
REST API Best Practices & Implementing in Codeigniter
PPTX
Plone FSR
KEY
jRecruiter - The AJUG Job Posting Service
PDF
Lab 5-Android
Meteor Meet-up San Diego December 2014
O365 DEVCamp Los Angeles June 16, 2015 Module 06 Hook into SharePoint APIs wi...
Mobile App Development: Primi passi con NativeScript e Angular 2
Timings API: Performance Assertion during the functional testing
Google I/O 2021 Recap
Sst hackathon express
Hooking SharePoint APIs with Android
Session - 1 Forms and Session management.pptx
Monitoring Spark Applications
Apache Aries Blog Sample
2013 - Back to the Future with Client/Server Development
Itb 2021 - Bulding Quick APIs by Gavin Pickin
React Native for multi-platform mobile applications
Android rest client applications-services approach @Droidcon Bucharest 2012
Spring boot microservice metrics monitoring
Spring Boot - Microservice Metrics Monitoring
REST API Best Practices & Implementing in Codeigniter
Plone FSR
jRecruiter - The AJUG Job Posting Service
Lab 5-Android
Ad

More from Ahmad Arif Faizin (20)

PDF
Guideline Submission GitHub BFAA Dicoding
PPTX
Proker Departemen Dakwah dan Syiar 2013.pptx
PPTX
DKM_2013_BISMILLAH.pptx
PPT
Proker bendahara al muhandis 2013.ppt
PPTX
PPT raker EKONOMI 2013.pptx
PPT
Program Kerja Kaderisasi Al Muhandis 2013
PPTX
Departemen Mentoring.pptx
PPTX
ANNISAA' 2013.pptx
PPTX
PPT KKN PEDURUNGAN 2016.pptx
PPTX
Absis UNBK.pptx
PPTX
Dts x dicoding #5 memulai pemrograman kotlin
PPTX
Dts x dicoding #4 memulai pemrograman kotlin
PPTX
Dts x dicoding #3 memulai pemrograman kotlin
PPTX
Dts x dicoding #2 memulai pemrograman kotlin
PPTX
Dts x dicoding #1 memulai pemrograman kotlin
PPTX
Dsc how google programs make great developer
PPTX
First Gathering Sandec
PPTX
Mockup Android Application Template Library
PPTX
Mockup Android Application : Go bon
PPTX
Lomba Sayembara Logo
Guideline Submission GitHub BFAA Dicoding
Proker Departemen Dakwah dan Syiar 2013.pptx
DKM_2013_BISMILLAH.pptx
Proker bendahara al muhandis 2013.ppt
PPT raker EKONOMI 2013.pptx
Program Kerja Kaderisasi Al Muhandis 2013
Departemen Mentoring.pptx
ANNISAA' 2013.pptx
PPT KKN PEDURUNGAN 2016.pptx
Absis UNBK.pptx
Dts x dicoding #5 memulai pemrograman kotlin
Dts x dicoding #4 memulai pemrograman kotlin
Dts x dicoding #3 memulai pemrograman kotlin
Dts x dicoding #2 memulai pemrograman kotlin
Dts x dicoding #1 memulai pemrograman kotlin
Dsc how google programs make great developer
First Gathering Sandec
Mockup Android Application Template Library
Mockup Android Application : Go bon
Lomba Sayembara Logo

Recently uploaded (20)

PDF
System and Network Administration Chapter 2
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
PTS Company Brochure 2025 (1).pdf.......
PPTX
history of c programming in notes for students .pptx
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PPTX
ISO 45001 Occupational Health and Safety Management System
PPTX
ManageIQ - Sprint 268 Review - Slide Deck
PPTX
Online Work Permit System for Fast Permit Processing
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PPTX
L1 - Introduction to python Backend.pptx
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PPT
Introduction Database Management System for Course Database
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
System and Network Administration Chapter 2
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Odoo Companies in India – Driving Business Transformation.pdf
Odoo POS Development Services by CandidRoot Solutions
PTS Company Brochure 2025 (1).pdf.......
history of c programming in notes for students .pptx
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
ISO 45001 Occupational Health and Safety Management System
ManageIQ - Sprint 268 Review - Slide Deck
Online Work Permit System for Fast Permit Processing
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Design an Analysis of Algorithms I-SECS-1021-03
Navsoft: AI-Powered Business Solutions & Custom Software Development
L1 - Introduction to python Backend.pptx
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
Introduction Database Management System for Course Database
Upgrade and Innovation Strategies for SAP ERP Customers
Internet Downloader Manager (IDM) Crack 6.42 Build 41
How to Migrate SBCGlobal Email to Yahoo Easily
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...

Android Intermediatte IAK full