Задать вопрос
  • Как запустить цикл с okhttp3 в фоновом режиме Android?

    @uzolenta Автор вопроса
    Есть файл ForegroundService с кодом:
    class ForegroundService : Service() {
        private val CHANNEL_ID = "1"
        companion object {
            fun startService(context: Context, message: String) {
                val startIntent = Intent(context, ForegroundService::class.java)
                startIntent.putExtra("inputExtra", message)
                ContextCompat.startForegroundService(context, startIntent)
            }
            fun stopService(context: Context) {
                val stopIntent = Intent(context, ForegroundService::class.java)
                context.stopService(stopIntent)
            }
        }
        @RequiresApi(Build.VERSION_CODES.O)
        override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
            //do heavy work on a background thread
            val input = intent?.getStringExtra("inputExtra")
            createNotificationChannel()
            val notificationIntent = Intent(this, PostingVKActivity::class.java)
            val pendingIntent = PendingIntent.getActivity(
                this,
                0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
            )
    
            val notification = NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("Foreground Service Kotlin Example")
                .setContentText(input)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(pendingIntent)
                .build()
    
    
            startForeground(1, notification)
    
    
            //stopSelf();
            return START_NOT_STICKY
        }
        override fun onBind(intent: Intent): IBinder? {
            return null
        }
        @RequiresApi(Build.VERSION_CODES.O)
        private fun createNotificationChannel() {
          //  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val serviceChannel = NotificationChannel(CHANNEL_ID, "1",
                    NotificationManager.IMPORTANCE_DEFAULT)
                val manager = getSystemService(NotificationManager::class.java)
                manager!!.createNotificationChannel(serviceChannel)
           // }
        }
    }


    Есть функция, которой надо работать в фоновом режиме:
    fun HOPO(){
    
    g = 0
    
    while(g < 10){
    api = "https://test.ru/g=$g"
    val request = Request.Builder()
                .url(api)
                .post(postBody.toRequestBody(MEDIA_TYPE_MARKDOWN))
                .header("X-Get-Processing-Time", "1")
                .removeHeader("User-Agent")
                .addHeader("User-Agent", UserAgent)
                .build()
    
            client.newCall(request).enqueue(object : Callback {
                override fun onFailure(call: Call, e: IOException) {
                    e.printStackTrace()
                }
           override fun onResponse(call: Call, response: Response) {
     runOnUiThread {
                                gEditText.text = "$g"
    }
          }
    })
    
    g++
    }//END WHILE
    }//END FUN


    в Активити через кнопку запускать?
    val intentActivity = Intent(this, Activity::class.java)
                startService(intentActivity)
    
                HOPO()
  • Как запустить цикл с okhttp3 в фоновом режиме Android?

    @uzolenta Автор вопроса
    rPman, а не похоже, что я не только гуглю? Варианты же кидаю, какие пробую.

    В цикле вызываю из второго варианта сервис:
    ForegroundService.startService(this, "СТАРТ ")
    Но ничего не происходит, хотя там есть
    val notification = NotificationCompat.Builder(this, CHANNEL_ID)
  • Как запустить цикл с okhttp3 в фоновом режиме Android?

    @uzolenta Автор вопроса
    Либо такой ещё есть

    class ForegroundService : Service() {
        private val CHANNEL_ID = "1"
        companion object {
            fun startService(context: Context, message: String) {
                val startIntent = Intent(context, ForegroundService::class.java)
                startIntent.putExtra("inputExtra", message)
                ContextCompat.startForegroundService(context, startIntent)
            }
            fun stopService(context: Context) {
                val stopIntent = Intent(context, ForegroundService::class.java)
                context.stopService(stopIntent)
            }
        }
        @RequiresApi(Build.VERSION_CODES.O)
        override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
            //do heavy work on a background thread
            val input = intent?.getStringExtra("inputExtra")
            createNotificationChannel()
            val notificationIntent = Intent(this, PostingVKActivity::class.java)
            val pendingIntent = PendingIntent.getActivity(
                this,
                0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
            )
                /*
            val notification = NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("Foreground Service Kotlin Example")
                .setContentText(input)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(pendingIntent)
                .build()
    
    
            startForeground(1, notification)
            */
    
            //stopSelf();
            return START_NOT_STICKY
        }
        override fun onBind(intent: Intent): IBinder? {
            return null
        }
        @RequiresApi(Build.VERSION_CODES.O)
        private fun createNotificationChannel() {
          //  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val serviceChannel = NotificationChannel(CHANNEL_ID, "1",
                    NotificationManager.IMPORTANCE_DEFAULT)
                val manager = getSystemService(NotificationManager::class.java)
                manager!!.createNotificationChannel(serviceChannel)
           // }
        }
    }
  • Как запустить цикл с okhttp3 в фоновом режиме Android?

    @uzolenta Автор вопроса
    rPman, я это понимаю. Я не понимаю как связать сервис и мой код.
    Вот взял код с сайта, ошибок не выдаёт, но что с ним делать дальше? Реально как связать одно с другим не понимаю.

    class ForegroundService2 : Service() {
    
    
    
        override fun onCreate() {
            super.onCreate()
        }
    
        @RequiresApi(Build.VERSION_CODES.O)
        override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
            val input = intent.getStringExtra("inputExtra")
            createNotificationChannel()
            val notificationIntent = Intent(this, MainActivity::class.java)
            val pendingIntent = PendingIntent.getActivity(
                this,
                0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
            )
            val notification: Notification = Notification.Builder(this, CHANNEL_ID)
                .setContentTitle("Foreground Service")
                .setContentText(input)
                .setSmallIcon(R.drawable.alert_light_frame)
                .setContentIntent(pendingIntent)
                .build()
            startForeground(1, notification)
            //do heavy work on a background thread
            //stopSelf();
            return START_NOT_STICKY
        }
    
        override fun onDestroy() {
            super.onDestroy()
        }
    
        @Nullable
        override fun onBind(intent: Intent): IBinder? {
            return null
        }
    
        private fun createNotificationChannel() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val serviceChannel = NotificationChannel(
                    Companion.CHANNEL_ID,
                    "Foreground Service Channel",
                    NotificationManager.IMPORTANCE_DEFAULT
                )
                val manager = getSystemService(
                    NotificationManager::class.java
                )
                manager.createNotificationChannel(serviceChannel)
            }
        }
    
        companion object {
            const val CHANNEL_ID = "ForegroundServiceChannel"
        }
    }
  • Как запустить цикл с okhttp3 в фоновом режиме Android?

    @uzolenta Автор вопроса
    А для такой задачи не лучше WorkManager?
    Мб где-нибудь встречали пример похожий на мой - отправка запроса в цикле в фоне?
    А то я честно не могу раздуплиться, хотя фоновый сервис уже был написан до этого, я пытался разобраться.
    Спасибо.
  • Как отправлять почту через smtp на mail.ru/gmail?

    @uzolenta Автор вопроса
    Выделите свой надменный коммент и нажмите клавишу Del.
    Если бы интересовал phpmailer, то про него бы и спрашивал.
    Вопрос конкретно про такую реализацию, не набивайте себе комментарии.
  • Получаю ошибку "UIImage? is not convetrible to UIImage". Как работать с UIImagePickerController в Swift 5?

    @uzolenta
    var image = UIImage()

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    
                image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
    
        }
  • Как обновить интерфейс при нажатии кнопки(проблема с потоками)?

    @uzolenta Автор вопроса
    briahas, какая кислотность? Выше вся проблема расписана в подробностях. Если Вы не читаете, а хотите, чтобы Вам всё повторяли - это не по делу. + я уже ответил ещё раз. До свидания ещё раз.
  • Как обновить интерфейс при нажатии кнопки(проблема с потоками)?

    @uzolenta Автор вопроса
    briahas, выше уже всё расписано до мелочей. Убеждать Вас - я здесь не за этим. До свидания.
  • Как обновить интерфейс при нажатии кнопки(проблема с потоками)?

    @uzolenta Автор вопроса
    briahas, в коде, который кидал в самом начале же видно. Чтобы управлять индикатором, либо показывать алерт внутри Global()
  • Как обновить интерфейс при нажатии кнопки(проблема с потоками)?

    @uzolenta Автор вопроса
    doublench21, если в цикле, который перебирает blackList и отправляет запросы, возникает ошибка.

    Тут уже до меня, вроде, допёрло, что тупанул.
    Надо же просто, скорее всего, выйти из цикла перебора blackList с помощью break
  • Как обновить интерфейс при нажатии кнопки(проблема с потоками)?

    @uzolenta Автор вопроса
    doublench21, ну выполнения кода, который завёрнут в global(){ код }
  • Как обновить интерфейс при нажатии кнопки(проблема с потоками)?

    @uzolenta Автор вопроса
    doublench21, Да, так. Так я сделал, только с использованием схемы с Global(), но проблема Global в том, что при возникновении ошибок внутри Global, нельзя остановить никак же.
  • Как обновить интерфейс при нажатии кнопки(проблема с потоками)?

    @uzolenta Автор вопроса
    doublench21, спасибо Вам.
    Тут реально больше вопрос в том как заставить показаться индикатору( или алерту) при нажатии кнопки, а это надо сделать не в asyc, как я понимаю.
  • Как обновить интерфейс при нажатии кнопки(проблема с потоками)?

    @uzolenta Автор вопроса
    doublench21,
    "P.S. Он у вас запускается и скорее всего тут же и останавливается, в виду асинхронности кода."

    acrivityIndicator.stopAnimating() я убрал, поэтому не останавливается.

    Получает массив blackList, по которому дальше в цикле прогоняются запросы (кусок кода который кинул выше).
  • Как обновить интерфейс при нажатии кнопки(проблема с потоками)?

    @uzolenta Автор вопроса
    doublench21, я уже просто не знаю как проще объяснить :)

    "Чтобы индикатор активности отображался (либо Алерт всплывал) при нажатии на кнопку до начала выполнения остального кода. Для меня просто непонятно, почему не делается по коду то, что стоит первым(отображение индикатора) после нажатия кнопки, а ждёт выполнения DataTask, которая находится ниже по коду."

    @IBAction func button(_ sender: UIButton) {
    acrivityIndicator.startAnimating() //чтобы выполнилось в первую очередь
    
    // остальной код с URLSession
    }
  • Как обновить интерфейс при нажатии кнопки(проблема с потоками)?

    @uzolenta Автор вопроса
    doublench21, в чём ужас? Вы просто внутри функции data присваиваете ответ в String. Я же с помощью ожидания могу контролировать время ожидания ответа от сервера, а не ожидать что отдаст сам сервер.
    Меня стопорит отображение(изменение) интерфейса в процессе всех циклов (запросы DataTask могут быть и 2000 за цикл).
    Чтобы индикатор активности отображался при нажатии на кнопку до начала выполнения. Для меня просто непонятно, почему не делается по коду то, что стоит первым(отображение индикатора) после нажатия кнопки, а ждёт выполнения DataTask, которая находится ниже по коду.
  • Как обновить интерфейс при нажатии кнопки(проблема с потоками)?

    @uzolenta Автор вопроса
    /*START DELETE Black List*/
         
            var b: Int = 0
                while(b<self.blackList.count){
                    if(b > 0){
                        OperationQueue.main.addOperation {
                            self.dismiss(animated: true, completion: nil)
                        }
                    }
            let vkUrl = URL(string: "http://url.ru/test/deleteBlackList.php")
            var request = URLRequest(url: vkUrl!)
            let device: String = "\(shared.nameDevice)"
                    let postString = "v=5.80&lang=ru&https=1&device=\(device)&access_token=\(self.access_token)&owner_id=\(self.blackList[b].id)"
            
            request.httpBody = postString.data(using: String.Encoding.utf8);
            request.httpMethod = "POST"
            request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")
            request.addValue(shared.userAgent, forHTTPHeaderField: "User-Agent")
            request.addValue("300", forHTTPHeaderField: "content-Length")
            request.addValue("1", forHTTPHeaderField: "X-Get-Processing-Time")
            request.addValue("remixlang=0", forHTTPHeaderField: "Cookie")
            
            
            URLSession.shared.dataTask(with: request) {(data, response, error) in
                guard let data = data else {
                    let error_code = String(error!._code)
                    let error_msg = "DeleteFromBlackList 1. Ошибка соединения с сервером. Пожалуйста, попробуйте позже. \n Если ошибка будет повторяться, то сообщите в службу поддержки приложения. \n Код ошибки: " + error_code"
                    let alertVC = UIAlertController(title: "Ошибка", message: error_msg, preferredStyle: .alert)
                    let actionOK = UIAlertAction(title: "OK", style: .default, handler: nil)
                    alertVC.addAction(actionOK)
                    DispatchQueue.main.async(execute: {
                        self.present(alertVC, animated: true, completion: nil)
                    })
                    return
                }
                do {
                    self.json = data
                    self.k = true
                }
                }.resume()
            
            /*WAIT RESPONSE*/
            var i = 0
            while (self.k != true && i<20){
                sleep(1)
                i += 1
            }
            self.k = false
            
            if i >= 20 {
                let error_msg = "Время ожидания ответа от сервера приложения истекло, проверьте интернет-соединение. Если ошибка будет повторяться много раз, то напишите в поддержку приложения. \n Попытка получить черный список."
                let alertVC = UIAlertController(title: "Ошибка", message: error_msg, preferredStyle: .alert)
                let actionOK = UIAlertAction(title: "OK", style: .default, handler: nil)
                alertVC.addAction(actionOK)
                DispatchQueue.main.async(execute: {
                self.present(alertVC, animated: true, completion: nil)
                })
                return
            }
            /*END WAIT RESPONSE*/
            
            /*JSON DECODE*/
            
            var dataString: String = ""
            dataString = NSString(data: self.json!, encoding: String.Encoding.utf8.rawValue)! as String
             print("------------------")
             print(dataString)
            
                    OperationQueue.main.addOperation {
    
                        let alert = UIAlertController(title: "Удалено: \(b)", message: nil, preferredStyle: .alert)
                        let activityIndicator = UIActivityIndicatorView(style: .medium)
                        activityIndicator.translatesAutoresizingMaskIntoConstraints = false
                        activityIndicator.isUserInteractionEnabled = false
                        activityIndicator.startAnimating()
    
                        alert.view.addSubview(activityIndicator)
                        alert.view.heightAnchor.constraint(equalToConstant: 95).isActive = true
    
                        activityIndicator.centerXAnchor.constraint(equalTo: alert.view.centerXAnchor, constant: 0).isActive = true
                        activityIndicator.bottomAnchor.constraint(equalTo: alert.view.bottomAnchor, constant: -20).isActive = true
    
                        self.present(alert, animated: true)
                    }
                    
                    
                b += 1
            }//END WHILE
                
                OperationQueue.main.addOperation {
                    self.dismiss(animated: true, completion: nil)
                }
            }//END Global
            
            /*END DELETE Black List*/
  • Как обновить интерфейс при нажатии кнопки(проблема с потоками)?

    @uzolenta Автор вопроса
    Оверлай я сделал, всё как в примере, который Вы скинули.

    Вопрос всё в том же, как запустить Оверлай при нажатии на кнопку и как его потом закрыть, если не использовать Global, как выше.