Last Updated on 10 years by Mas Herdi
Tutorial ini adalah pengembangan dari tutorial sebelumnya tentang membuat location based services di Android menggunakan Maps API v2. Pada tutorial kali ini kita akan mengimplementasikan fitur Check-In pada aplikasi location based services tersebut. Check-in ini berfungsi seperti aplikasi Foursquare, hanya saja bersifat private sehingga cuma kalian yang bisa melihat tempat-tempat yang sudah pernah kalian kunjungi. Lokasi tempat-tempat yang pernah kalian kunjungi akan ditampilkan pada peta menggunakan Android Maps API V2. Tutorial mengenai implementasi check in ini akan dibagi menjadi 3 tahap.
Oke sebelum kalian mencoba tutorial ini sangat disarankan untuk membaca postingan-postingan tentang Android Maps API v2 sebelumnya.
Pre-requisites :
- Membuat Location Based Service app menggunakan Android Maps API v2
- Panduan lengkap Database SQLite Android
- Panduan lengkap Android Maps API SDK v2
Add Check-In
Pada tutorial sebelumnya kita telah belajar tentang bagaimana mendapatkan lokasi pengguna menggunakan GPS. Sekarang kita akan belajar cara menyimpan data latitude dan longitude tersebut ke dalam database SQLite Android. Untuk proses transaksi ke database-nya kita akan menggunakan teknik MVC (Model View Controller).
Sekarang, buka kembali project yang telah kalian buat pada tutorial LBS sebelumnya, di situ kita akan menambahkan beberapa kelas baru. Masing-masing kelas tersebut adalah :
- DBDataSource.java, berfungsi sebagai controller untuk memanipulas data pada database, seperti insert, read dan delete data.
- CheckInActivity..java; berfungsi sebagai interface/view tempat kita memasukkan data check-in.
- DBLokasi.java; berfungsi sebagai model objek lokasi.
- DBMapsHelper.java; berfungsi sebagai SQLite helper, kelas ini menyimpan informasi seperti nama tabel, sintaks SQL untuk create tabel dan sebagainya.
Kemudian beberapa file XML baru yang harus ditambahkan adalah sebagai berikut:
- activity_checkin.xml; layout untuk tampilan CheckInActivity.
- fragment_dialog_checkin.xml; layout untuk check-in dialog.
- fragment_dialog_datashow.xml; layout untuk menampilkan data ketika marker diklik
- layout_check_in_item.xml; layout sederhana untuk item pada listview.
Oke, pertama-tama kita akan membuat kelas CheckInActivity.java, untuk itu kita akan membuat layoutnya terlebih dahulu. CheckInActivity akan menggunakan ListView untuk menampilkan daftar check-in yang sudah pernah dimasukkan. Di layout ini juga ada tombol check-in yang langsung berfungsi untuk memasukkan koordinat ke dalam database. Dan juga tombol untuk delete semua data, dan tombol untuk memetakan semua lokasi check-in ke Maps.
activity_checkin.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/textcheckin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="check in di sini?" android:layout_gravity="center_horizontal" android:background="#ccc" /> <LinearLayout android:id="@+id/group" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/bt_checkin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Check-in" /> <Button android:id="@+id/bt_showmap" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Petakan semua lokasi" /> <Button android:id="@+id/bt_delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Delete all" /> </LinearLayout> <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
fragment_dialog_checkin.xml
Setelah layout selesai kita set, kita akan membuat SQLite helper class yang bernama DBMapsHelper.java. Kelas ini merupakan inheritance (extends) dari kelas SQLiteOpenHelper, berisi informasi tentang tabel database yang ingin kita buat, seperti:
- TABLE_NAME : nama table
- COLUMN_ID : kolom primary key pada tabel
- COLUMN_LAT : kolom untuk menyimpan data latitude
- COLUMN_LONG : kolom untuk menyimpan data longitude
- COLUMN_NAMA : kolom untuk menyimpan data nama tempat
- db_version : versi dari database
- db_name : nama dari database file (.db)
Kemudian di kelas ini juga terdapat SQL command dalam bentuk string(db_create), yang berfungsi untuk membuat database baru, dan mengupgrade apabila ada database baru. Copy pastekan kode berikut ini ke dalam kelas tersebut DBMapsHelper.java :
package id.web.twoh.twohmaps.database; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; @SuppressWarnings("unused") public class DBMapsHelper extends SQLiteOpenHelper{ public static final String TABLE_NAME = "data_lokasi"; public static final String COLUMN_ID = "_id"; public static final String COLUMN_LAT = "lat"; public static final String COLUMN_LONG = "long"; public static final String COLUMN_NAMA = "nama"; private static final String db_name ="lokasi.db"; private static final int db_version=1; // Database creation sql statement private static final String db_create = "create table " + TABLE_NAME + "(" + COLUMN_ID +" integer primary key autoincrement, " + COLUMN_LAT+ " varchar(50) not null, " + COLUMN_NAMA+ " varchar(255) not null, " + COLUMN_LONG+ " varchar(50) not null);"; public DBMapsHelper(Context context) { super(context, db_name, null, db_version); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(db_create); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.w(DBMapsHelper.class.getName(),"Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data"); db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); } }
Setelah helper, kita akan membuat model untuk object lokasi yang akan kita masukkan ke dalam database. Kelas ini bernama DBLokasi.java, DBLokasi mempunyai atribut berupa, lat (latitude), lng (longitude), dan id (primary key). Dan juga beberapa methods yang berfungsi sebagai getter dan setter. Ada satu method toString() yang nantinya akan digunakan untuk menampilkan info pada tampilan ListView. Berikut adalah kodenya :
DBLokasi.java
package id.web.twoh.twohmaps.model; import java.io.Serializable; public class DBLokasi implements Serializable{ /** * */ private static final long serialVersionUID = -151607691806704480L; private long id; private String lat; private String lng; private String nama; private double latD; private double lngD; public DBLokasi() { } public long getId() { return id; } public void setId(long id) { this.id = id; } // Will be used by the ArrayAdapter in the ListView @Override public String toString() { return "("+id+")"+" Nama : "+nama+" "+" ("+lat+" , "+lng+")"; } public String getLat() { return lat; } public void setLat(String lat) { this.lat = lat; } public String getLng() { return lng; } public void setLng(String lng) { this.lng = lng; } public int describeContents() { // TODO Auto-generated method stub return 0; } public String getNama() { return nama; } public void setNama(String nama) { this.nama = nama; } public double getLatD() { latD = Double.parseDouble(lat); return latD; } public void setLatD(double latD) { this.latD = latD; } public double getLngD() { lngD = Double.parseDouble(lng); return lngD; } public void setLngD(double lngD) { this.lngD = lngD; } }
Kemudian, kita akan membuat class controller-nya bernama DBDataSource.java, kelas ini yang berperan penting dalam proses manipulasi data/CRUD. Di kelas ini, methods yang berfungsi untuk membuat lokasi baru, memasukkan lokasi ke dalam database, mendelete lokasi dan lain sebagainya diimplementasikan. Cara kerjanya, awalnya kelas ini akan membuat sebuah database baru dengan cara menginstanstiasi kelas DBMapsHelper, dan mengambil database dari sana. Kemudian database itulah yang nantinya akan dimanipulasi pada saat transaksi data. Penjelasan lebih lanjut ada pada komen di source code :
DBDataSource.java
package id.web.twoh.twohmaps.database; import id.web.twoh.twohmaps.model.DBLokasi; import java.util.ArrayList; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; public class DBDataSource { // Inisialisasi database fields private SQLiteDatabase database; private DBMapsHelper dbHelper; // Ambil konstanta private String[] allColumns = { DBMapsHelper.COLUMN_ID, DBMapsHelper.COLUMN_LAT, DBMapsHelper.COLUMN_LONG, DBMapsHelper.COLUMN_NAMA }; // Menggunakan DBMapsHelper yang diiinisialisasi pada konstruktor public DBDataSource(Context context) { dbHelper = new DBMapsHelper(context); } // Mengambil sebuah database yang bisa digunakan public void open() throws SQLException { database = dbHelper.getWritableDatabase(); } public void close() { dbHelper.close(); } // Method yang berfungsi untuk membuat lokasi baru dan memasukkannya ke dalam database public DBLokasi createLokasi(DBLokasi lokasi) { ContentValues values = new ContentValues(); values.put(DBMapsHelper.COLUMN_LAT, lokasi.getLat()); values.put(DBMapsHelper.COLUMN_LONG, lokasi.getLng()); values.put(DBMapsHelper.COLUMN_NAMA, lokasi.getNama()); long insertId = database.insert(DBMapsHelper.TABLE_NAME, null, values); Cursor cursor = database.query(DBMapsHelper.TABLE_NAME, allColumns, DBMapsHelper.COLUMN_ID + " = " + insertId, null, null, null, null); cursor.moveToFirst(); DBLokasi newLokasi = cursorToLokasi(cursor); cursor.close(); return newLokasi; } // Method yang berfungsi untuk menghapus lokasi berdasarkan ID public void deleteLokasi(DBLokasi lokasi) { long id = lokasi.getId(); System.out.println("Lokasi deleted with id: " + id); database.delete(DBMapsHelper.TABLE_NAME, DBMapsHelper.COLUMN_ID + " = " + id, null); } // Method yang berfungsi untuk menghapus semua data lokasi yang tersimpan public void deleteAllLokasi() { database.execSQL("DELETE FROM "+ DBMapsHelper.TABLE_NAME); } // Method yang berfungsi untuk mengambil semua lokasi public ArrayList<DBLokasi> getAllLokasi() { ArrayList<DBLokasi> daftarLokasi = new ArrayList<DBLokasi>(); Cursor cursor = database.query(DBMapsHelper.TABLE_NAME, allColumns, null, null, null, null, null); cursor.moveToFirst(); while (!cursor.isAfterLast()) { DBLokasi lokasi = cursorToLokasi(cursor); daftarLokasi.add(lokasi); cursor.moveToNext(); } // Make sure to close the cursor cursor.close(); return daftarLokasi; } // method yang berfungsi untuk mengambil data lokasi baru berdasarkan ID public DBLokasi getLokasi(int id) { DBLokasi lokasi = new DBLokasi(); Cursor cursor = database.query(DBMapsHelper.TABLE_NAME, allColumns, "_id ="+id, null, null, null, null); cursor.moveToFirst(); lokasi = cursorToLokasi(cursor); cursor.close(); return lokasi; } // Method yang berfungsi untuk membuat sebuah objek lokasi baru yang nantinya akan dimasukkan ke dalam database private DBLokasi cursorToLokasi(Cursor cursor) { DBLokasi lokasi = new DBLokasi(); //Log.v("info", "The getLONG "+cursor.getLong(0)); //Log.v("info", "The setLatLng "+cursor.getString(1)+","+cursor.getString(2)+cursor.getString(3)+cursor.getString(4)+cursor.getString(5)+cursor.getString(6)+cursor.getString(7)); lokasi.setId(cursor.getLong(0)); lokasi.setLat(cursor.getString(1)); lokasi.setLng(cursor.getString(2)); lokasi.setNama(cursor.getString(3)); return lokasi; } }
Yups, setelah semuanya lengkap, sekarang kita akan membuat kelas terakhir yang berfungsi sebagai view, bernama CheckInActivity.java. Kelas ini berfungsi sebagai interface yang akan menampilkan data checkin ke dalam ListView.
Oh iya, sebelum membuat kelas ini, kita pertama-tama harus memodifikasi main class yang bernama MainActivity.java (lihat file di GitHub), kita akan tambahkan intent sehingga tombol checkin pada main menu dapat berfungsi. Yaitu pada method berikut :
public void switchToCheckIn() { Intent i = new Intent(getActivity(), CheckInActivity.class); Bundle b = new Bundle(); if(location!=null) { b.putDouble("longitude", location.getLongitude()); b.putDouble("latitude", location.getLatitude()); Log.v("info", "The lat "+location.getLatitude()); Log.v("info", "The lng "+location.getLongitude()); i.putExtras(b); startActivity(i); }else { Toast.makeText(getActivity(), "Nyalakan lokasimu", Toast.LENGTH_LONG).show(); } }
Dan tambahkan juga kelas ChekckInActivity ke dalam daftar Activity pada AndroidManifest.xml (lihat file di GitHub).
CheckInActivity.java
package id.web.twoh.twohmaps; import java.util.ArrayList; import id.web.twoh.twohmaps.R; import id.web.twoh.twohmaps.database.DBDataSource; import id.web.twoh.twohmaps.model.DBLokasi; import android.app.Dialog; import android.app.ListActivity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemLongClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; public class CheckInActivity extends ListActivity implements OnItemLongClickListener{ private TextView tvCheckin; private DBDataSource dataSource; private Button btCheck; private Button btShowAll; private Button btDelete; private double lat,lng; private ArrayList<DBLokasi> values; private ArrayAdapter<DBLokasi> adapter; ListView lv; public static final String TAG = CheckInActivity.class.getSimpleName(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_checkin); dataSource = new DBDataSource(this); dataSource.open(); values = dataSource.getAllLokasi(); btCheck = (Button)findViewById(R.id.bt_checkin); btDelete = (Button) findViewById(R.id.bt_delete); btShowAll = (Button)findViewById(R.id.bt_showmap); tvCheckin = (TextView) findViewById(R.id.textcheckin); btDelete.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { dataSource.deleteAllLokasi(); adapter.clear(); adapter.notifyDataSetChanged(); Toast.makeText(CheckInActivity.this, "All data deleted", Toast.LENGTH_SHORT).show(); } }); btCheck.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(CheckInActivity.this, "checked in", Toast.LENGTH_LONG); final Dialog dialog = new Dialog(CheckInActivity.this); dialog.setTitle("Input Data Checkin"); dialog.setContentView(R.layout.fragment_dialog_checkin); TextView text = (TextView)dialog.findViewById(R.id.tv_koordinat); Button btSave = (Button) dialog.findViewById(R.id.bt_checkin_save); Button btCancel = (Button) dialog.findViewById(R.id.bt_checkin_cancel); final EditText etNama = (EditText) dialog.findViewById(R.id.et_nama); text.setText("Masukkan data check-in di koordinat ("+lat+","+lng+") : "); btCancel.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { dialog.cancel(); } }); btSave.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { DBLokasi lokasi = null; DBLokasi lokasiTemp = new DBLokasi(); lokasiTemp.setLat(lat+""); lokasiTemp.setLng(lng+""); lokasiTemp.setNama(etNama.getText().toString()); lokasi = dataSource.createLokasi(lokasiTemp); if(lokasi!=null) { adapter.add(lokasi); adapter.notifyDataSetChanged(); } dialog.cancel(); } }); dialog.show(); } }); btShowAll.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // lihat di postingan selanjutnya } }); Bundle b = this.getIntent().getExtras(); lat = b.getDouble("latitude"); lng = b.getDouble("longitude"); tvCheckin.setText("Ingin check-in di koordinat berikut ? "+lat+","+lng); dataSource = new DBDataSource(this); dataSource.open(); values = dataSource.getAllLokasi(); adapter = new ArrayAdapter<DBLokasi>(this,R.layout.layout_checkin_item, values); setListAdapter(adapter); lv = getListView(); lv.setOnItemLongClickListener(new OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { DBLokasi lokTemp = adapter.getItem(position); dataSource.deleteLokasi(lokTemp); Toast.makeText(CheckInActivity.this, "location has been deleted", Toast.LENGTH_SHORT).show(); adapter.remove(lokTemp); adapter.notifyDataSetChanged(); return true; } }); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); DBLokasi lokasi = dataSource.getLokasi((int)adapter.getItem(position).getId()); if(lokasi!=null) // lihat di postingan selanjutnya else Toast.makeText(this, "location is null", Toast.LENGTH_LONG).show(); } @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { DBLokasi lokasi = dataSource.getLokasi(position+1); if(lokasi!=null) { dataSource.deleteLokasi(lokasi); Toast.makeText(CheckInActivity.this, "location has been deleted", Toast.LENGTH_SHORT).show(); adapter.remove(lokasi); adapter.notifyDataSetChanged(); }else Toast.makeText(CheckInActivity.this, "location is null", Toast.LENGTH_SHORT).show(); return false; } }
Pada aplikasi TWOH Maps V2 ini kita bisa melakukan pengecekan GPS apakah aktif atau tidak. Karena pada versi sebelumnya yang tidak melakukan pengecekan, akan terjadi error apabila kita klik View On Map/Get Location, padahal GPS mati. Koordinat pada peta murni didapat dari GPS.
Kemudian ada fungsionalitas tambahan pada kelas CheckInActivity.java, yaitu untuk melakukan penghapusan data. Untuk menghapus semua data bisa menggunakan tombol “Delete All”, dan untuk menghapus data satu persatu tinggal lakukan long click pada list item untuk menghapus data check-in yang diinginkan.
Demo
Oke, halaman awalnya masih sama seperti pada aplikasi LBS di tutorial sebelumnya :p :
Setelah itu klik tombol Check-In dan kita akan masuk ke tampilan check-in menu dimana sudah ada satu lokasi di sana :
Coba kita tambahkan satu lokasi lagi :D. Klik tombol Check-In dan akan muncul dialog dimana kita bisa memasukkan nama lokasi :
Klik save, dan lokasi pun akan muncul pada daftar check-in:
Lakukan long-click pada listview item untuk menghapus lokasi :
Kemudian klik tombol “Delete All” untuk menghapus lokasi :). Inilah tampilan halaman Check-in dengan lokasi yang kosong.
Conclusion
Kira-kira seperti itu hal-hal yang perlu ditambahkan. Tutorial selanjutnya adalah untuk menampilkan lokasi yang sudah tersimpan di SQLite ke dalam peta.
Atau kalau kalian ingin mencoba meng-oprek-nya sendiri, bisa download project TWOH-Maps v2 pada repositori GitHub saya.
Jangan sungkan untuk bertanya lewat komentar atau di forum apabila ada yang kurang jelas ! Semoga membantu 😀
siang gan,
gan saya coba untuk ikuti tutorial ini dari awal. tapi pada CheckInActivity.java ada error pada bagian :
dialog.setContentView(R.layout.fragment_dialog_checkin);
TextView text = (TextView)dialog.findViewById(R.id.tv_koordinat);
Button btSave = (Button) dialog.findViewById(R.id.bt_checkin_save);
Button btCancel = (Button) dialog.findViewById(R.id.bt_checkin_cancel);
final EditText etNama = (EditText) dialog.findViewById(R.id.et_nama);
apakah ada layout xml yang belum di ikut sertakan pada aplikasi ini gan,..
mohon pencerahannya gan
Yup 😀
Maaf, sepertinya layout fragment_dialog_checkin nya missing.
Untuk file nya silahkan bisa dilihat di sini
https://github.com/twoh/TWOH-MapsV2/blob/master/res/layout/fragment_dialog_checkin.xml
🙂
udah saya ikutin update fragment dialog checkin nya masih salah aja gan
salah pada bagian
android:hint=”@string/checkin_hint_nama”
android:text=”@string/bt_cancel”
android:text=”@string/bt_save”
gan mau nanya,kalau mau buat peta dan lokasi tempat didalam kampus semisal kantin,laboratorium,loket,ruang jurusan dll, di android apa saja yang diperlukan dan bagaimana langkah2nya?
Untuk indoor maps… saat ini belum ada caranya kalau dari Google Maps. Kalau mau bisa membuat render model 3D bangunan sendiri beserta denah ruangan-ruangannya, kemudian model 3D itu dioverlay di atas peta, itupun petanya pakai 3rd party library dan bukan peta Google. Lumayan ribet caranya gan 🙂
cara nya gimana gan membuat render model 3D bangunan sendiri beserta denah ruangan-ruangannya, kemudian model 3D itu dioverlay di atas peta? itu tetap memerlukan google maps dan gps ?
mas boleh tanya nggak? klo misalnya kita mau membuat button untuk menampilkan lokasi yg kita marker bisa nggak ya? klo bisa gmn mas? makasih 😀
bisa… gampangnya sih lokasi marker itu disimpan di object tombol, yang ketika diklik akan langsung menuju ke lokasi marker tersebut
permisi gan mau tanya. ada tidak tutorial menampilkan semua marker sesuai kategori yang kita pilih. databasenya mysql. misal saya ingin menampilkan semua bank B. maka nnti yang muncul di maps adalah semua marker bank B. mohon pencerahannya gan. thanks
permisi gan saya nyoba coding punya agan cuma pas buka map kok langsung close di android studionya keluar error seperti ini :
E/AndroidRuntime: FATAL EXCEPTION: main
Process: id.web.twoh.twohmaps, PID: 19766
java.lang.RuntimeException: Unable to start activity ComponentInfo{id.web.twoh.twohmaps/id.web.twoh.twohmaps.MapsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method ‘void com.google.android.gms.maps.GoogleMap.setMyLocationEnabled(boolean)’ on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
at android.app.ActivityThread.access$800(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5371)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:945)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:740)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method ‘void com.google.android.gms.maps.GoogleMap.setMyLocationEnabled(boolean)’ on a null object reference
at id.web.twoh.twohmaps.MapsActivity.onCreate(MapsActivity.java:46)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2332)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
at android.app.ActivityThread.access$800(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5371)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:945)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:740)
kenapa ya gan?mohon bantuannya,thanks
source codenya sudah dari GitHub?
gan, yang ini github nya juga ga bisa dibuka yang main activity sama android manifest nya, belum update ya ?
GitHub nya ini bukan https://github.com/twoh/twoh-mapsv2 ?
Coba compile dari situ, as project, kalo ga bisa coba compile as module
mas waktu diopen atau import muncul gini
Error:Cannot read packageName from D:\Riset Android\twoh-mapsv2-master\src\main\AndroidManifest.xml
Nama package nya coba disamain mas