View list of bluetooth devices in Kotlin? - android

I have a small bluetooth project in kotlin. The code for it is below:
var mArrayAdapter: ArrayAdapter<String>? = null
val bluetoothAdapter: BluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
var myList: MutableList<String> = mutableListOf<String>()
var devices = ArrayList<BluetoothDevice>()
var devicesMap = HashMap<String, BluetoothDevice>()
class MainActivity : AppCompatActivity(), View.OnClickListener {
private val REQUEST_ENABLE_BT = 1000
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<View>(R.id.btn_scan).setOnClickListener(this)
checkBluetoothStatus()
val filter = IntentFilter(BluetoothDevice.ACTION_FOUND)
registerReceiver(receiver, filter)
mArrayAdapter = ArrayAdapter(this, R.layout.dialog_select_device)
}
private val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val action: String? = intent.action
when(action) {
BluetoothDevice.ACTION_FOUND -> {
val device: BluetoothDevice =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
val deviceName = device.name
myList.add(deviceName)
}
}
}
}
override fun onClick(v: View?) {
when (v?.id) {
R.id.btn_scan ->
startScan()
}
}
fun startScan() {
if (BluetoothAdapter.getDefaultAdapter().startDiscovery()) {
val myToast = Toast.makeText(this, myList.toString(), Toast.LENGTH_SHORT)
myToast.show()
}
}
}
When a user clicks a button, I want to be able to see a list of other bluetooth devices (which I thought the onReceive method would enable me to do). So I'm adding device names to the myList variable, which I'm then displaying in a toast. But at the moment when they click, nothing comes up. Grateful for your advice.

Related

Android NFC card emulation with specific content

class MainActivity : AppCompatActivity() {
// private var nfcAdapter: NfcAdapter? = null
lateinit var text: Button
#SuppressLint("SuspiciousIndentation")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// nfcAdapter = NfcAdapter.getDefaultAdapter(this);
text = findViewById(R.id.helo) as Button
text.setOnClickListener {
val intent = Intent(this, MyHostApduService::class.java)
Log.e("TAGGG","HELLO")
startService(intent)
}
}
}`
`class MyHostApduService : HostApduService() {
private val SELECT_APDU = byteArrayOf(
0x00.toByte(),
0xA4.toByte(),
0x04.toByte(),
0x00.toByte(),
0x08.toByte(),
0xF0.toByte(),
0x01.toByte(),
0x02.toByte(),
0x03.toByte(),
0x04.toByte(),
0x05.toByte(),
0x06.toByte()
)
private val HELLO_WORLD_APDU = "Hello World".toByteArray()
override fun processCommandApdu(commandApdu: ByteArray?, extras: Bundle?): ByteArray? {
return if (Arrays.equals(SELECT_APDU, commandApdu)) {
HELLO_WORLD_APDU
} else {
ByteArray(0)
}
}
override fun onDeactivated(reason: Int) {}
}
I need to emulate NFC card with specific content/record on my android device. Content on card should be a text something like "t100200". It s just a part of wider project and i could not find working example or tutorial. So i am not sure if is something like this possible. Thanks for any help or advice

Can I press a button in Activity A to filter a RecyclerView in Activity B?

What I want to reach is that the same RecyclerView shows different data depending on which button the App user pressed before in the MainActivity.kt.
In my MainActivity.kt I have two buttons, which both send the user to the same RecyclerView Activity (RecyclerViewLayout.kt) via Intent.
Example: The RecyclerView contains a picture of an apple and a banana. By pressing button A in MainActivity.kt, the RecyclerView in RecyclerViewLayout.kt should only show the apple. By pressing button B it should only show the banana. In my real app there are no fruits. but Tutorials, which should be filtered like described.
I gently ask for help here how to do that. Maybe there is also a better way to reach my target to filter the RecyclerView?
Thanks in Advance!
MainActivity.kt
class MainActivity : AppCompatActivity() {
private var binding:ActivityMainBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding?.root)
val buttonRecyclerView = findViewById<Button>(R.id.btn_recyclerview)
buttonRecyclerView.setOnClickListener {
val intent = Intent(this, RecyclerViewLayout::class.java)
startActivity(intent)
}
}}
RecyclerViewLayout.kt
class RecyclerViewLayout : AppCompatActivity() {
private lateinit var newRecylerview : RecyclerView
private lateinit var newArrayList : ArrayList<RecyclerViewDataClass>
private lateinit var tempArrayList : ArrayList<RecyclerViewDataClass>
lateinit var imageId : Array<Int>
lateinit var tutorialHeading : Array<String>
lateinit var tutorialText : Array<String>
lateinit var url : Array<String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_recycler_view_layout)
imageId = arrayOf(
R.drawable.brake,
R.drawable.brake,
)
tutorialHeading = arrayOf(
getString(R.string.scheibenbremse_lüften_heading),
getString(R.string.felgenbremse_richten_heading),
)
tutorialText = arrayOf(
getString(R.string.scheibenbremse_lüften_text),
getString(R.string.felgenbremse_richten_text),
)
url = arrayOf(
getString(R.string.url_a),
getString(R.string.url_b),
)
newRecylerview =findViewById(R.id.recyclerView)
newRecylerview.layoutManager = LinearLayoutManager(this)
newRecylerview.setHasFixedSize(true)
newArrayList = arrayListOf<RecyclerViewDataClass>()
tempArrayList = arrayListOf<RecyclerViewDataClass>()
getUserdata()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_item,menu)
val item = menu?.findItem(R.id.search_action)
val searchView = item?.actionView as SearchView
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener{
override fun onQueryTextSubmit(query: String?): Boolean {
TODO("Not yet implemented")
}
override fun onQueryTextChange(newText: String?): Boolean {
tempArrayList.clear()
val searchText = newText!!.toLowerCase(Locale.getDefault())
if (searchText.isNotEmpty()){
newArrayList.forEach {
if (it.heading.toLowerCase(Locale.getDefault()).contains(searchText)){
tempArrayList.add(it)
}
}
newRecylerview.adapter!!.notifyDataSetChanged()
}else{
tempArrayList.clear()
tempArrayList.addAll(newArrayList)
newRecylerview.adapter!!.notifyDataSetChanged()
}
return false
}
})
return super.onCreateOptionsMenu(menu)
}
private fun getUserdata() {
for(i in imageId.indices){
val news = RecyclerViewDataClass(imageId[i],tutorialHeading[i],url[i])
newArrayList.add(news)
}
tempArrayList.addAll(newArrayList)
val adapter = RecyclerViewAdapter(tempArrayList)
newRecylerview.adapter = adapter
adapter.setOnItemClickListener(object : RecyclerViewAdapter.onItemClickListener{
override fun onItemClick(position: Int) {
val intent = Intent(this#RecyclerViewLayout,TutorialsActivity::class.java)
intent.putExtra("tutorialHeading",newArrayList[position].heading)
intent.putExtra("imageId",newArrayList[position].titleImage)
intent.putExtra("url",newArrayList[position].url)
intent.putExtra("tutorialText",tutorialText[position])
startActivity(intent)
}
})
}}
RecyclerViewAdapter.kt
class RecyclerViewAdapter(private val newsList : ArrayList<RecyclerViewDataClass>) : RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder>(),
Filterable {
private lateinit var mListener : onItemClickListener
interface onItemClickListener{
fun onItemClick(position : Int)
}
fun setOnItemClickListener(listener: onItemClickListener){
mListener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.list_item,
parent,false)
return MyViewHolder(itemView,mListener)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem = newsList[position]
holder.titleImage.setImageResource(currentItem.titleImage)
holder.tvHeading.text = currentItem.heading
}
override fun getItemCount(): Int {
return newsList.size
}
class MyViewHolder(itemView : View, listener: onItemClickListener) : RecyclerView.ViewHolder(itemView){
val titleImage : ShapeableImageView = itemView.findViewById(R.id.title_image)
val tvHeading : TextView = itemView.findViewById(R.id.tvHeading)
init {
itemView.setOnClickListener {
listener.onItemClick(adapterPosition)
}
}
}
override fun getFilter(): Filter {
TODO("Not yet implemented")
}}
RecyclerViewDataClass.kt
data class RecyclerViewDataClass(var titleImage: Int, var heading: String, val url: String)
**Tutorials Activity**
class TutorialsActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_tutorials)
val headingNews : TextView = findViewById(R.id.heading)
val mainNews : TextView = findViewById(R.id.news)
val imageNews : ImageView = findViewById(R.id.image_heading)
val bundle : Bundle?= intent.extras
val tutorialHeading = bundle!!.getString("tutorialHeading")
val imageId = bundle.getInt("imageId")
val tutorialText = bundle.getString("tutorialText")
val url = bundle.getString("url")
headingNews.text = tutorialHeading
mainNews.text = tutorialText
imageNews.setImageResource(imageId)
imageNews.setOnClickListener {
val openURL = Intent(Intent.ACTION_VIEW)
openURL.data = Uri.parse(url.toString())
startActivity(openURL)
}
}}
I believe you can pass data about which button is clicked using intents. Here's a link about that:
How to Pass custom object via intent in kotlin
For example, you can pass "A" if button A is clicked and "B" if button B is clicked, and then get that string in RecyclerViewLayout.kt to determine which elements should be shown.
According to me the simplest solution for doing this is you should have a boolean in preferences you can set preferences according to the button clicked and set data in your adapter to by getting the preferences value.
If you want to set data according to the button clicked
Other way is to pass the action onClick while starting a new Activity and getAction() in your second Activity.
This way you can also set data of your recyclerView by passing different data

SCREEN_ON and SCREEN_OFF broadcast not getting which are sent from PowerManager.WakeLock

I am trying to do some work when my screen goes off. The screen on and off function is related to the proximity sensor, but this method is not working for some samsung devices, I am currently using PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK. With this I'm able to turn the screen on and off with proximity behaviour but the problem is I'm not receiving any broadcast for screenn_on and screen_off so that I can start and stop some background work.
here's My Activity
private lateinit var sensorText : TextView
private lateinit var accuText : TextView
private lateinit var lightBtn : TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.sensor_test)
sensorText = findViewById(R.id.sensorInfo)
accuText = findViewById(R.id.accuracyInfo)
lightBtn = findViewById(R.id.lightBtn)
val proxMgr = ProximityMgr(this)
proxMgr.acquire()
val receiver = object : BroadcastReceiver() {
override fun onReceive(p0: Context?, p1: Intent?) {
MediaPlayer.create(this#SensorTestAct, R.raw.btnclick).start()
// do required task here
}
}
val iFilter = IntentFilter().apply {
addAction(Intent.ACTION_SCREEN_ON)
addAction(Intent.ACTION_SCREEN_OFF)
}
registerReceiver(receiver, iFilter)
}
#SuppressLint("InvalidWakeLockTag")
class ProximityMgr(context: Context) {
private val powerManager: PowerManager = (context.getSystemService(POWER_SERVICE) as PowerManager?)!!
private val wakeLock: PowerManager.WakeLock
init {
wakeLock = powerManager.newWakeLock(
PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,
"proximity")
}
fun acquire() {
if (powerManager.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {
if (wakeLock.isHeld) {
wakeLock.release()
}
wakeLock.acquire(WAKE_LOCK_TIMEOUT_MS)
} else {
Log.w(TAG, "not supported")
}
}
fun release() {
if (wakeLock.isHeld)
wakeLock.release()
}
companion object {
private const val TAG = "ProximitySensor"
private const val WAKE_LOCK_TIMEOUT_MS: Long = 2 * 3600 * 1000
}
}
}```
If you suggest me any alternate method then it will be very helpful

Kotlin] I want to send some data from One class to Other class by using Intent

I just want to say sorry to my English skill
I've studied the Android Studio and Kotlin these days.
but I'd got a problem on RecyclerViewer and Adapter, for Intent method
work flow chart
this image, this is what i want to do
so i coded the three classes
ShoppingAppActivity.kt, MyAdapter.kt, CartActivity.kt
At ShoppingAppActivity, If I click the itemId ( in the Red box texts)
I make it move to other context(CartActivity)
ShoppingAppActivity working
if i clicked the red box then
cartStatus
go to cart Activity
it worked but already I said, I just want to send only send itemID
covert to String (i will use toString())
SO i tried to use Intent method in ShoppingAppActivity.kt
///PROBLEM PART
adapter?.setOnItemClickListener{
val nextIntent = Intent(this, CartActivity::class.java)
//nextIntent.putExtra("itemID", )
startActivity(nextIntent)
}
///PROBLEM PART
like this but the problem is I don't know what am i have to put the parameter in
nextIntent.putExtra("itemID", )
what should i do?
I think, I should fix MyAdaptor.kt or ShopingAppActivity.kt for this problem.
But in my knowledge, this is my limit. :-(
below
Full Codes of ShoppingAppActivity.kt, MyAdapter.kt, CartActivity.kt
ShoppingAppActivity.kt
class ShoppingAppActivity : AppCompatActivity() {
lateinit var binding: ActivityShoppingAppBinding
private var adapter: MyAdapter? = null
private val db : FirebaseFirestore = Firebase.firestore
private val itemsCollectionRef = db.collection("items")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityShoppingAppBinding.inflate(layoutInflater)
setContentView(binding.root)
updateList()
binding.recyclerViewItems.layoutManager = LinearLayoutManager(this)
adapter = MyAdapter(this, emptyList())
binding.recyclerViewItems.adapter = adapter
///PROBLEM PART
adapter?.setOnItemClickListener{
val nextIntent = Intent(this, CartActivity::class.java)
//nextIntent.putExtra("itemID", )
startActivity(nextIntent)
}
///PROBLEM PART
}
private fun updateList() {
itemsCollectionRef.get().addOnSuccessListener {
val items = mutableListOf<Item>()
for (doc in it) {
items.add(Item(doc))
}
adapter?.updateList(items)
}
}
}
MyAdapter.kt
data class Item(val id: String, val name: String, val price: Int, val cart: Boolean) {
constructor(doc: QueryDocumentSnapshot) :
this(doc.id, doc["name"].toString(), doc["price"].toString().toIntOrNull() ?: 0, doc["cart"].toString().toBoolean() ?: false)
constructor(key: String, map: Map<*, *>) :
this(key, map["name"].toString(), map["price"].toString().toIntOrNull() ?: 0, map["cart"].toString().toBoolean() ?: false)
}
class MyViewHolder(val binding: ItemBinding) : RecyclerView.ViewHolder(binding.root)
class MyAdapter(private val context: Context, private var items: List<Item>)
: RecyclerView.Adapter<MyViewHolder>() {
fun interface OnItemClickListener {
fun onItemClick(student_id: String)
}
private var itemClickListener: OnItemClickListener? = null
fun setOnItemClickListener(listener: OnItemClickListener) {
itemClickListener = listener
}
fun updateList(newList: List<Item>) {
items = newList
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val inflater = LayoutInflater.from(parent.context)
val binding: ItemBinding = ItemBinding.inflate(inflater, parent, false)
return MyViewHolder(binding)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val item = items[position]
val itemID : String
holder.binding.textID.text = item.id
holder.binding.textName.text = item.name
if(item.cart)
{
holder.binding.textCart.text = "in Cart"
}
else
{
holder.binding.textCart.text = ""
}
holder.binding.textID.setOnClickListener {
AlertDialog.Builder(context).setMessage("You clicked ${item.id}.").show()
itemClickListener?.onItemClick(item.id)
}
holder.binding.textName.setOnClickListener {
//AlertDialog.Builder(context).setMessage("You clicked ${student.name}.").show()
itemClickListener?.onItemClick(item.id)
}
//return item.id.toString()
}
override fun getItemCount() = items.size
}
CartActivity.kt
class CartActivity : AppCompatActivity() {
lateinit var binding: ActivityCartBinding
private val db: FirebaseFirestore = Firebase.firestore
private val itemsCollectionRef = db.collection("items")
private var adapter: MyAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityCartBinding.inflate(layoutInflater)
setContentView(binding.root)
updateList()
//binding.recyclerViewItems.layoutManager = LinearLayoutManager(this)
//adapter = MyAdapter(this, emptyList())
//binding.recyclerViewItems.adapter = adapter
binding.changeCartStatus.setOnClickListener{
//change the button's text if the itemID is corrected
//if(){
// binding.changeCartStatus.text = ""
//}
}
}
private fun updateList() {
itemsCollectionRef.get().addOnSuccessListener {
val items = mutableListOf<Item>()
for (doc in it) {
items.add(Item(doc))
}
adapter?.updateList(items)
}
}
}
You just need to implement listener to your activity
class ShoppingAppActivity : AppCompatActivity() ,MyAdapter.OnItemClickListener {
In oncreate add below line after adapter
adapter?.setOnItemClickListener(this)
Then override its method
override fun onItemClick(id: String){
val nextIntent = Intent(this, CartActivity::class.java)
nextIntent.putExtra("itemID",id )
startActivity(nextIntent)
}

Bluetooth Classic scan not showing devices

Im implementing a simple blutooth classic scan from the official docs on my Redmi Note 4 (Bluetooth 4.1).
However I am not seeing a toast that should appear when the onReceive function on the broadcast receiver is called.
What could be wrong here?
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
defaultAdapter = BluetoothAdapter.getDefaultAdapter()
if (defaultAdapter == null) {
toast("no adapter")
return
}
if (!defaultAdapter!!.isEnabled) {
val enableBluetoothIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
startActivityForResult(enableBluetoothIntent, REQUEST_ENABLE_BLUETOOTH)
}
searchButton.setOnClickListener { newDevicesList() }
val filter = IntentFilter(BluetoothDevice.ACTION_FOUND)
Log.i("receiver", "registering receiver")
registerReceiver(receiver, filter)
}
private val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
toast("maybe i find new device who know")
when (intent.action) {
BluetoothDevice.ACTION_FOUND -> {
// Discovery has found a device. Get the BluetoothDevice
// object and its info from the Intent.
val device: BluetoothDevice? =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
val deviceName = device?.name
val deviceHardwareAddress = device?.address // MAC address
toast("device $deviceName was found")
}
BluetoothAdapter.ACTION_DISCOVERY_FINISHED -> {
context.unregisterReceiver(this)
}
}
if (defaultAdapter!!.isDiscovering) {
toast("scan already in progress")
} else {
toast("starting discovery")
defaultAdapter!!.startDiscovery();
}
}
How do i know that the onReceive function never gets called? cause this toast toast("maybe i find new device who know") never appears.

Categories

Resources