diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 36ee5747c3903c72336d7ebb7f23942611139bf5..6356ee5e965138872cabfd64d74a2a12bd45c12d 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -15,7 +15,7 @@ </deviceKey> </Target> </targetSelectedWithDropDown> - <timeTargetWasSelectedWithDropDown value="2024-03-11T13:50:48.684911700Z" /> + <timeTargetWasSelectedWithDropDown value="2024-03-12T15:43:38.986853700Z" /> </State> </entry> </value> diff --git a/app/build.gradle.kts b/app/build.gradle.kts index d4443457f280209f1fec5c38e25b0d8bf4acaf7d..f5e86c55731d3c9c6e2f943bc478d49712836e3a 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -51,4 +51,6 @@ dependencies { testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") + implementation ("androidx.navigation:navigation-fragment-ktx:2.4.0-alpha10") + implementation ("androidx.navigation:navigation-ui-ktx:2.4.0-alpha10") } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ec8d56f739437541ec42570e52f9ab5c146d90f5..2296cceb1643b2b66e3a078996c896bc3b932302 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools"> + xmlns:tools="http://schemas.android.com/tools" + package="com.example.tubespbd"> + + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <application android:allowBackup="true" @@ -12,16 +16,15 @@ android:supportsRtl="true" android:theme="@style/Theme.Tubespbd" tools:targetApi="31"> + <activity android:name=".MainActivity" android:exported="true" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> - -</manifest> \ No newline at end of file +</manifest> diff --git a/app/src/main/java/com/example/tubespbd/MainActivity.kt b/app/src/main/java/com/example/tubespbd/MainActivity.kt index 23d2a1c423608c40beae7ad2b6347d105a03f706..730bcf399ab7a0b907b94fdb38670958d76d406e 100644 --- a/app/src/main/java/com/example/tubespbd/MainActivity.kt +++ b/app/src/main/java/com/example/tubespbd/MainActivity.kt @@ -1,19 +1,23 @@ package com.example.tubespbd +import android.Manifest +import android.content.pm.PackageManager import android.os.Bundle import androidx.appcompat.app.AppCompatActivity +import androidx.core.app.ActivityCompat +import com.example.tubespbd.databinding.ActivityMainBinding +import android.location.LocationManager import androidx.navigation.findNavController import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupWithNavController -import com.example.tubespbd.database.MyDBHelper -import com.example.tubespbd.databinding.ActivityMainBinding import com.google.android.material.bottomnavigation.BottomNavigationView class MainActivity : AppCompatActivity() { - private lateinit var dbHelper: MyDBHelper private lateinit var binding: ActivityMainBinding + private lateinit var locationManager: LocationManager + private lateinit var transactionManager: TransactionManager override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -22,11 +26,14 @@ class MainActivity : AppCompatActivity() { binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) + locationManager = getSystemService(LOCATION_SERVICE) as LocationManager + + checkAndRequestLocationPermissions() + val navView: BottomNavigationView = binding.navView val navController = findNavController(R.id.nav_host_fragment_activity_main) - // Passing each menu ID as a set of Ids because each - // menu should be considered as top level destinations. + val appBarConfiguration = AppBarConfiguration( setOf( R.id.navigation_home, R.id.navigation_scan, R.id.navigation_dashboard, R.id.navigation_notifications @@ -35,38 +42,70 @@ class MainActivity : AppCompatActivity() { setupActionBarWithNavController(navController, appBarConfiguration) navView.setupWithNavController(navController) - // Database - dbHelper = MyDBHelper(this) + } - // TEST DB Sementara - // Insert - val transactionId = dbHelper.insertTransaction("Mi Ayam", "Pembelian", 15000, "Bandung") + private fun initializeAfterPermissionsGranted() { + // Initialize TransactionManager after permissions are granted + transactionManager = TransactionManager(this, locationManager) + + performDatabaseOperations() + } + private fun performDatabaseOperations() { + val locationString = if (hasLocationPermissions() && isLocationEnabled()) { + transactionManager.getLocationString() + } else { + "None" + } + + val transactionId = transactionManager.insertTransaction("Mi Ayam", "Pembelian", 15000, locationString) println("Inserted transaction with ID: $transactionId") - // Retrieve - val transactions = dbHelper.getAllTransactions() - println("All transactions:") - for (transaction in transactions) { - println("Transaction ID: ${transaction.id}, Title: ${transaction.title}, Amount: ${transaction.amount}") + // Retrieve all transactions + val transactions = transactionManager.getAllTransactions() + transactions.forEach { transaction -> + println("Transaction ID: ${transaction.id}, Title: ${transaction.title}, Amount: ${transaction.amount}, Location: ${transaction.location}") } + } - // Update - val updatedRows = dbHelper.updateTransaction(transactionId.toInt(), "Mi Bakso", "Pengeluaran", 20000, "Jakarta") - println("Updated $updatedRows row(s)") - // Retrieve yang sudah di update - val updatedTransaction = dbHelper.getAllTransactions().find { it.id == transactionId.toInt() } - println("Updated transaction: ${updatedTransaction?.id}, ${updatedTransaction?.title}, ${updatedTransaction?.amount}") + private fun isLocationEnabled(): Boolean { + return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) + } + + private fun hasLocationPermissions() = ActivityCompat.checkSelfPermission( + this, Manifest.permission.ACCESS_FINE_LOCATION + ) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( + this, Manifest.permission.ACCESS_COARSE_LOCATION + ) == PackageManager.PERMISSION_GRANTED + + private fun requestLocationPermissions() { + ActivityCompat.requestPermissions( + this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION), + REQUEST_LOCATION_PERMISSION + ) + } - // Delete - val deletedRows = dbHelper.deleteTransaction(transactionId.toInt()) - println("Deleted $deletedRows row(s)") + private fun checkAndRequestLocationPermissions() { + if (!hasLocationPermissions()) { + requestLocationPermissions() + } else { + initializeAfterPermissionsGranted() + } + } - // Retrieve setelah delete - val remainingTransactions = dbHelper.getAllTransactions() - println("Transactions after deletion:") - for (transaction in remainingTransactions) { - println("Transaction ID: ${transaction.id}, Title: ${transaction.title}, Amount: ${transaction.amount}") + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array<String>, grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + if (requestCode == REQUEST_LOCATION_PERMISSION && grantResults.all { it == PackageManager.PERMISSION_GRANTED }) { + initializeAfterPermissionsGranted() + } else { + println("Location permission was denied by the user.") } } + + companion object { + private const val REQUEST_LOCATION_PERMISSION = 100 + } } + diff --git a/app/src/main/java/com/example/tubespbd/TransactionManager.kt b/app/src/main/java/com/example/tubespbd/TransactionManager.kt new file mode 100644 index 0000000000000000000000000000000000000000..94b495fdf3cb260d4219c030fabfcdc553424c7a --- /dev/null +++ b/app/src/main/java/com/example/tubespbd/TransactionManager.kt @@ -0,0 +1,45 @@ +package com.example.tubespbd + +import android.content.Context +import android.location.LocationManager +import androidx.core.app.ActivityCompat +import android.Manifest +import android.content.pm.PackageManager +import com.example.tubespbd.database.MyDBHelper +import com.example.tubespbd.database.MyDBHelper.Transaction + +class TransactionManager(private val context: Context, private val locationManager: LocationManager) { + + private val dbHelper = MyDBHelper(context) + + fun insertTransaction(title: String, type: String, amount: Int, locationString: String): Long { + val locationString = getLocationString() + return dbHelper.insertTransaction(title, type, amount, locationString) + } + + fun getAllTransactions(): List<Transaction> { + return dbHelper.getAllTransactions() + } + + fun updateTransaction(id: Int, title: String, type: String, amount: Int, location: String): Int { + return dbHelper.updateTransaction(id, title, type, amount, location) + } + + fun deleteTransaction(id: Int): Int { + return dbHelper.deleteTransaction(id) + } + + fun getLocationString(): String { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && + ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + // Permission is not granted + return "Location Permissions not granted" + } + val location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) + return if (location != null) { + "${location.latitude}, ${location.longitude}" + } else { + "Location not available" + } + } +} diff --git a/app/src/main/java/com/example/tubespbd/database/MyDBHelper.kt b/app/src/main/java/com/example/tubespbd/database/MyDBHelper.kt index 473c3005ea44757433310909a77588b687b3ddde..79602786cd0185bf9c21c67768843de146699de7 100644 --- a/app/src/main/java/com/example/tubespbd/database/MyDBHelper.kt +++ b/app/src/main/java/com/example/tubespbd/database/MyDBHelper.kt @@ -4,9 +4,16 @@ import android.content.ContentValues import android.content.Context import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteOpenHelper +import android.location.Location +import android.location.LocationManager +import android.Manifest +import androidx.core.app.ActivityCompat -class MyDBHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) { +import android.content.pm.PackageManager +import com.example.tubespbd.database.MyDBHelper.Transaction +class MyDBHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) { + private val context: Context = context data class Transaction( val id: Int, val title: String, @@ -50,6 +57,29 @@ class MyDBHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, nu } return db.insert(TABLE_NAME, null, values) } + private fun getUserLocation(locationManager: LocationManager): String { + // Check if the location permission is granted + if (ActivityCompat.checkSelfPermission( + context, + Manifest.permission.ACCESS_FINE_LOCATION + ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( + context, + Manifest.permission.ACCESS_COARSE_LOCATION + ) != PackageManager.PERMISSION_GRANTED + ) { + // Handle the case where location permission is not granted + return "Location permission not granted" + } + + // Location permission is granted, proceed with getting the location + val location: Location? = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) + return if (location != null) { + "${location.latitude}, ${location.longitude}" + } else { + "Location not available" + } + } + fun getAllTransactions(): ArrayList<Transaction> { val transactionList = ArrayList<Transaction>() @@ -58,13 +88,24 @@ class MyDBHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, nu val cursor = db.rawQuery(selectQuery, null) cursor?.use { while (cursor.moveToNext()) { - val id = cursor.getInt(cursor.getColumnIndex(COLUMN_ID)) - val title = cursor.getString(cursor.getColumnIndex(COLUMN_TITLE)) - val category = cursor.getString(cursor.getColumnIndex(COLUMN_CATEGORY)) - val amount = cursor.getInt(cursor.getColumnIndex(COLUMN_AMOUNT)) - val location = cursor.getString(cursor.getColumnIndex(COLUMN_LOCATION)) - val transaction = Transaction(id, title, category, amount, location) - transactionList.add(transaction) + val idIndex = cursor.getColumnIndex(COLUMN_ID) + val titleIndex = cursor.getColumnIndex(COLUMN_TITLE) + val categoryIndex = cursor.getColumnIndex(COLUMN_CATEGORY) + val amountIndex = cursor.getColumnIndex(COLUMN_AMOUNT) + val locationIndex = cursor.getColumnIndex(COLUMN_LOCATION) + + // Check if the column exists before accessing its index + if (idIndex != -1 && titleIndex != -1 && categoryIndex != -1 && amountIndex != -1 && locationIndex != -1) { + val id = cursor.getInt(idIndex) + val title = cursor.getString(titleIndex) + val category = cursor.getString(categoryIndex) + val amount = cursor.getInt(amountIndex) + val location = cursor.getString(locationIndex) + val transaction = Transaction(id, title, category, amount, location) + transactionList.add(transaction) + } else { + + } } } return transactionList @@ -85,4 +126,4 @@ class MyDBHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, nu val db = this.writableDatabase return db.delete(TABLE_NAME, "$COLUMN_ID = ?", arrayOf(id.toString())) } -} +} \ No newline at end of file