Running CameraX in a service in Android Studio with Kotlin - android

i want to create a class in Android Studio using Kotlin that runs Camera in background
class MyForegroundService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val notification = createNotification()
startForeground(1, notification)
// **************** I want to add camerax here *****************************
return START_STICKY
}
}
to run the camera in background can you help me please

Do you want to develop any ForegroundService for android?
Some answers already have been made on the Use of camera as ForegroundService. You can check the links below.
Camera frames in a service / background process
Grafika, a dumping ground for Android graphics & media hacks.

Related

Capability Info, Health Service, and Ambient Mode

I'm trying to write a fitness companion watch app that would collect heart rate, and calories via HealthServices API, and send them to the device, where we display a workout. I've been following suggested examples:
https://github.com/android/wear-os-samples/tree/main/AlwaysOnKotlin, https://github.com/android/health-samples/tree/2220ea6611770b56350d26502faefc28791f3cbd/health-services/ExerciseSample, and https://github.com/googlecodelabs/ongoing-activity .
I'm trying to achieve the following workflow:
Launch app on Wear device when X happens on the phone
Start exercise client on Wear
Send heart rate/calories update on a regular basis back to phone
Show summary screen, and stop exercise client when Y happens on the phone.
All of these work somewhat well until the watch goes into ambient mode. Then I run into the following problems:
When watch is in ambient mode, the capabilities client on the phone cannot locate watch, and tell it to start exercise. Nor can it tell it to stop exercise. What is a suggested workaround for this?
I use message client on phone to send message to the wearable. But nothing happens here, since the current node is empty.
currentNode?.also { nodeId ->
val sendTask: Task<*>? =
messageClient
?.sendMessage(nodeId, WORKOUT_STATUS_MESSAGE_PATH, "START.toByteArray())
When trying to simulate ambient mode by pressing 'hand' on the watch simulator, the ambient mode listener does not actually trigger to tell me the right thing. The screen gets "stuck" instead of updating to what I want it to.
Code for the ambient mode in MainActivity (I'm still learning Compose, so right now Main activity is where it's at, to eliminate other Compose specific errors):
In Manifest:
<uses-permission android:name="android.permission.WAKE_LOCK" />
In Main Activity:
class MainActivity : FragmentActivity(), AmbientModeSupport.AmbientCallbackProvider {
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ambientController = AmbientModeSupport.attach(this)
setContent {
val ambientEvent by mainViewModel.ambientEventFlow.collectAsState()
StatsScreen(ambientEvent)
}
...
}
override fun getAmbientCallback(): AmbientModeSupport.AmbientCallback = AmbientModeCallback()
inner class AmbientModeCallback : AmbientModeSupport.AmbientCallback() {
override fun onEnterAmbient(ambientDetails: Bundle) {
Timber.e("ambient event: enter: $ambientDetails")
mainViewModel.sendAmbientEvent(AmbientEvent.Enter(ambientDetails))
}
override fun onExitAmbient() {
Timber.e("ambient event: exit")
mainViewModel.sendAmbientEvent(AmbientEvent.Exit)
}
override fun onUpdateAmbient() {
Timber.e("ambient event: update")
mainViewModel.sendAmbientEvent(AmbientEvent.Update)
}
}
I don't see anything printed in this callback, and then consequently, by StateScreen doesn't really do anything when the device enters in the ambient mode.

Sending React Native Android Events to JavaScript from a Service

I am trying to emit an event using DeviceEventManagerModule.RCTDeviceEventEmitter in React Native, but because I wish to call it from a Service, I don't know how to get the reactContext. My code looks like this:
class TimerService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val reactContext = ???
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("tick", "tock");
}
}
If the essence of what I am trying to do is wrong I'm happy to change anything and everything.
For more context, what I'm trying to do is keep track of rest timers in-between sets at the gym. Full code can be found here. I wanted to add a page to display the currently running rest timer, where the state is being stored in TimerService.
I tried to cast applicationContext to ReactContext like:
(applicationContext as ReactApplicationContext)
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("tick", "tock");
But was given an error saying I can't cast ApplicationContext to ReactApplicationContext. I also tried to figure out how I could pass reactApplicationContext down to my Service, but got a bit stumped on trying to parcel it for an Intent.

How To Record Calls In Android Devices Using Kotlin?

I want to make an Android application that can record both incoming and outgoing calls in the background as a service in kotlin and at a particular time in the day, it sends all that recordings to a server by API. I had researched about it all I found is to use Device Policy Manager and Telephoney Manager but it is not much about it on the internet. So can you help me with any article, documentation, or tutorial?
There is no solution from Google as of now. Google has deprecated the feature of recording the calls in it's latest versions of Android OS. Earlier it was possible, I had tried various methods but I was only getting the silent audio when I had tried to record calls. When using Google's Phone application it only allows that application to use the microphone and other things it won't allow any other application to overpower and get that hardware access.
But there are actually two hacks to do that.
Build your own phone application like Truecaller and manage every call and other things from that application by doing this you can get access to managing calls on your device and you will also get the access to record the calls.
If your work is specific to any one mobile example like Samsung, OnePlus, etc. Then you can use any Truecaller or Google's Phone application which will store the recordings of the calls in file storage and then you can make a service to upload that call recording from that particular file location every night at 12 AM or something.
first create MyCallRecordReceiver class
class MyCallRecordReceiver(callRecord: CallRecord) : CallRecordReceiver(callRecord) {
override fun onIncomingCallReceived(context: Context, number: String?, start: Date) {
super.onIncomingCallReceived(context, number, start)
}
}
then in MainActivity
class MainActivity : AppCompatActivity() {
companion object {
private val TAG = MainActivity::class.java.simpleName
}
private lateinit var callRecord: CallRecord
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
callRecord = CallRecord.Builder(this)
.setLogEnable(true)
.setRecordFileName("CallRecorderTestFile")
.setRecordDirName("CallRecorderTest")
.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION)
.setShowSeed(true)
.build()
}
fun StartCallRecordClick(view: View) {
LogUtils.i(TAG, "StartCallRecordClick")
callRecord.startCallReceiver()
}
fun StopCallRecordClick(view: View) {
LogUtils.i(TAG, "StopCallRecordClick")
callRecord.stopCallReceiver()
}
}
In addition Add it as a dependency in your app's build.gradle file
allprojects {
repositories {
maven { url 'https://jitpack.io' }
}
}
and this
compile 'com.github.aykuttasil:CallRecorder:1.5.3'

Start a FlutterActivity subclass using a cached engine

I'm currently adding a view developed using Flutter to an existing Android app. I have been following the tutorials found in the Flutter website and decided to used a cached engine in order to minimize the delay that users may experience when navigating to the Flutter portion of the app. In order to do so, you must launch your Flutter activity like
startActivity(
FlutterActivity
.withCachedEngine("my_engine_id")
.build(this) // this is a Context
)
After a while I need to wirte a method channel to communicate from the Flutter portion of the app back to the Android host app, so I followed the instructions found in another of Flutter's tutorials, where it is shown that the activity that implements the channel must extend FlutterActivity.
So my problem is that I'm not sure how to initialize this activity using a cached engine, since I obviously can't use FlutterActivity.withCachedEngine anymore. Has anyone solved this already?
After looking at FlutterActivity documentation I found the provideFlutterEngine method. The doc description clearly states that:
This hook is where a cached FlutterEngine should be provided, if a cached FlutterEngine is desired.
So the final implementation of my class looks like this now
class MyActivity : FlutterActivity() {
override fun provideFlutterEngine(context: Context): FlutterEngine? =
FlutterEngineCache.getInstance().get(FlutterConstants.ENGINE_ID)
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "my-channel")
.setMethodCallHandler { call, result ->
if (call.method == "my-method") {
myMethod()
result.success(null)
} else {
result.notImplemented()
}
}
}
private fun myMethod() {
// Do native stuff
}
}
And I simply start it writing startActivity(Intent(this, MyActivity::class.java))

Android altbeacon ranging in intervals when app in background

I'm working on an app that runs a background service to range bluetooth beacons in intervals.
I start a ForegroundService with a timer to start ranging beacons for 10 seconds every minute, with an interval of 200 millis, calculates the strongest beacon and submits it to the backend API.
This works neatly while the app is in foreground, and, when the screen is off, as long as i'm hooked up using adb logcat. As soon as I take it off, nothing gets submitted to the servers anymore, meaning that no beacons are being ranged anymore.
Here are the relevant code pieces, I hope I didn't simplify too much:
class BeaconService : Service(), BeaconConsumer {
private var beaconManager: BeaconManager? = null
private var rangingTimer = Timer("rangingTimer", true)
private val region = Region("com.beacon.test", Identifier.parse("f7826da6-4fa2-4e98-8024-bc5b71e0893e"), null, null)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return Service.START_STICKY
}
override fun onCreate() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationManager = MyNotificationManager.getInstance()
val notification = notificationManager.buildBeaconServiceNotification(this, "iBeacon service", null)
startForeground(NOTIFICATION_ID, notification)
}
initBeaconManager()
}
private fun initBeaconManager() {
BeaconManager.setDebug(true)
beaconManager = BeaconManager.getInstanceForApplication(this)
beaconManager?.foregroundScanPeriod = 200L
beaconManager?.beaconParsers?.add(BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"))
beaconManager?.bind(this)
}
override fun onBeaconServiceConnect() {
beaconManager?.addRangeNotifier { beacons, _ ->
if (beacons.isNotEmpty()) {
//code add ranged beacons to list
}
}
startRanging()
}
private fun startRanging() {
//code to reset the list of ranged beacons
beaconManager?.startRangingBeaconsInRegion(region)
rangingTimer.schedule(10000L) {
stopRanging(50000L)
}
}
private fun stopRanging(restartRangingAfter: Long? = null) {
beaconManager?.stopRangingBeaconsInRegion(region)
//code calcuate the strongest beacon and submit to server
if (restartRangingAfter != null) {
rangingTimer.schedule(restartRangingAfter) {
startRanging()
}
}
}
}
On OS Versions 8+, Android limits background processing unless it is part of a foreground service or a job initiated by the JobScheduler. As a result of this limitation, the Android Beacon Library will by default use the JobScheduler on Android 8+. In the foreground, an "immediate" ScanJob will run constantly to do scans. In the background (meaning when no activities are visible with the screen unlocked), Android does not allow this. A job may be scheduled at most once every ~15 minutes. This is why you see scans stop.
It does not matter that you have your own foreground service. Android still enforces these limits on any background processing performed outside that foreground service.
Two alternatives:
Live with the job limitations (scan once every 15 minutes). Use BackgroundPowerSaver to auto switch between foreground/background mode and set beaconManager.setBackgroundScanPeriod(5000) (for a 5 second scan every 15 minutes.) For clarity, you should also set beaconManager.setBackgroundBetweenScanPeriod(15*60*1000) (15 minutes), although you can set a lower value that will be disallowed by the OS on Android 8+.
Set up the library to scan with its own Foreground Service (yes as second foreground service) as described here. You can then stop using your own foreground service, or keep it. If you keep it, you will see two notification icons about the two foreground services running. It is possible to combine those two notifications if you want to keep two foreground services and show just one notification.

Categories

Resources