What do I use now that BootstrapNotifier interface is deprecated in IBEACON?
Ibeacon deprecated : 1) RegionBootstrap 2) BootstrapNotifier 3)
BackgroundPowerSaver
is there any alternate solution or reference link?
I shared my full code
import android.annotation.SuppressLint
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationCompat
import org.altbeacon.beacon.BeaconManager
import org.altbeacon.beacon.Region
import org.altbeacon.beacon.powersave.BackgroundPowerSaver
import org.altbeacon.beacon.startup.BootstrapNotifier
import org.altbeacon.beacon.startup.RegionBootstrap
class MainActivity2 : AppCompatActivity(), BootstrapNotifier {
private var regionBootstrap: RegionBootstrap? = null
private var backgroundPowerSaver: BackgroundPowerSaver? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// showNotification(this,"found beacon init")
//enable beacon features///////////////////////////////////////////////////////////////////////
val beaconManager: BeaconManager = BeaconManager.getInstanceForApplication(this)
beaconManager.beaconParsers.clear()
beaconManager.beaconParsers
.add(org.altbeacon.beacon.BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"))
beaconManager.setEnableScheduledScanJobs(false) // disable JobScheduler-based scans (used on Android 8+)
beaconManager.backgroundBetweenScanPeriod = 0 // set the time between each scan to be 1 hour (3600 seconds)
beaconManager.backgroundScanPeriod = 1100 // set the duration of the scan to be 1.1 seconds
val region = Region("backgroundRegion", null, null, null)
regionBootstrap = RegionBootstrap(this, region) // wake up the app when a beacon is seen
backgroundPowerSaver = BackgroundPowerSaver(this) //This reduces bluetooth power usage by about 60%
//////////////////////////////////////////////////////////////////////////////////////////////
}
override fun didEnterRegion(arg0: Region?) {
Log.d("mybeacon", "i found a enter")
showNotification(this,"found beacon enter")
}
override fun didExitRegion(region: Region?) {
Log.d("mybeacon", "i found a exit")
showNotification(this,"found beacon exit")
}
override fun didDetermineStateForRegion(state: Int, region: Region?) {}
//............................................................
fun showNotification(context: Context, message: String?) {
}
}
implementation :
implementation 'org.altbeacon:android-beacon-library:2.19.3'
Library version 2.19+ introduces autowind APIs that make setting up beacon scanning much simpler, more intuitive and less prone to configuration errors.
In earlier versions of the library, auto-launch of an app on beacon detection was handled by the RegionBootstrap utility class, but as of 2.19 it is no longer necessary -- you simply start monitoring with startMonitoring(region). The library sample code shows an example of how to start up auto-launch section of the code samples
To start up beacon scanning in the background simply replace regionBootstrap = RegionBootstrap(this, region) with this:
beaconManager.addMonitorNotifier(this)
beaconManager.startMonitoring(region)
Instead of the BootstrapNotifier interface, your class should implement MonitorNotifier.
While it is unrelated to the autobind API changes in 2.19, be aware that if you want the library to automatically launch your app on beacon detection, you must implement the above code in the onCreate method of a custom Android Application class and not an Activity as shown in the question. If you don't care about auto launch, then doing this in an Activity class is fine.
Related
I'm creating a native module in react native.
his role is to connect to something and listen to data from this thing.
But.. I don't know how to observe my liveData property.
I can't use observeForever because I cannot use it in the background thread. and can't use it with reactContext looper.
I can't use it either with livedata.observe(owner) because my nativeModule don't have lifeCycleOwner. And if I create mine, I got the following error: Method handleLifeCycleEvent must be called on the main thread
I tried everything I can and I didn't find any tutorial about what I want. Everyone use sendEvent when a and I didn't find any tutorial is called but never in background. the official documentation doesn't give enought information too...
here my module:
package com.my.module
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.WritableMap
import com.facebook.react.bridge.Arguments
import com.facebook.react.modules.core.DeviceEventManagerModule
import com.someone.extsdk
class MyModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
override fun getName() = "MyModule"
#ReactMethod fun connect(id: String, promise: Promise) {
extsdk.connect(
onSuccess = { promise.resolve(null) },
onError = { e -> promise.reject("connect", e.toString())}
)
}
#ReactMethod fun disconnect() {
extsdk.disconnect()
}
#ReactMethod fun addListener(eventName: String) {
// How can I listen to extsdk.liveData?
}
#ReactMethod fun removeListeners(count: Int) {
// How can I remove listener?
}
private fun sendEvent(reactContext: ReactContext, eventName: String, params: WritableMap?) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit(eventName, params)
}
}
Can anyone please help. Am a noob to Android studio. My first major app, is a streaming media player. Problem, i wish to use foreground service, but i just cannot understand how to implement foreground service. I tried searching youtube, but not much on kotlin, and the same with the sites. Can anyone please give me a step by step guide for this.
This is my MainActivity below. The app is working, just missing the foreground service.
package com.example.al_bunyan
import android.app.Dialog
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.AnimationDrawable
import android.media.MediaPlayer
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.VideoView
import java.time.Instant
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var web_btn = findViewById<Button>(R.id.link_btn)
web_btn.setOnClickListener {
var intent = Intent(this#MainActivity, AlbunyaWebview::class.java)
startActivity(intent)
}
}
fun video_check(view:View) {
val fm105 = findViewById<Button>(R.id.fm105_7)
val alert = Dialog(this#MainActivity)
alert.setContentView(R.layout.audio_play)
val video = alert.findViewById<VideoView>(R.id.video_alert)
val play = alert.findViewById<Button>(R.id.play)
val pause = alert.findViewById<Button>(R.id.pause)
val resume = alert.findViewById<Button>(R.id.resume)
if (fm105.isPressed) {
val video_1 = Uri.parse("http://albunyan.fm:8000/live")
video.setVideoURI(video_1)
alert.show()
play.setOnClickListener {
video.start()
}
pause.setOnClickListener {
video.pause()
}
resume.setOnClickListener {
video.start()
}
}
}
}
There are many resources available including code examples.
following are some of them
Android developer docs Services
Android developer docs Foreground services
Sample Android project on github LocationUpdatesForegroundService
I suggest first you read some theory from the first two resources and then try to learn from the code in the github project, which clearly shows how you can implement foreground service.
Our app needs to prevent users to record our screen for some important reasons. How to prevent screen-record on iOS and android?
It seems that we can get a call-back if users are recording the screen after iOS 11. Is there any method to use that call-back to realize screen-record preventing?
That is something which is not completely possible. There are 2 scenarios for Android OS
1 - When Android device is not rooted - You can use flag FLAG_SECURE which will prevent screenshot and video recording. You can read further here https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_SECURE
2 - When Android device is rooted - You can have a check programatically to know if device is rooted or not. If it is rooted then you can stop your application from running further. Here is the link to check for root device - Determining if an Android device is rooted programmatically?
Put this code in your MainActivity.kt and You're done :)
(The code isn't mine, I found it on Github)
import io.flutter.embedding.android.FlutterActivity
import android.os.Build
import android.view.ViewTreeObserver
import android.app.ActivityManager
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.os.Bundle
import android.util.Log
import android.view.SurfaceView
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.view.WindowManager.LayoutParams
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val flutter_native_splash = true
var originalStatusBarColor = 0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
originalStatusBarColor = window.statusBarColor
window.statusBarColor = 0xffeaeaea.toInt()
}
val originalStatusBarColorFinal = originalStatusBarColor
if (!setSecureSurfaceView()) {
Log.e("MainActivity", "Could not secure the MainActivity!")
// React as appropriate.
}
getWindow().addFlags(LayoutParams.FLAG_SECURE)
getWindow().setFlags(LayoutParams.FLAG_SECURE,
LayoutParams.FLAG_SECURE)
SurfaceView(applicationContext).setSecure(true)
}
private fun setSecureSurfaceView(): Boolean {
val content = findViewById<ViewGroup>(android.R.id.content)
if (!isNonEmptyContainer(content)) {
return false
}
val splashView = content.getChildAt(0)
if (!isNonEmptyContainer(splashView)) {
return false
}
val flutterView = (splashView as ViewGroup).getChildAt(0)
if (!isNonEmptyContainer(flutterView)) {
return false
}
val surfaceView = (flutterView as ViewGroup).getChildAt(0)
if (surfaceView !is SurfaceView) {
return false
}
surfaceView.setSecure(true)
this.window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
return true
}
private fun isNonEmptyContainer(view: View): Boolean {
if (view !is ViewGroup) {
return false
}
if (view.childCount < 1) {
return false
}
return true
}
}
You can use the flutter_windowmanager plugin. Once you have added to your pubspec.yaml file then import it where you want to disable screenshot. Using
import 'package:flutter_windowmanager/flutter_windowmanager.dart';
Now add this line into your Stateful Widget.
Future<void> disableScreenShot() async {
await FlutterWindowManager.addFlags(FlutterWindowManager.FLAG_SECURE);
}
#override
void initState() {
disableScreenShot();
super.initState();
}
Now Normal Users can't take screenshots.
I want to try out work manager for the first time. I am used to rxJava so I decided to implement my work manager using RxWorker. But the testing aspect is giving me headache.Basically, the work manager checks firebase to get latest changes to latest changes to particular document (This is not the best use case I know).But the problem is in the test returns without waiting for success or failure.It returns when the work manager is still running.
This is my work manager implementation
class MidiSyncWorker(context: Context, params: WorkerParameters) : RxWorker(context, params) {
override fun createWork(): Single<Result> {
return Injection.provideSharePrefsRepo.midiArchiveVersion()
.flatMapObservable { currentVersion ->
Injection.provideOnlineRepo.latestMidiArchive()
.filter { onlineMidi -> onlineMidi.version > currentVersion }
}.firstOrError()
.map { onlineMidi ->
val outputData = Data.Builder()
.putString(KEY_FIREBASE_ARCHIVE_PATH, onlineMidi.url)
Result.success(outputData.build()) }
}
.onErrorReturn { Result.failure() }
}
This is my test
fun midiSyncVersionCheck_success_onlineVersionDiffersFromLocalVersion() {
// create request
val request = OneTimeWorkRequestBuilder<MidiSyncWorker>()
.build()
wmRule.workManager.enqueue(request).result.get()
val workInfo = wmRule.workManager.getWorkInfoById(request.id).get(10, TimeUnit.SECONDS)
assertThat(workInfo.state, `is`(WorkInfo.State.SUCCEEDED))
}
I expected the test to wait until workmanager returns success or failure. But it returns while work manager is still running
java.lang.AssertionError:
Expected: is <SUCCEEDED>
but: was <RUNNING>
WorkManager makes available a couple of ways to test your Worker classes. You can find all the details on WorkManager Testing documentation page.
The original WorkManagerTestInitHelper only supports Worker classes, meanwhile, the newly introduce in (WorkManager v2.1.0-alpha01) TestListenableWorkerBuilder can be used to test both ListenableWorker classes and the other classes that derives from it (like CoroutineWorker and RxWorker.
In your particular case, you should be able to do:
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.work.ListenableWorker.Result
import androidx.work.testing.TestListenableWorkerBuilder
import org.hamcrest.CoreMatchers.`is`
import org.junit.Assert.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
#RunWith(JUnit4::class)
class MyWorkTest {
private lateinit var context: Context
#Before
fun setup() {
context = ApplicationProvider.getApplicationContext()
}
#Test
fun testMidiSyncWorker() {
// Get the ListenableWorker
val worker = TestListenableWorkerBuilder<MidiSyncWorker>(context).build()
// Start the work synchronously
val result = worker.startWork().get()
assertThat(result, `is`(Result.success()))
}
}
In this way you're calling synchrously your worker class.
In this case you need to use the as a test dependency in your build.gradle file:
def work_version = "2.1.0-alpha02"
androidTestImplementation "androidx.work:work-testing:$work_version"
You can find a similar, complete, sample (for a CoroutineWorker), on the Kotlin's coroutine Codelab.
I would be glad if anyone could help me with an Android app that i am trying to make .
Actually , there is a module in the app which counts how many time i used different service like gps ,wifi , camera etc.
So i am stuck with camera feature , how to record the usage of camera by 3rd party applications like whatsapp , instagram etc . I tried broadcast receiver on gallery , content observer on mediastore , and file manager also .
So how to do it ?
You can use the Accessibility Service to detect every time that the camera is in use.
Remember to add the permission:
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
import android.app.Activity
import android.content.Context
import android.hardware.camera2.CameraManager
import android.hardware.camera2.CameraManager.AvailabilityCallback
import android.os.Handler
class YourClassActivity : Activity() {
private lateinit var callback: AvailabilityCallback
private lateinit var manager: CameraManager
public override fun onResume() {
super.onResume()
manager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
callback = object : AvailabilityCallback() {
override fun onCameraAvailable(cameraId: String) {
super.onCameraAvailable(cameraId)
//Do something
}
override fun onCameraUnavailable(cameraId: String) {
super.onCameraUnavailable(cameraId)
//The camera is not available
}
}
manager.registerAvailabilityCallback(callback, Handler())
}
public override fun onPause() {
//Unsubscribe listener
manager.unregisterAvailabilityCallback(callback)
super.onPause()
}
}