I am making an SOS application that, when pressing the power button three times, should make a call to a pre-defined number and send an SOS message to the specified numbers, the problem is that it sees that the power button is pressed and sends a message but does not make a call over the lock.
MyReceiver:
class MyReceiver(activity: Activity?) : BroadcastReceiver() {
private var activity: Activity? = null
var t1 = System.currentTimeMillis()
var t2 = System.currentTimeMillis()
var thread: Thread? = null
override fun onReceive(context: Context, intent: Intent) {
Log.v("onReceive", "Power button is pressed.")
val a = countPowerOff + 1
if (intent.action == Intent.ACTION_SCREEN_OFF) {
countPowerOff++
if (countPowerOff == 1) t1 = System.currentTimeMillis()
if (countPowerOff == 3) t2 = System.currentTimeMillis()
} else {
if (intent.action == Intent.ACTION_SCREEN_ON) {
if (countPowerOff == 3) {
Toast.makeText(context, "Clicked to call", Toast.LENGTH_LONG)
.show()
}
if (countPowerOff == 3 && t2 - t1 <= 5000) {
thread = Thread(Task())
thread!!.start()
}
if (countPowerOff == 3) {
countPowerOff = 0
}
}
}
}
internal inner class Task : Runnable {
override fun run() {
(activity as MainActivity).callFragmentMethod()
}
}
companion object {
var countPowerOff = 0
var starttime = 0
}
init {
this.activity = activity
}
}
Method for making a call and sending a message:
fun sendSos() {
val manager = context!!.getSystemService(Context.LOCATION_SERVICE) as LocationManager
if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
sosMassage =
"I need help, I'm at Latitude: ${currentLocation.latitude} and Longitude ${currentLocation.longitude} https://www.google.com/maps/search/?api=1&query=${currentLocation.latitude},${currentLocation.longitude}"
}
threadCall = Thread(callSOS())
threadCall!!.start()
threadMessage = Thread(sendSOS())
threadMessage!!.start()
}
internal inner class callSOS : Runnable {
override fun run() {
checkForCallSmsPermission()
val intent = Intent(Intent.ACTION_CALL)
val prefs = PreferenceManager.getDefaultSharedPreferences(requireContext())
val callPreferences = prefs.getString("call_preference", "1")
if (callPreferences == "1") {
intent.setData(Uri.parse("tel:103"))
} else {
intent.setData(Uri.parse("tel:${prefs.getString("contact_text_1", "103")}"))
}
startActivity(intent)
}
}
internal inner class sendSOS : Runnable {
override fun run() {
checkForSmsPermission()
val prefs = PreferenceManager.getDefaultSharedPreferences(requireContext())
val sms = SmsManager.getDefault()
val textPreferences = prefs.getString("text_preference", "1")
val primaryContact = prefs.getString("contact_text_1", "0701217070")
sms.sendTextMessage(
primaryContact,
null,
sosMassage,
null,
null
)
if (textPreferences == "2") {
for (i in 2..3) {
val contactNumber = prefs.getString("contact_text_$i", null)
if (contactNumber != null) {
sms.sendTextMessage(
contactNumber,
null,
sosMassage,
null,
null
)
}
}
}
}
}
Related
Android 12 Location updates not working when app is on background. and work fine when app is on forground.
I also "allow all time" permission for for location. Acc to docs after this location updates start work on background. but in my case it stop updates when app is on foreground.
locationUpdatePendingIntent
private val locationUpdatePendingIntent: PendingIntent by lazy {
val intent = Intent(context, LocationUpdatesBroadcastReceiver::class.java)
intent.action = LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES
PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_MUTABLE)
}
Firstly I use Location Request. inside Automatic Workmanager
val mLocationRequest = LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 0L)
.setWaitForAccurateLocation(false)
.build()
if (ActivityCompat.checkSelfPermission(
context.applicationContext,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
return Result.success();
}
fusedLocationProviderClient?.requestLocationUpdates(
mLocationRequest,
locationUpdatePendingIntent
)
then listen to location updates used inside Automatic Workmanager
override fun onLocationUpdate(location: Location) {
val executor: ExecutorService = Executors.newSingleThreadExecutor()
executor.execute {
lastLocation = location
updateLocation()
}
}
Location update broadcast (in this location update)
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.location.Location
import android.util.Log
import com.google.android.gms.location.LocationAvailability
import com.google.android.gms.location.LocationResult
class LocationUpdatesBroadcastReceiver: BroadcastReceiver() {
private val TAG = "LocationUpdatesBroadcas";
override fun onReceive(context: Context?, intent: Intent?) {
Log.d(TAG, "onReceive() context:$context, intent:$intent")
if (intent?.action == ACTION_PROCESS_UPDATES) {
// Checks for location availability changes.
LocationAvailability.extractLocationAvailability(intent)?.let { locationAvailability ->
if (!locationAvailability.isLocationAvailable) {
Log.d(TAG, "Location services are no longer available!")
}
}
LocationResult.extractResult(intent)?.let { locationResult ->
Log.e(TAG, "onReceive: lastLocation ${locationResult.locations.size}", )
if(locationResult.lastLocation != null){
ShareLocationToAutomaticWorker.INSTANCE?.reciveLocation(locationResult.lastLocation!!)
}
}
}
}
companion object {
const val ACTION_PROCESS_UPDATES =
"action." +
"PROCESS_UPDATES"
}
interface UpdatedLocation{
fun onLocationUpdate(location: Location)
}
}
class ShareLocationToAutomaticWorker(var updateLocation: LocationUpdatesBroadcastReceiver.UpdatedLocation){
private val TAG = "LocationUpdatesBroadcas"
fun reciveLocation( location:Location){
Log.e(TAG, "reciveLocation:--- ${location} " )
updateLocation.onLocationUpdate(location)
}
companion object {
var INSTANCE: ShareLocationToAutomaticWorker? = null
fun getInstance(updateLocation: LocationUpdatesBroadcastReceiver.UpdatedLocation): ShareLocationToAutomaticWorker {
return INSTANCE ?: synchronized(this) {
INSTANCE ?: ShareLocationToAutomaticWorker(
updateLocation )
.also { INSTANCE = it }
}
}
}
}
I fixed this issue by changing "AutomaticLocationWorker" to "AutomaticLocationBackgroundService:LifecycleService()" or change worker to lifecycleService.
private var fusedLocationProviderClient: FusedLocationProviderClient? = null
private val locationUpdatePendingIntent: PendingIntent by lazy {
val intent = Intent(this, LocationUpdatesBroadcastReceiver::class.java)
intent.action = LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES
PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_MUTABLE)
}
fusedLocationProviderClient?.requestLocationUpdates(
mLocationRequest,
locationUpdatePendingIntent
)
LocationUpdatesBroadcastReceiver
class LocationUpdatesBroadcastReceiver: BroadcastReceiver() {
private val TAG = "LocationUpdatesBroadcas";
override fun onReceive(context: Context?, intent: Intent?) {
Log.d(TAG, "onReceive() context:$context, intent:$intent")
if (intent?.action == ACTION_PROCESS_UPDATES) {
// Checks for location availability changes.
LocationAvailability.extractLocationAvailability(intent)?.let { locationAvailability ->
if (!locationAvailability.isLocationAvailable) {
Log.d(TAG, "Location services are no longer available!")
}
}
LocationResult.extractResult(intent)?.let { locationResult ->
Log.e(TAG, "onReceive: lastLocation ${locationResult.locations.size}", )
if(locationResult.lastLocation != null){
ShareLocationToAutomaticWorker.INSTANCE?.reciveLocation(locationResult.lastLocation!!)
}
}
}
}
companion object {
const val ACTION_PROCESS_UPDATES =
"com.commuteoptm.bcos.background_services.action." +
"PROCESS_UPDATES"
}
interface UpdatedLocation{
fun onLocationUpdate(location: Location)
}
}
ShareLocationToAutomaticWorker
class ShareLocationToAutomaticWorker(var updateLocation: LocationUpdatesBroadcastReceiver.UpdatedLocation){
private val TAG = "LocationUpdatesBroadcas"
fun reciveLocation( location:Location){
Log.e(TAG, "reciveLocation:--- ${location} " )
updateLocation.onLocationUpdate(location)
}
companion object {
var INSTANCE: ShareLocationToAutomaticWorker? = null
fun getInstance(updateLocation: LocationUpdatesBroadcastReceiver.UpdatedLocation): ShareLocationToAutomaticWorker {
return INSTANCE ?: synchronized(this) {
INSTANCE ?: ShareLocationToAutomaticWorker(
updateLocation )
.also { INSTANCE = it }
}
}
}
}
How to scan barcode lines with VARCHAR Chars For example OfficeEqp35023U11 In android Kotlin
Struggling to scan this asset image
Struggling to scan this asset image
class BarcodeScannerActivity : AppCompatActivity(), ZXingScannerView.ResultHandler {
private var mScannerView: ZXingScannerView? = null
lateinit var apiInterface: APIInterface
public override fun onCreate(state: Bundle?) {
super.onCreate(state)
setContentView(R.layout.activity_barcode_scanner)
ssoId = intent.getStringExtra("initiator")
val contentFrame = findViewById<View>(R.id.content_frame) as ViewGroup
mScannerView = ZXingScannerView(this)
contentFrame.addView(mScannerView)
}
public override fun onResume() {
super.onResume()
mScannerView!!.setResultHandler(this)
mScannerView!!.startCamera()
}
public override fun onPause() {
super.onPause()
mScannerView!!.stopCamera()
}
override fun handleResult(rawResult: Result) {
Toast.makeText(
this, "Contents = " + rawResult.text +
", Format = " + rawResult.barcodeFormat.toString(), Toast.LENGTH_SHORT
).show()
var result = rawResult.text
if (result.isDigitsOnly()) {
assetTag = result.filter { it.isLetterOrDigit() }
mScannerView!!.stopCamera()
apiInterface = APIClient.client!!.create(APIInterface::class.java)
val call: Call<Verifiedd> =
apiInterface.saveVerification(assetTag, ssoId, ssoId, "Verified", "Verified")
call.enqueue(object : Callback<Verifiedd> {
override fun onResponse(call: Call<Verifiedd>, response: Response<Verifiedd>) {
if (response.body() != null) {
lovelyProgressDialog?.dismiss()
Log.d("TAG", response.code().toString() + "")
var displayResponse = ""
val resource: Verifiedd = response.body()!!
responseCode = resource.responseCode
responseMessage = resource.responseMessage
if (responseMessage == "Data persisted successfully " || responseMessage.equals(
"Data persisted successfully "
)
) {
Toasty.normal(
this#BarcodeScannerActivity,
"",
Toasty.LENGTH_LONG
).show()
} else if (responseMessage == "" || responseMessage.equals(
""
)
) {
Toasty.normal(
this#BarcodeScannerActivity,
"Invalid Asset Verification status values",
Toasty.LENGTH_LONG
).show()
val intent =
Intent(this#BarcodeScannerActivity, BranchItemsActivity::class.java)
intent.flags =
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
intent.putExtra(
"initiator", ssoId
)
startActivity(intent)
}
}
}
override fun onFailure(call: Call<Verifiedd>, t: Throwable) {
Toasty.normal(
this#BarcodeScannerActivity,
"Server Error",
Toasty.LENGTH_LONG
).show()
}
})
I'm assigning a value to lateinit varable in my first function and I want to access same value in my second function but gives me an error UninitializedPropertyAccessException. I know it is because of variable scope. My question is how can i access this value?
Here is my lateinit variables
lateinit var area:String
lateinit var zipcode:String
Here is my first function
fun showSearchDialog(view: View) {
val dialog = context?.let { Dialog(it) }
dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE)
dialog?.setCancelable(true)
dialog?.setContentView(R.layout.alertdialog_search_layout)
//Initializing the views of the dialog.
val postalCode: TextInputEditText? = dialog?.findViewById(R.id.et_zip_code)
val sliderArea: Slider? = dialog?.findViewById(R.id.slider_area)
val searchButton: Button? = dialog?.findViewById(R.id.search_btn)
searchButton?.setOnClickListener {
if (sliderArea != null) {
area = sliderArea.value.toString()
}
zipcode = postalCode?.text.toString()
val postCodeUpperCase = postalCode?.text.toString().toUpperCase(Locale.ROOT)
if (zipcode.isEmpty()) {
postalCode?.error = "Please enter your post code"
postalCode?.requestFocus()
} else if (isValidZipCode(postCodeUpperCase)) {
postalCode?.error = "Please enter valid post code"
postalCode?.requestFocus()
} else {
if (isNetworkAvailable(requireContext())) {
viewModel.getSkipFilterList(zipcode, area)
Toast.makeText(context, "Valid postal code is = $zipcode", Toast.LENGTH_LONG).show()
}
else {
showAlertDialog(getString(R.string.no_internet))
}
}
//dialog.dismiss()
}
dialog?.show()
Here is my second Function
override fun inOnCreateView(mRootView: ViewGroup, savedInstanceState: Bundle?) {
val homeActivity = activity as HomeNavHostActivity
homeActivity.toolbar_id?.visibility = View.VISIBLE
homeActivity.toolbar_search_icon_id.visibility = View.VISIBLE
homeActivity.toolbar_add_icon_id.visibility = View.GONE
homeActivity.home_view_layout?.visibility = View.VISIBLE
homeActivity.bottom_layout?.visibility = View.VISIBLE
homeActivity.toolbar_title_tv.text = "Home"
homeActivity.toolbar_search_icon_id.setOnClickListener() {
showSearchDialog(mRootView)
}
homeActivity.cancel_text.setOnClickListener() {
homeActivity.search_layout.visibility = View.GONE
homeActivity.toolbar_title_tv.visibility = View.VISIBLE
homeActivity.search_view?.setQuery("", false)
homeActivity.search_view?.clearFocus()
}
val dialogHelper by inject<MaterialDialogHelper>()
setupProgressDialog(viewModel.showHideProgressDialog, dialogHelper)
if (isNetworkAvailable(requireContext())) {
viewModel.getSkipFilterList(zipcode, area)
// viewModel.getSkipHomeData()
} else {
showAlertDialog(getString(R.string.no_internet))
}
attachViewModel()
}
I am building an application which shows overlay over another application like a app locker do. but its not like it. I want to show a dialog on an application which exists on database every time i open the application. I have made a service which continuously checks for which application is in foreground using a timer task set at delay and period of 1sec.
The problem is that it shows the dialog only one time on every application due to one statement inside the timer task run function. How can i make it work so that it always shows dialog on the application. Any alternative or optimizations?
import android.app.ActivityManager
import android.app.Dialog
import android.app.Service
import android.app.usage.UsageStats
import android.app.usage.UsageStatsManager
import android.content.Context
import android.content.Intent
import android.graphics.PixelFormat
import android.os.Build
import android.os.IBinder
import android.util.Log
import android.view.Gravity
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import androidx.annotation.RequiresApi
import app.privvio.android.policysplash.PolicyDialog
import app.privvio.android.preference.GetFirebaseAllApps
import java.util.*
import kotlin.collections.ArrayList
class AppCheckServices : Service() {
private var context: Context? = null
var imageView: ImageView? = null
private var windowManager: WindowManager? = null
private var dialog: Dialog? = null
var dbPackageName: ArrayList<String> = GetFirebaseAllApps().getAppsUploaded()
override fun onCreate() {
super.onCreate()
context = applicationContext
/** Timer started for long time **/
timer = Timer("AppCheckServices")
timer!!.scheduleAtFixedRate(updateTask, 1000L, 1000L)
/** Window Manager posts a Blank Image
* view with transparent background which blocks the view
* and the policy dialog is shown over it
* **/
windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
imageView = ImageView(this)
imageView!!.visibility = View.GONE
val LAYOUT_FLAG: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
} else {
WindowManager.LayoutParams.TYPE_PHONE
}
val params = WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
LAYOUT_FLAG,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSPARENT)
params.gravity = Gravity.TOP or Gravity.CENTER
params.x = applicationContext.resources.displayMetrics.widthPixels / 2
params.y = applicationContext.resources.displayMetrics.heightPixels / 2
windowManager!!.addView(imageView, params)
}
private val updateTask: TimerTask = object : TimerTask() {
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
override fun run() {
currentApp = ForegroundApps
if (dbPackageName.contains(ForegroundApps)) {
Log.d("DBAppFRGRND", "true : The application is in foreground.")
if (imageView != null) {
imageView!!.post {
if (currentApp != previousApp) {
showPolicyDialog()
previousApp = currentApp
} else {
Log.d("AppCheckService", "currentApp matches previous App")
}
}
}
} else {
Log.d("DBAppFRGRND", "false : The application is not uploaded to the server. ")
if (imageView != null) {
imageView!!.post {
hidePolicyDialog();
}
}
}
}
}
/** This section tells whether an application is in foreground or background */
val ForegroundApps: String?
#RequiresApi(Build.VERSION_CODES.LOLLIPOP_MR1)
get() {
var mpackageName: String? = null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
val usm = this.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
val time = System.currentTimeMillis()
val appList: List<UsageStats>? = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, 0, time)
if (appList != null && appList.isNotEmpty()) {
val sortedMap = TreeMap<Long, UsageStats>()
for (usageStats in appList) {
sortedMap[usageStats.lastTimeUsed] = usageStats
}
mpackageName = sortedMap.takeIf { it.isNotEmpty() }?.lastEntry()?.value?.packageName
Log.d(TAG, "isEmpty No : $mpackageName")
} else {
Log.d(TAG, "isEmpty Yes")
mpackageName = ""
}
} else {
val am = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
#Suppress("DEPRECATION") //The deprecated method is used for devices running an API lower than LOLLIPOP
mpackageName = am.getRunningTasks(5)[0].topActivity?.packageName
Log.d(TAG, "isEmpty No : $mpackageName")
}
return mpackageName
}
fun showPolicyDialog() {
if (context == null) context = applicationContext
PolicyDialog(context!!).showDialog(context!!)
}
fun hidePolicyDialog() {
previousApp = ""
try {
if (dialog != null) {
if (dialog!!.isShowing) {
dialog!!.dismiss()
}
}
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
/** We want this service to continue running until it is explicitly
* stopped, so return sticky.
*/
return START_STICKY
}
override fun onDestroy() {
super.onDestroy()
// timer!!.cancel()
// timer = null
if (imageView != null) {
windowManager!!.removeView(imageView)
}
try {
if (dialog != null) {
if (dialog!!.isShowing) {
dialog!!.dismiss()
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
companion object {
const val TAG = "AppCheckServices"
var currentApp: String? = ""
var previousApp: String? = ""
var timer: Timer? = null
}
}
Is it possible to use Android Bundle to create and putString() in Activity then getString() in Service on button click?
If not what can i do?
Example
MainActivity.kt
val bundle = Bundle()
bundle.putString("MyString", "Message")
val mesg = Message.obtain(null, MyService.SEND_MESSAGE_FLAG)
mesg.obj = bundle
try {
myService!!.send(mesg)
} catch (e: RemoteException) {
}
Service
override fun handleMessage(msg: Message) {
when (msg.what) {
SEND_MESSAGE_FLAG -> {
val data = msg.data
val dataString = data.getString("MyString")
println(dataString)
val mesg = Message.obtain(null, SEND_MESSAGE_FLAG)
mesg.obj = dataString
try {
msg.replyTo.send(mesg)
} catch (e: RemoteException) {
Log.i(TAG, "Error: " + e.message)
}
}
}
super.handleMessage(msg)
}
You can add static method in your service:
companion object {
private const val EXTRA_KEY_MY_STR = "EXTRA_KEY_MY_STR"
fun startMyService(context: Context?, myStr: String?) {
if (context != null) {
val intent = Intent(context, MyService::class.java)
intent.putExtra(EXTRA_KEY_MY_STR, myStr)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent)
} else {
context.startService(intent)
}
}
}
}
then call it from your activity: MyService.startMyService(this, "MyString")
and then get string in your onHandleIntent(): val myStr = intent?.extras?.getString(EXTRA_KEY_MY_STR)