Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 0 additions & 12 deletions .idea/runConfigurations.xml

This file was deleted.

32 changes: 17 additions & 15 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
compileSdkVersion 33
defaultConfig {
applicationId "com.eagb.blockchainexamplewithkotlin"
minSdkVersion 21
targetSdkVersion 29
minSdkVersion 23
targetSdkVersion 33
versionCode 3
versionName "1.0.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Expand All @@ -24,20 +23,23 @@ android {
buildFeatures {
viewBinding = true
}

namespace 'com.eagb.blockchainexamplewithkotlin'
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.google.android.material:material:1.2.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
implementation 'com.google.android.play:core:1.8.0'
implementation "com.google.android.material:material:$material_version"
implementation "androidx.legacy:legacy-support-v4:$legacy_support_version"
implementation "androidx.appcompat:appcompat:$appcompat_version"
implementation "androidx.core:core-ktx:$core_ktx_version"
implementation "androidx.constraintlayout:constraintlayout:$constraintlayout_version"
implementation "androidx.coordinatorlayout:coordinatorlayout:$coordinatorlayout_version"
implementation "com.google.android.play:core:$play_core_version"
implementation "androidx.compose.material3:material3:$material3_version"

testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
testImplementation "junit:junit:$junit_version"
androidTestImplementation "androidx.test:runner:$test_runner_version"
androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_core_version"
}
11 changes: 5 additions & 6 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.eagb.blockchainexamplewithkotlin">
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />

<application
android:name=".activities.BaseApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.DayNight"
android:theme="@style/Theme.App"
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
<activity
android:name=".activities.MainActivity"
android:label="@string/app_name"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar"
android:theme="@style/Theme.App"
tools:ignore="LockedOrientationActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.eagb.blockchainexamplewithkotlin.activities

import android.app.Application
import com.google.android.material.color.DynamicColors

class BaseApplication: Application() {

override fun onCreate() {
super.onCreate()

// Applies dynamic color
DynamicColors.applyToActivitiesIfAvailable(this)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.eagb.blockchainexamplewithkotlin.R
import com.eagb.blockchainexamplewithkotlin.databinding.ActivityMainBinding
import com.eagb.blockchainexamplewithkotlin.databinding.ContentMainBinding
import com.eagb.blockchainexamplewithkotlin.databinding.InputContainerBinding
import com.eagb.blockchainexamplewithkotlin.fragments.MoreInfoFragment
import com.eagb.blockchainexamplewithkotlin.fragments.PowFragment
import com.eagb.blockchainexamplewithkotlin.managers.BlockChainManager
Expand All @@ -26,9 +26,10 @@ import com.google.android.play.core.appupdate.AppUpdateManagerFactory
import com.google.android.play.core.install.model.AppUpdateType
import com.google.android.play.core.install.model.UpdateAvailability

class MainActivity : AppCompatActivity() {
class MainActivity : AppCompatActivity(R.layout.activity_main) {

private lateinit var viewBindingContent: ContentMainBinding
private lateinit var binding: ActivityMainBinding
private lateinit var bindingInput: InputContainerBinding
private lateinit var prefs: SharedPreferencesManager
private lateinit var appUpdateManager: AppUpdateManager

Expand All @@ -47,6 +48,14 @@ class MainActivity : AppCompatActivity() {
prefs = SharedPreferencesManager(this)
isDarkThemeActivated = prefs.isDarkTheme()

/*val dynamicColor = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
val colorScheme = if (dynamicColor) {
val context = LocalContext.current
if (darkMode) dynamicLightColorScheme(context) else dynamicDarkColorScheme(context)
} else {
// Use lightColorScheme, darkColorScheme...
}*/

val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
var isPowerSaveMode: Boolean

Expand All @@ -72,51 +81,59 @@ class MainActivity : AppCompatActivity() {

// Setting the Night mode - must be done before calling super()
super.onCreate(savedInstanceState)
val viewBinding: ActivityMainBinding = ActivityMainBinding.inflate(layoutInflater)
viewBindingContent = ContentMainBinding.bind(viewBinding.contentMain.root)
val viewBinding = ActivityMainBinding.inflate(layoutInflater)
binding = ActivityMainBinding.bind(viewBinding.root)
binding.toolbar.apply {
setTitleTextColor(resources.getColor(android.R.color.white, context.theme))
setSubtitleTextColor(resources.getColor(android.R.color.white, context.theme))
}
bindingInput = InputContainerBinding.bind(binding.inputContainer.root)
setContentView(viewBinding.root)
setSupportActionBar(viewBinding.toolbar)
//setSupportActionBar(viewBinding.toolbar)
setSupportActionBar(binding.toolbar)

// Check a possible update from Play Store
checkUpdate()

isEncryptionActivated = prefs.getEncryptionStatus()

// Use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
viewBindingContent.recyclerContent.setHasFixedSize(true)
// Use a linear layout manager
viewBindingContent.recyclerContent.layoutManager = LinearLayoutManager(
this,
RecyclerView.VERTICAL,
false
)

// Setting the Progress Dialog
showProgressDialog(resources.getString(R.string.text_creating_block_chain))

// Starting BlockChain request on a thread
Thread(Runnable {
runOnUiThread {
// Initializing BlockChain...
// PROOF_OF_WORK = difficulty.
// Given some difficulty, the CPU will has to find a hash for the block
// starting with a given number of zeros.
// More Proof-of-Work will be harder to mine and will take longer time.
// Watch out!
blockChain = BlockChainManager(this, prefs.getPowValue())
viewBindingContent.recyclerContent.adapter = blockChain?.adapter
cancelProgressDialog(progressDialog)
}
}).start()
binding.recyclerContent.apply {
// Use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
setHasFixedSize(true)

// Use a linear layout manager
layoutManager =
LinearLayoutManager(context, RecyclerView.VERTICAL, false)

// Starting BlockChain request on a thread
Thread(Runnable {
runOnUiThread {
// Initializing BlockChain...
// PROOF_OF_WORK = difficulty.
// Given some difficulty, the CPU will has to find a hash for the block
// starting with a given number of zeros.
// More Proof-of-Work will be harder to mine and will take longer time.
// Watch out!
blockChain = BlockChainManager(context, prefs.getPowValue())
adapter = blockChain?.adapter
cancelProgressDialog(progressDialog)
}
}).start()
}

viewBindingContent.btnSendData.setOnClickListener {
bindingInput.btnSendData.setOnClickListener {
// Start new request on a UI thread
startBlockChain()
}
}

// Check a possible update from Play Store
/**
* Checks a possible update from Play Store.
*/
private fun checkUpdate() {
// Creates instance of the manager
appUpdateManager = AppUpdateManagerFactory.create(this)
Expand All @@ -135,7 +152,13 @@ class MainActivity : AppCompatActivity() {
}
}

// If an update exist, request for the update
/**
* If an update exist, request for the update.
*
* @param appUpdateManager is the manager to start the flow for result
* [AppUpdateManager.startUpdateFlowForResult].
* @param appUpdateInfo gets the app info [AppUpdateInfo].
*/
private fun startTheUpdate(
appUpdateManager: AppUpdateManager,
appUpdateInfo: AppUpdateInfo
Expand Down Expand Up @@ -163,7 +186,9 @@ class MainActivity : AppCompatActivity() {
resumeTheUpdate()
}

// Continue with the update if one exists
/**
* Continue with the update if one exists.
*/
private fun resumeTheUpdate() {
appUpdateManager
.appUpdateInfo
Expand All @@ -177,15 +202,17 @@ class MainActivity : AppCompatActivity() {
}
}

// Starting new request on a thread
/**
* Starting new request or block on a thread.
*/
private fun startBlockChain() {
// Setting the Progress Dialog
showProgressDialog(resources.getString(R.string.text_mining_blocks))

runOnUiThread {
blockChain?.let {
if (viewBindingContent.editMessage.text != null && viewBindingContent.recyclerContent.adapter != null) {
val message = viewBindingContent.editMessage.text.toString()
if (bindingInput.editMessage.text != null && binding.recyclerContent.adapter != null) {
val message = bindingInput.editMessage.text.toString()

if (message.isNotEmpty()) {

Expand All @@ -212,7 +239,6 @@ class MainActivity : AppCompatActivity() {
).show()
}
}
viewBindingContent.recyclerContent.scrollToPosition(it.adapter.itemCount - 1)

// Validate block's data
println(
Expand All @@ -223,9 +249,10 @@ class MainActivity : AppCompatActivity() {
)
if (it.isBlockChainValid()) {
// Preparing data to insert to RecyclerView
viewBindingContent.recyclerContent.adapter?.notifyDataSetChanged()
binding.recyclerContent.smoothScrollToPosition(it.adapter.itemCount - 1)
binding.recyclerContent.adapter?.notifyDataSetChanged()
// Cleaning the EditText
viewBindingContent.editMessage.setText("")
bindingInput.editMessage.setText("")
} else {
Toast.makeText(
this,
Expand Down Expand Up @@ -253,7 +280,11 @@ class MainActivity : AppCompatActivity() {
}
}

// Setting the Progress Dialog
/**
* Setting the Progress Dialog.
*
* @param loadingMessage is the message in [String].
*/
private fun showProgressDialog(loadingMessage: String) {
progressDialog = ProgressDialog(this@MainActivity)
progressDialog!!.setProgressStyle(ProgressDialog.STYLE_SPINNER)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import androidx.recyclerview.widget.RecyclerView
import com.eagb.blockchainexamplewithkotlin.R
import com.eagb.blockchainexamplewithkotlin.databinding.ItemBlockDataBinding
import com.eagb.blockchainexamplewithkotlin.holders.RecyclerViewHolder
import com.eagb.blockchainexamplewithkotlin.models.BlockModel
import java.util.*

class BlockAdapter(
private val context: Context,
Expand All @@ -21,29 +20,15 @@ class BlockAdapter(
// Create new views (invoked by the layout manager)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder {
// Inflate the layout, initialize the View Holder
val view = LayoutInflater.from(parent.context).inflate(
viewType,
parent,
false
)

val view = ItemBlockDataBinding.inflate(LayoutInflater.from(parent.context))
return RecyclerViewHolder(view)
}

override fun onBindViewHolder(viewHolder: RecyclerViewHolder, position: Int) {
// Use the provided View Holder on the onCreateViewHolder method
// to populate the current row on the RecyclerView
blocks?.let {
viewHolder.txtIndex.text = String.format(
context.getString(R.string.title_block_number), it[position]?.getIndex()
)
viewHolder.txtPreviousHash.text =
if (it[position]?.getPreviousHash() != null) it[position]?.getPreviousHash() else "Null"
viewHolder.txtTimestamp.text = Date(
it[position]!!.getTimestamp()
).toString()
viewHolder.txtData.text = it[position]?.getData()
viewHolder.txtHash.text = it[position]?.getHash()
viewHolder.collectData(context, it[position]!!)
}

setAnimation(viewHolder.itemView, position)
Expand All @@ -59,11 +44,6 @@ class BlockAdapter(
}

// Return the size of list of data (invoked by the layout manager)
override fun getItemCount(): Int {
return blocks?.size ?: 0
}
override fun getItemCount(): Int = blocks?.size ?: 0

override fun getItemViewType(position: Int): Int {
return R.layout.item_block_data
}
}
Loading