· 8 years ago · Jan 26, 2018, 11:24 AM
1--------------------------------------------------------------------------------------------------------------------------------------
2 SPREMANJE PODATAKA
3--------------------------------------------------------------------------------------------------------------------------------------
4
5 - FUNKCIJE KLASE CURSOR:
6
7 moveToFirst() = pomice kursor na 1. redak
8
9moveToNext() = pomice kursor na iduci redak
10
11moveToPrevious() = pomice kursor na prethodni redak
12
13getCount() = vraca broj redaka u ispisu
14
15moveToPosition() = pomice kursor na specificirani redak
16
17getPosition() = vraca trenutnu poziciju kursora
18
19
20
21
22
23ZAD27 STVORITE (KAO DIO NOVOG PROJEKTA) BAZU PODATAKA MYDB KOJA SADRZI JEDNU TABLICU CONTACTS(_ID,NAME,EMAIL). PROJEKT TREBA IMPLEMENTIRATI SVE FUNKCIJE BITNE ZA RAD BAZE (VIDJETI IDUCE LINKOVE).
24
25- ADAPTER:
26
27 static final String KEY_ROWID = "_id";
28 static final String KEY_NAME = "name";
29 static final String KEY_EMAIL = "email";
30 static final String TAG = "DBAdapter";
31
32 static final String DATABASE_NAME = "MyDB";
33 static final String DATABASE_TABLE = "contacts";
34 static final int DATABASE_VERSION = 2;
35
36 static final String DATABASE_CREATE =
37 "create table contacts (_id integer primary key autoincrement, "
38 + "name text not null, email text not null);";
39
40 final Context context;
41
42 DatabaseHelper DBHelper;
43 SQLiteDatabase db;
44
45 public DBAdapter(Context ctx)
46 {
47 this.context = ctx;
48 DBHelper = new DatabaseHelper(context);
49 }
50
51 private static class DatabaseHelper extends SQLiteOpenHelper
52 {
53 DatabaseHelper(Context context)
54 {
55 super(context, DATABASE_NAME, null, DATABASE_VERSION);
56 }
57
58 @Override
59 public void onCreate(SQLiteDatabase db)
60 {
61 try {
62 db.execSQL(DATABASE_CREATE);
63 } catch (SQLException e) {
64 e.printStackTrace();
65 }
66 }
67
68 @Override
69 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
70 {
71 Log.w(TAG, "Upgrading db from" + oldVersion + "to"
72 + newVersion );
73 db.execSQL("DROP TABLE IF EXISTS contacts");
74 onCreate(db);
75 }
76 }
77
78 //---opens the database---
79 public DBAdapter open() throws SQLException
80 {
81 db = DBHelper.getWritableDatabase();
82 return this;
83 }
84
85 //---closes the database---
86 public void close()
87 {
88 DBHelper.close();
89 }
90
91 //---insert a contact into the database---
92 public long insertContact(String name, String email)
93 {
94 ContentValues initialValues = new ContentValues();
95 initialValues.put(KEY_NAME, name);
96 initialValues.put(KEY_EMAIL, email);
97 return db.insert(DATABASE_TABLE, null, initialValues);
98 }
99
100 //---deletes a particular contact---
101 public boolean deleteContact(long rowId)
102 {
103 return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
104 }
105
106 //---retrieves all the contacts---
107 public Cursor getAllContacts()
108 {
109 return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME,
110 KEY_EMAIL}, null, null, null, null, null);
111 }
112
113 //---retrieves a particular contact---
114 public Cursor getContact(long rowId) throws SQLException
115 {
116 Cursor mCursor =
117 db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
118 KEY_NAME, KEY_EMAIL}, KEY_ROWID + "=" + rowId, null,
119 null, null, null, null);
120 if (mCursor != null) {
121 mCursor.moveToFirst();
122 }
123 return mCursor;
124 }
125
126 //---updates a contact---
127 public boolean updateContact(long rowId, String name, String email)
128 {
129 ContentValues args = new ContentValues();
130 args.put(KEY_NAME, name);
131 args.put(KEY_EMAIL, email);
132 return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
133 }
134
135
136- METODE KLASE SQLITEDATABASE:
137
138long insert(String table, String nullColumnHack, ContentValues values)
139 Metoda za ubacivanje retka u bazu.
140Vraca ID retka koji je ubacen, ili -1 u slucaju greske.
141
142int delete(String table, String whereClause, String[] whereArgs)
143Metoda za brisanje redaka iz baze.
144Vraca broj pobrisanih redaka ako je bilo whereClause-a, inace vraca 0. Da se izbrisu svi retci stavimo "1" na mjesto whereClause.
145
146int update(String table, ContentValues values, String whereClause, String[] whereArgs)
147Metoda za izmjenu redaka u bazi.
148Vraca broj redaka koji su izmjenjeni.
149
150Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
151Za upit na danoj tablici, vraca Cursor na rezultat.
152
153Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
154Za upit na danoj tablici, vraca Cursor na rezultat.
155
156Cursor query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
157Za upit na danoj tablici, vraca Cursor na rezultat.
158
159
160
161
162- STVARANJE I EDITIRANJE BAZE:
163
164// u onCreate
165
166DBAdapter db = new DBAdapter(this);
167
168
169 //---add a contact---
170 db.open();
171 long id = db.insertContact("Wei-Meng Lee", "weimenglee@learn2develop.net");
172 id = db.insertContact("Mary Jackson", "mary@jackson.com");
173 db.close();
174
175
176
177 //--get all contacts---
178 db.open();
179 Cursor c = db.getAllContacts();
180 if (c.moveToFirst())
181 {
182 do {
183 DisplayContact(c);
184 } while (c.moveToNext());
185 }
186 db.close();
187
188
189
190 //---get a contact---
191 db.open();
192 Cursor cu = db.getContact(1);
193 if (cu.moveToFirst())
194 DisplayContact(cu);
195 else
196 Toast.makeText(this, "No contact found", Toast.LENGTH_LONG).show();
197 db.close();
198
199
200
201 //---update contact---
202 db.open();
203 if (db.updateContact(1, "Wei-Meng Lee", "weimenglee@gmail.com"))
204 Toast.makeText(this, "Update successful.", Toast.LENGTH_LONG).show();
205 else
206 Toast.makeText(this, "Update failed.", Toast.LENGTH_LONG).show();
207 db.close();
208
209
210
211 //---delete a contact---
212 db.open();
213 if (db.deleteContact(1))
214 Toast.makeText(this, "Delete successful.", Toast.LENGTH_LONG).show();
215 else
216 Toast.makeText(this, "Delete failed.", Toast.LENGTH_LONG).show();
217 db.close();
218
219
220// nakon onCreate
221
222//funkcija za ispis
223 public void DisplayContact(Cursor c)
224 {
225 Toast.makeText(this,
226 "id: " + c.getString(0) + "\n" +
227 "Name: " + c.getString(1) + "\n" +
228 "Email: " + c.getString(2),
229 Toast.LENGTH_LONG).show();
230 }
231
232
233
234ZAD DODAJTE U BAZU JOS JEDNU TABLICU KOJA SADRZI PODATKE O POSTANSKIM ADRESAMA KONTAKATA. ISPISITE SADRZAJ OBJE TABLICE.
235
236-PREDEFINIRANE KONSTANTE
237
238Browser.BOOKMARKS_URI
239Browser.SEARCHES_URI
240CallLog.CONTENT_URI
241Setiings.CONTENT_URI
242ContactsContract.Contacts.CONTENT_URI
243
244-PRIMJER
245
246umjesto
247Uri allContacts=Uri.parse("content://contacts/people");
248mozemo pisati
249Uri allContacts=ContactsContract.Contacts.CONTENT_URI;
250
251umjesto
252Uri allContacts=Uri.parse("content://contacts/people/1");
253mozemo pisati
254Uri allContacts=ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,1);
255
256-ZAD28 ISPISITE SVE KONTAKTE U VASEM UREDJAJU (EMULATORU) U OBLIKU LISTE.
257
258
259
260-CONTACTS CP XML (tu ima greška na webu. contactID je layout_width = "wrap_content")
261
262<ListView
263 android:id="@+id/android:list"
264 android:layout_width="fill_parent"
265 android:layout_height="wrap_content"
266 android:layout_weight="1" />
267
268<TextView
269 android:id="@+id/contactName"
270 android:layout_width="wrap_content"
271 android:layout_height="wrap_content" />
272
273<TextView
274 android:id="@+id/contactID"
275 android:layout_width="wrap_content"
276 android:layout_height="wrap_content" />
277
278-CONTACTS CP JAVA
279
280
281 //Uri allContacts = Uri.parse("content://contacts/people");
282 Uri allContacts = ContactsContract.Contacts.CONTENT_URI;
283
284
285 Cursor c;
286 if (android.os.Build.VERSION.SDK_INT <11) {
287 //---before Honeycomb---
288 c = managedQuery(allContacts, null,null,null,null);
289
290 } else {
291 //---Honeycomb and later---
292 CursorLoader cursorLoader = new CursorLoader(
293 this,
294 allContacts,
295 null,
296 null,
297 null,
298 null);
299 c = cursorLoader.loadInBackground();
300 }
301
302 String[] columns = new String[] {
303 ContactsContract.Contacts.DISPLAY_NAME,
304 ContactsContract.Contacts._ID};
305
306 int[] views = new int[] {R.id.contactName, R.id.contactID};
307
308 SimpleCursorAdapter adapter;
309
310 if (android.os.Build.VERSION.SDK_INT <11) {
311 //---before Honeycomb---
312 adapter = new SimpleCursorAdapter(
313 this, R.layout.activity_main, c, columns, views);
314 } else {
315 //---Honeycomb and later---
316 adapter = new SimpleCursorAdapter(
317 this, R.layout.activity_main, c, columns, views,
318 CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
319 }
320 this.setListAdapter(adapter);
321
322
323
324-PERMISSIONS MANIFEST
325
326<uses-permission android:name="android.permission.READ_CONTACTS"/>
327
328-PERMISSIONS DOPUNA
329
330//dodati u klasu
331
332private int MY_PERM=1;
333
334//dodati u onCreate()
335
336if (ContextCompat.checkSelfPermission(this,
337 Manifest.permission.READ_CONTACTS)
338 != PackageManager.PERMISSION_GRANTED) {
339 ActivityCompat.requestPermissions(this,
340 new String[]{Manifest.permission.READ_CONTACTS},MY_PERM);
341 }
342
343-ZAD29 STVORITE VLASTITI CONTENT PROVIDER KOJI POHRANJUJE LISTU KNJIGA BOOKS(_ID,TITLE,ISBN) U BAZU PODATAKA.
344
345
346
347-VLASTITI CONTENT PROVIDER
348
349public class BooksProvider extends ContentProvider
350{
351 static final String PROVIDER_NAME =
352 "hr.math.provider.contprov";
353
354 static final Uri CONTENT_URI =
355 Uri.parse("content://"+ PROVIDER_NAME + "/books");
356
357 static final String _ID = "_id";
358 static final String TITLE = "title";
359 static final String ISBN = "isbn";
360
361 static final int BOOKS = 1;
362 static final int BOOK_ID = 2;
363
364 private static final UriMatcher uriMatcher;
365 static{
366 uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
367 uriMatcher.addURI(PROVIDER_NAME, "books", BOOKS);
368 uriMatcher.addURI(PROVIDER_NAME, "books/#", BOOK_ID);
369 }
370
371 //---for database use---
372 SQLiteDatabase booksDB;
373 static final String DATABASE_NAME = "Books";
374 static final String DATABASE_TABLE = "titles";
375 static final int DATABASE_VERSION = 1;
376 static final String DATABASE_CREATE =
377 "create table " + DATABASE_TABLE +
378 " (_id integer primary key autoincrement, "
379 + "title text not null, isbn text not null);";
380
381 private static class DatabaseHelper extends SQLiteOpenHelper
382 {
383 DatabaseHelper(Context context) {
384 super(context, DATABASE_NAME, null, DATABASE_VERSION);
385 }
386
387 @Override
388 public void onCreate(SQLiteDatabase db)
389 {
390 db.execSQL(DATABASE_CREATE);
391 }
392
393 @Override
394 public void onUpgrade(SQLiteDatabase db, int oldVersion,
395 int newVersion) {
396 Log.w("CONTPROVDB", "Upgrading from " + oldVersion + " to " + newVersion);
397
398
399
400 db.execSQL("DROP TABLE IF EXISTS titles");
401 onCreate(db);
402 }
403 }
404
405 @Override
406 public int delete(Uri arg0, String arg1, String[] arg2) {
407 // arg0 = uri
408 // arg1 = selection
409 // arg2 = selectionArgs
410 int count=0;
411 switch (uriMatcher.match(arg0)){
412 case BOOKS:
413 count = booksDB.delete(
414 DATABASE_TABLE,
415 arg1,
416 arg2);
417 break;
418 case BOOK_ID:
419 String id = arg0.getPathSegments().get(1);
420 count = booksDB.delete(
421 DATABASE_TABLE,
422 _ID + " = " + id +
423 (!TextUtils.isEmpty(arg1) ? " AND (" +
424 arg1 + ')' : ""),
425 arg2);
426 break;
427 default: throw new IllegalArgumentException("Unknown URI " + arg0);
428 }
429 getContext().getContentResolver().notifyChange(arg0, null);
430 return count;
431 }
432
433 @Override
434 public String getType(Uri uri) {
435 switch (uriMatcher.match(uri)){
436 //---get all books---
437 case BOOKS:
438 return "vnd.android.cursor.dir/vnd.math.books ";
439
440 //---get a particular book---
441 case BOOK_ID:
442 return "vnd.android.cursor.item/vnd.math.books ";
443
444 default:
445 throw new IllegalArgumentException("Unsupported URI: " + uri);
446 }
447 }
448
449 @Override
450 public Uri insert(Uri uri, ContentValues values) {
451 //---add a new book---
452 long rowID = booksDB.insert(
453 DATABASE_TABLE,
454 "",
455 values);
456
457 //---if added successfully---
458 if (rowID>0)
459 {
460 Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
461 getContext().getContentResolver().notifyChange(_uri, null);
462 return _uri;
463 }
464 throw new SQLException("Failed to insert row into " + uri);
465 }
466
467 @Override
468 public boolean onCreate() {
469 Context context = getContext();
470 DatabaseHelper dbHelper = new DatabaseHelper(context);
471 booksDB = dbHelper.getWritableDatabase();
472 return (booksDB == null)? false:true;
473 }
474
475 @Override
476 public Cursor query(Uri uri, String[] projection, String selection,
477 String[] selectionArgs, String sortOrder) {
478 SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();
479 sqlBuilder.setTables(DATABASE_TABLE);
480
481 if (uriMatcher.match(uri) == BOOK_ID)
482 //---if getting a particular book---
483 sqlBuilder.appendWhere(
484 _ID + " = " + uri.getPathSegments().get(1));
485
486 if (sortOrder==null || sortOrder=="")
487 sortOrder = TITLE;
488
489 Cursor c = sqlBuilder.query(
490 booksDB,
491 projection,
492 selection,
493 selectionArgs,
494 null,
495 null,
496 sortOrder);
497
498 //---register to watch a content URI for changes---
499 c.setNotificationUri(getContext().getContentResolver(), uri);
500 return c;
501 }
502
503 @Override
504 public int update(Uri uri, ContentValues values, String selection,
505 String[] selectionArgs) {
506 int count = 0;
507 switch (uriMatcher.match(uri)){
508 case BOOKS:
509 count = booksDB.update(
510 DATABASE_TABLE,
511 values,
512 selection,
513 selectionArgs);
514 break;
515 case BOOK_ID:
516 count = booksDB.update(
517 DATABASE_TABLE,
518 values,
519 _ID + " = " + uri.getPathSegments().get(1) +
520 (!TextUtils.isEmpty(selection) ? " AND (" +
521 selection + ')' : ""),
522 selectionArgs);
523 break;
524 default: throw new IllegalArgumentException("Unknown URI " + uri);
525 }
526 getContext().getContentResolver().notifyChange(uri, null);
527 return count;
528 }
529}
530
531
532 ZAD30 TESTIRAJTE CP IZ ZAD29: DIZAJNIRAJTE UI SA POLJIMA ZA UNOS ISBN I NASLOVA, TE GUMBE ZA UNOS I ZA ISPIS SVIH KNJIGA.
533
534
535
536 - VLASTITI CP XML
537
538 <EditText
539 android:id="@+id/txtISBN"
540 android:layout_height="wrap_content"
541 android:layout_width="fill_parent"
542 android:hint="ISBN" />
543
544
545<EditText
546 android:id="@+id/txtTitle"
547 android:layout_height="wrap_content"
548 android:layout_width="fill_parent"
549 android:hint="title" />
550
551<Button
552 android:text="Add title"
553 android:id="@+id/btnAdd"
554 android:layout_width="fill_parent"
555 android:layout_height="wrap_content"
556 android:onClick="onClickAddTitle" />
557
558<Button
559 android:text="Retrieve titles"
560 android:id="@+id/btnRetrieve"
561 android:layout_width="fill_parent"
562 android:layout_height="wrap_content"
563 android:onClick="onClickRetrieveTitles" />
564
565
566
567
568 - VLASTITI CP JAVA
569
570 public void onClickAddTitle(View view) {
571
572 //---add a book---
573
574 ContentValues values = new ContentValues();
575 values.put("title", ((EditText)
576 findViewById(R.id.txtTitle)).getText().toString());
577 values.put("isbn", ((EditText)
578 findViewById(R.id.txtISBN)).getText().toString());
579 Uri uri = getContentResolver().insert(
580 Uri.parse(
581 "content://hr.math.provider.contprov/books"),
582 values);
583 }
584
585 public void onClickRetrieveTitles(View view) {
586 //---retrieve the titles---
587 Uri allTitles = Uri.parse(
588 "content://hr.math.provider.contprov/books");
589
590 Cursor c;
591 if (android.os.Build.VERSION.SDK_INT <11) {
592 //---before Honeycomb---
593 c = managedQuery(allTitles, null, null, null,
594 "title desc");
595 } else {
596 //---Honeycomb and later---
597 CursorLoader cursorLoader = new CursorLoader(
598 this,
599 allTitles, null, null, null,
600 "title desc");
601 c = cursorLoader.loadInBackground();
602 }
603
604 if (c.moveToFirst()) {
605 do{
606 Toast.makeText(this,
607 c.getString(c.getColumnIndex(
608 BooksProvider._ID)) + ", " +
609 c.getString(c.getColumnIndex(
610 BooksProvider.TITLE)) + ", " +
611 c.getString(c.getColumnIndex(
612 BooksProvider.ISBN)),
613 Toast.LENGTH_SHORT).show();
614 } while (c.moveToNext());
615 }
616 }
617
618 - ZAD DODAJTE U ZADATAK 30 I GUMB ZA ISPIS SVIH KNJIGA KOJIMA NASLOV POCINJE NA SLOVO B ILI SLOVO L, TE GUMB ZA BRISANJE KNJIGE SA ZADANIM ISBN-OM.
619
620--------------------------------------------------------------------------------------------------------------------------------------
621 MREZNA KOMUNIKACIJA
622--------------------------------------------------------------------------------------------------------------------------------------
623
624 - PERMISSION
625
626<uses-permission android:name="android.permission.SEND_SMS"/>
627
628 - PERMISSION DODATNO
629
630// u klasu
631private int MY_PERM=1;
632
633//u onCreate
634
635 //ask for permission
636 if (ContextCompat.checkSelfPermission(this,
637 Manifest.permission.SEND_SMS)
638 != PackageManager.PERMISSION_GRANTED)
639 ActivityCompat.requestPermissions(this,
640 new String[]{Manifest.permission.SEND_SMS}, MY_PERM);
641
642 - ZAD31 NAPISITE APLIKACIJU KOJA SALJE SMS PORUKU NA DVA RAZLICITA NACINA.
643
644
645
646 - SMS.XML
647
648<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnSendSMS" android:text="SendSMS" android:onClick="onClick"/>
649
650<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnSMS2" android:text="SendSMS2" android:onClick="onSMSIntentClick"/>
651
652
653 - SMS.JAVA
654
655 public void onClick(View v) {
656 sendSMS("5556", "Neki moj tekst koji saljem.");
657 }
658
659
660
661
662 public void onSMSIntentClick(View v) {
663
664 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) //for new versions
665 {
666 Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("sms:" + 5556));
667 i.putExtra("sms_body", "Moj tekst koji saljem.");
668 startActivity(i);
669
670 }
671 else // For early versions, do what worked before.
672 {
673 Intent i = new Intent(Intent.ACTION_VIEW);
674 i.setType("vnd.android-dir/mms-sms");
675 i.putExtra("address", "5556");
676 i.putExtra("sms_body","Moj tekst koji saljem.");
677 startActivity(i);
678 }
679
680
681
682 }
683
684 //sends an SMS message to another device
685 private void sendSMS(String phoneNumber, String message)
686 {
687 SmsManager sms = SmsManager.getDefault();
688 sms.sendTextMessage(phoneNumber, null, message, null, null);
689 }
690
691
692 - ZAD32 U PROJEKT IZ ZAD31 DODAJTE MOGUCNOST SLANJA MAILA.
693
694
695 - MAIL.XML
696
697<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnSendEmail" android:text="SendEmail" android:onClick="onClick2"/>
698
699 - MAIL.JAVA
700
701 public void onClick2(View v) {
702 String[] to =
703 {"someguy@yourcompany.com",
704 "anotherguy@yourcompany.com"};
705 String[] cc = {"busybody@yourcompany.com"};
706 sendEmail(to, cc, "Hello", "Hello my friends!");
707 }
708
709 //sends message to another device-
710 private void sendEmail(String[] emailAddresses, String[] carbonCopies,
711 String subject, String message)
712 {
713 Intent emailIntent = new Intent(Intent.ACTION_SEND);
714 emailIntent.setData(Uri.parse("mailto:"));
715 String[] to = emailAddresses;
716 String[] cc = carbonCopies;
717 emailIntent.putExtra(Intent.EXTRA_EMAIL, to);
718 emailIntent.putExtra(Intent.EXTRA_CC, cc);
719 emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
720 emailIntent.putExtra(Intent.EXTRA_TEXT, message);
721 emailIntent.setType("message/rfc822");
722 startActivity(Intent.createChooser(emailIntent, "Email"));
723 }
724
725 - SPAJANJE HTTP
726
727private InputStream OpenHttpConnection(String urlString)
728 throws IOException
729 {
730 InputStream in = null;
731 int response = -1;
732
733 URL url = new URL(urlString);
734 URLConnection conn = url.openConnection();
735
736 if (!(conn instanceof HttpURLConnection))
737 throw new IOException("Not an HTTP connection");
738 try{
739 HttpURLConnection httpConn = (HttpURLConnection) conn;
740 httpConn.setAllowUserInteraction(false);
741 httpConn.setInstanceFollowRedirects(true);
742 httpConn.setRequestMethod("GET");
743 httpConn.connect();
744 response = httpConn.getResponseCode();
745 if (response == HttpURLConnection.HTTP_OK) {
746 in = httpConn.getInputStream();
747 }
748 }
749 catch (Exception ex)
750 {
751 Log.d("Networking", ex.getLocalizedMessage());
752 throw new IOException("Error connecting");
753 }
754 return in;
755 }
756
757 - ZAD33 NAPISITE APLIKACIJU KOJA DOWNLADA SLIKU S WEBA I PRIKAZUJE JE.
758
759
760
761 - PERMISSION
762
763<uses-permission android:name="android.permission.INTERNET"/>
764
765 - DOWNLOAD SLIKE
766
767 private Bitmap DownloadImage(String URL)
768 {
769 Bitmap bitmap = null;
770 InputStream in = null;
771 try {
772 in = OpenHttpConnection(URL);
773 bitmap = BitmapFactory.decodeStream(in);
774 in.close();
775 } catch (IOException e1) {
776 Log.d("NetworkingActivity", e1.getLocalizedMessage());
777 }
778 return bitmap;
779 }
780
781
782 private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
783 protected Bitmap doInBackground(String... urls) {
784 return DownloadImage(urls[0]);
785 }
786
787 protected void onPostExecute(Bitmap result) {
788 ImageView img = (ImageView) findViewById(R.id.img);
789 img.setImageBitmap(result);
790 }
791 }
792
793 - ZAD34 NAPISITE APLIKACIJU KOJA DOWNLOADA TEKSTUALNI FILE S WEBA I ISPISUJE GA.
794
795
796 - DOWNLOAD TEKSTA
797
798 private String DownloadText(String URL)
799 {
800 int BUFFER_SIZE = 2000;
801 InputStream in = null;
802 try {
803 in = OpenHttpConnection(URL);
804 } catch (IOException e) {
805 Log.d("NetworkingActivity", e.getLocalizedMessage());
806 return "";
807 }
808
809 InputStreamReader isr = new InputStreamReader(in);
810 int charRead;
811 String str = "";
812 char[] inputBuffer = new char[BUFFER_SIZE];
813 try {
814 while ((charRead = isr.read(inputBuffer))>0) {
815 //---convert the chars to a String---
816 String readString =
817 String.copyValueOf(inputBuffer, 0, charRead);
818 str += readString;
819 inputBuffer = new char[BUFFER_SIZE];
820 }
821 in.close();
822 } catch (IOException e) {
823 Log.d("NetworkingActivity", e.getLocalizedMessage());
824 return "";
825 }
826 return str;
827 }
828
829 private class DownloadTextTask extends AsyncTask<String, Void, String> {
830 protected String doInBackground(String... urls) {
831 return DownloadText(urls[0]);
832 }
833
834 @Override
835 protected void onPostExecute(String result) {
836 Toast.makeText(getBaseContext(), result, Toast.LENGTH_LONG).show();
837 }
838 }
839
840
841 - ZAD MODIFICIRAJTE ZADATAK 33 I 34 TAKO DA SE ODJEDNOM PRIKAZUJU DOWNLOADANA SLIKA I TEKST, I TO TEKST IZNAD SLIKE. TEKST SE NE SMIJE ISPISIVATI U TOASTU, TJ NE SMIJE BITI PROLAZAN.
842
843--------------------------------------------------------------------------------------------------------------------------------------
844 USLUGE
845--------------------------------------------------------------------------------------------------------------------------------------
846
847
848 - STARTANJE SERVICE-A
849
850 startService(new Intent(getBaseContext(),MyService.class));
851ili izvana (iz druge aplikacije):
852startService(new Intent("hr.math.MyService"));
853
854
855 - KONSTANTE ONSTARTCOMMAND()
856
857int START_NOT_STICKY = ako je Service killed ne restarta se automatski
858int START_STICKY = restarta se automatski ali bez ponovne predaje zadnjeg Intenta
859int START_REDELIVER_INTENT = restarta uz ponovnu predaju zadnjeg Intenta
860
861 - ZAD35 NAPISITE APLIKACIJU KOJA SADRZI SERVICE KOJI RADI NEPREKIDNO DOK GA NE ZAUSTAVIMO EKSPLICITNO, ISPISUJE ODGOVARAJUCU PORUKU KAD JE STARTAN I KAD JE UGASEN. SERVICE TREBA SVAKIH 1000 MILISEKUNDI ISPISATI PORUKU S VRIJEDNOSTI BROJACA U LOGCAT.
862
863
864
865 - SERVICE
866
867public class MyService extends Service {
868
869 //za timer:
870 int counter = 0;
871
872 static final int UPDATE_INTERVAL = 1000;
873 private Timer timer = new Timer();
874 // do tuda za timer
875
876 @Override
877 public IBinder onBind(Intent arg0) {
878 return null;
879 }
880
881
882 @Override
883 public int onStartCommand(Intent intent, int flags, int startId) {
884 // ovaj servis radi dok ga se ne zaustavi eksplicitno
885 // dakle vraca sticky
886
887 Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
888
889 //za timer:
890 doSomethingRepeatedly();
891
892
893 return START_STICKY;
894 }
895
896//za timer
897 private void doSomethingRepeatedly() {
898 timer.scheduleAtFixedRate( new TimerTask() {
899 public void run() {
900 Log.d("MyService", String.valueOf(++counter));
901 }
902 }, 0, UPDATE_INTERVAL);
903 }
904
905 @Override
906 public void onDestroy() {
907 super.onDestroy();
908
909 //za timer
910 if (timer != null){
911 timer.cancel();
912
913 }
914
915 Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
916 }
917}
918
919
920
921 - SERVICE MAIN
922
923
924 public void startService(View view) {
925 startService(new Intent(getBaseContext(), MyService.class));
926 }
927
928 public void stopService(View view) {
929 stopService(new Intent(getBaseContext(), MyService.class));
930 }
931
932 - NOTIFICATION
933
934public class NotificationView extends Activity
935{
936 @Override
937 public void onCreate(Bundle savedInstanceState)
938 {
939 super.onCreate(savedInstanceState);
940 setContentView(R.layout.notification);
941
942 //---look up the notification manager service---
943 NotificationManager nm = (NotificationManager)
944 getSystemService(NOTIFICATION_SERVICE);
945
946 //---cancel the notification that we started---
947 nm.cancel(getIntent().getExtras().getInt("notificationID"));
948 }
949}
950
951 - HANDLE IMENA
952
953NOTIFICATION_SERVICE = za Notification Manager
954ACTIVITY_SERVICE = za Activity MAnager
955DOWNLOAD_SERVICE = za Download Manager
956
957 - PATTERN VIBRACIJE
958
959long[] {100, 250, 100, 500}
960
961 - ZVUCNI SIGNAL
962
963Uri ringURI=Uri.fromFile(new File("system/media/audio/ringtones/ringer.mp3");
964
965 - ZAD36 NAPISITE NOVU APLIKACIJU KOJA PRIKAZUJE NOTIFICATION.
966
967
968
969 - ZA GUMB
970
971id="@+id/btn_displaynotif"
972text -> postaviti na npr. Prikazi notifikaciju (u @String)
973onClick="onClick"
974
975 - NOTIFICATIONVIEW
976
977//dohvat Notification Managera
978 NotificationManager nm=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
979 //cancel metoda za gasenje notificationa na kraju
980 nm.cancel(getIntent().getExtras().getInt("notificationID"));
981
982 - NOTIFICATION MANIFEST
983
984 <uses-permission android:name="android.permission.VIBRATE" />
985
986
987<activity
988 android:name=".NotificationView"
989 android:label="Details of notification" >
990 <intent-filter>
991 <action android:name="android.intent.action.MAIN" />
992
993 <category android:name="android.intent.category.DEFAULT" />
994 </intent-filter>
995 </activity>
996
997 - NOTIFICATION MAIN
998
999public void onClick(View view) {
1000 displayNotification();
1001 }
1002
1003
1004 protected void displayNotification()
1005 {
1006 //---PendingIntent to launch activity if the user selects
1007 // this notification---
1008 Intent i = new Intent(this, NotificationView.class);
1009
1010 i.putExtra("notificationID", notificationID);
1011
1012
1013 PendingIntent pendingIntent =
1014 PendingIntent.getActivity(this, 0, i, 0);
1015
1016 long[] vibrate = new long[] { 100, 250, 100, 500};
1017
1018//Notification Channel - novo od Android O
1019
1020 String NOTIFICATION_CHANNEL_ID = "my_channel_01";
1021 CharSequence channelName = "hr.math.karga.MYNOTIF";
1022 int importance = NotificationManager.IMPORTANCE_LOW;
1023 NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, importance);
1024 notificationChannel.enableLights(true);
1025 notificationChannel.setLightColor(Color.RED);
1026 notificationChannel.enableVibration(true);
1027 notificationChannel.setVibrationPattern(vibrate);
1028
1029//za sve verzije
1030 NotificationManager nm = (NotificationManager)
1031 getSystemService(NOTIFICATION_SERVICE);
1032
1033// za Notification Chanel
1034
1035 nm.createNotificationChannel(notificationChannel);
1036
1037
1038
1039
1040//ovako je i u starim verzijama, jedino dodano .setChannelId (za stare verzije to brisemo)
1041
1042 Notification notif = new Notification.Builder(this)
1043 .setTicker("Reminder: meeting starts in 5 minutes")
1044 .setContentTitle("Meeting with customer at 3pm...")
1045 .setContentText("this is the second row")
1046 .setSmallIcon(R.mipmap.ic_launcher)
1047 .setWhen(System.currentTimeMillis())
1048 .setShowWhen(true)
1049 .setContentIntent(pendingIntent)
1050 .setVibrate(vibrate)
1051 .setChannelId(NOTIFICATION_CHANNEL_ID)
1052 .build();
1053 //najnovije, od API level 26.1.0., .setWhen ide po defautlu ovdje na currentTimeMillis
1054
1055/* final NotificationCompat.Builder notif = new NotificationCompat.Builder(this,NOTIFICATION_CHANNEL_ID)
1056
1057 .setDefaults(Notification.DEFAULT_ALL)
1058 .setSmallIcon(R.mipmap.ic_launcher)
1059 .setVibrate(vibrate)
1060 .setSound(null)
1061 .setChannelId(NOTIFICATION_CHANNEL_ID)
1062 .setContentTitle("Meeting with customer at 3pm...")
1063 .setContentText("this is the second row")
1064 .setPriority(NotificationCompat.PRIORITY_DEFAULT)
1065 .setTicker("Reminder: meeting starts in 5 minutes")
1066 .setContentIntent(pendingIntent)
1067 .setAutoCancel(false); */
1068
1069// za sve verzije
1070
1071 nm.notify(notificationID, notif);
1072 }
1073
1074
1075 - IMPORTANCE
1076
1077Potpuna lista svih importance vrijednosti:
1078
1079IMPORTANCE_MAX: ne koristi se
1080IMPORTANCE_HIGH: pojavljuje se svuda, daje zvucne i vizualne signale
1081IMPORTANCE_DEFAULT: pojavljuje se svuda, daje zvucne signale, ali ne ometa korisnika vizualno
1082IMPORTANCE_LOW: pojavljuje se svuda ali ne ometa korisnika
1083IMPORTANCE_MIN: samo se pojavljuje u title baru aplikacije
1084IMPORTANCE_NONE: obavijest bez vaznosti, ne pojavljuje se ni u title baru
1085
1086
1087
1088 - NOTIFICATION CHANNEL METODE
1089
1090getId()-vraca Id kanala
1091enableLights()-ako uredjaj podrzava svijetlosne signale za obavijesti, omogucava ih
1092setLightColor()-ukoliko imamo svijetlosne signale, definiramo boju (int vrijednost)
1093enableVibration()-da li ce obavijesti iz ovog kanala vibrirati kad se pojave na uredjaju
1094setVibrationPattern()-ako da, postavlja uzorak vibracije (long[])
1095setImportance()-postavlja vaznost (importance) za kanal
1096getImportance()-vraca nivo vaznosti za kanal
1097setSound()-Uri zvuka koji ce se cuti kad se obavijest pojavi na uredjaju
1098getSound()-vraca zvuk prikljucen obavijesti
1099setGroup()-postavlja obavijest u grupu
1100getGroup()-vraca grupu u kojoj je obavijest
1101setBypassDnd()-da li obavijest treba zaobici Do Not Disturb mode (vrijednost INTERRUPTION_FILTER_PRIORITY )
1102canBypassDnd()-vraca da li obavijest moze zaobici Do Not Disturb mode
1103getName()-vraca ime kanala
1104setLockScreenVisibility()-da li obavijesti trebaju biti prikazane i na zakljucanom ekranu
1105getLockscreenVisibility()-vraca da li ce obavijesti biti prikazane i na zakljucanom ekranu
1106getAudioAttributes()-vraca atribute zvuka koji je bio pripisan kanalu
1107canShowBadge()-vraca da li se obavijesti iz ovog kanala mogu pojaviti kao tocke (dots/badges) na starter ikoni aplikacije koja ih je startala
1108
1109 - ZAD NAPISITE APLIKACIJU KOJA IZVRSAVA NEKI ZADATAK (U POZADINI) KOJI TRAJE NEKO VRIJEME (NPR. DOWNLOAD NECEGA S WEBA, ILI SIMULACIJA NEKOG RADA I SLICNO), TE KAD JE ZADATAK IZVRSEN SALJE NOTIFICATION S ODGOVARAJUCOM PORUKOM.
1110
1111--------------------------------------------------------------------------------------------------------------------------------------
1112 GOOGLE MAPS
1113--------------------------------------------------------------------------------------------------------------------------------------
1114
1115
1116 - KEY
1117
1118https://web.math.pmf.unizg.hr/~karaga/android/images_2/key.jpg
1119
1120 - GOOGLEPLAY
1121
1122https://web.math.pmf.unizg.hr/~karaga/android/images_2/googleplay.jpg
1123
1124 - ZAD37 STVORITE I POKRENITE APLIKACIJU KOJA PRIKAZUJE GOOGLE MAPS KARTU.
1125
1126
1127
1128 - MENI S OPCIJAMA
1129
1130 <item
1131 android:id="@+id/menu_sethybrid"
1132 android:orderInCategory="100"
1133 android:title="Hybrid Mode"/>
1134 <item
1135 android:id="@+id/menu_showtraffic"
1136 android:orderInCategory="100"
1137 android:title="Show Traffic"/>
1138 <item
1139 android:id="@+id/menu_zoomin"
1140 android:orderInCategory="100"
1141 android:title="Zoom In"/>
1142 <item
1143 android:id="@+id/menu_zoomout"
1144 android:orderInCategory="100"
1145 android:title="Zoom Out"/>
1146 <item
1147 android:id="@+id/menu_gotolocation"
1148 android:orderInCategory="100"
1149 android:title="Go to a location"/>
1150 <item
1151 android:id="@+id/menu_addmarker"
1152 android:orderInCategory="100"
1153 android:title="Add a marker"/>
1154 <item
1155 android:id="@+id/menu_getcurrentlocation"
1156 android:orderInCategory="100"
1157 android:title="Get Current Location"/>
1158 <item
1159 android:id="@+id/menu_showcurrentlocation"
1160 android:orderInCategory="100"
1161 android:title="Show Current Location"/>
1162 <item
1163 android:id="@+id/menu_lineconnecttwopoints"
1164 android:orderInCategory="100"
1165 android:title="Line connecting 2 points"/>
1166
1167
1168// u .java
1169@Override
1170 public boolean onCreateOptionsMenu(Menu menu) {
1171 getMenuInflater().inflate(R.menu.mainmenu, menu);
1172 return true;
1173 }
1174
1175
1176 - PROMJENA VIEW-A
1177
1178// samo za stare verzije koje nemaju getMapAsync, onCreate dodati
1179
1180map = ((SupportMapFragment) getSupportFragmentManager()
1181 .findFragmentById(R.id.map)).getMap();
1182 if (map == null) {
1183 Toast.makeText(this, "Google Maps not available",
1184 Toast.LENGTH_LONG).show();
1185 }
1186
1187// na kraj klase u sve verzije
1188
1189 @Override
1190 public boolean onOptionsItemSelected(MenuItem item) {
1191
1192 switch (item.getItemId()) {
1193
1194 case R.id.menu_sethybrid:
1195 mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
1196 break;
1197 case R.id.menu_showtraffic:
1198 mMap.setTrafficEnabled(true);
1199 break;
1200
1201 }
1202 return true;
1203 }
1204
1205 - ZOOM IN/OUT
1206
1207case R.id.menu_zoomin:
1208 mMap.animateCamera(CameraUpdateFactory.zoomIn());
1209 break;
1210
1211 case R.id.menu_zoomout:
1212 mMap.animateCamera(CameraUpdateFactory.zoomOut());
1213 break;
1214
1215 - ODREDJENA LOKACIJA
1216
1217
1218
1219// u klasu
1220 private static final LatLng AMFITEATAR =
1221 new LatLng(44.873222,13.850155);
1222
1223// u switch
1224
1225 case R.id.menu_gotolocation:
1226 CameraPosition cameraPosition = new CameraPosition.Builder()
1227 .target(AMFITEATAR) // Sets the center of the map to
1228 // Golden Gate Bridge
1229 .zoom(17) // Sets the zoom
1230 .bearing(90) // Sets the orientation of the camera to east
1231 .tilt(30) // Sets the tilt of the camera to 30 degrees
1232 .build(); // Creates a CameraPosition from the builder
1233 mMap.animateCamera(CameraUpdateFactory.newCameraPosition(
1234 cameraPosition));
1235 break;
1236
1237 - SLIKA ZA OZNAKU
1238
1239https://web.math.pmf.unizg.hr/~karaga/android/images_2/pushpin.png
1240
1241 - OZNAKE NA KARTI
1242
1243 case R.id.menu_addmarker:
1244
1245
1246 mMap.addMarker(new MarkerOptions()
1247 .position(AMFITEATAR)
1248 .title("Arena")
1249 .icon(BitmapDescriptorFactory
1250 // .defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
1251
1252 .fromResource(R.drawable.pushpin)));
1253 break;
1254
1255 - DOHVAT TRENUTNE LOKACIJE
1256
1257case R.id.menu_getcurrentlocation:
1258 // ---get your current location and display a blue dot---
1259 mMap.setMyLocationEnabled(true);
1260
1261 break;
1262
1263 case R.id.menu_showcurrentlocation:
1264 Location myLocation = mMap.getMyLocation();
1265 LatLng myLatLng = new LatLng(myLocation.getLatitude(),
1266 myLocation.getLongitude());
1267
1268 CameraPosition myPosition = new CameraPosition.Builder()
1269 .target(myLatLng).zoom(17).bearing(90).tilt(30).build();
1270 mMap.animateCamera(
1271 CameraUpdateFactory.newCameraPosition(myPosition));
1272 //da ucita kartu na kraju
1273 mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
1274
1275 break;
1276
1277 - CRTANJE LINIJE
1278
1279//1.dio
1280private static final LatLng BUJE =
1281 new LatLng(45.413944,13.665951);
1282
1283
1284
1285//2.dio
1286 case R.id.menu_lineconnecttwopoints:
1287 //---add a marker at Apple---
1288 mMap.addMarker(new MarkerOptions()
1289 .position(BUJE)
1290 .title("Buje")
1291
1292 .icon(BitmapDescriptorFactory.defaultMarker(
1293 BitmapDescriptorFactory.HUE_AZURE)));
1294
1295 //---draw a line connecting Apple and Golden Gate Bridge---
1296 mMap.addPolyline(new PolylineOptions()
1297 .add(AMFITEATAR, BUJE).width(5).color(Color.RED));
1298 break;
1299
1300 - ZAD38 DODAJTE U SVOJU APLIKACIJU NEKOLIKO PROMJENA VIEW-A, ZOOM IN/OUT, OZNAKU, DOHVAT TRENUTNE LOKACIJE TE JEDNU LINIJU.
1301
1302
1303
1304 - ZAD POSTAVITE RAZLICITE OZNAKE U GRADOVE ZAGREB, SPLIT, RIJEKA I OSIJEK I POVEZITE IH LINIJAMA SVAKI SA SVAKIM. ISPISITE KOJA JE LINJIA NAJDULJA.