【问题标题】:How do I create a notification that goes through an array on Android?如何在 Android 上创建通过数组的通知?
【发布时间】:2021-03-20 05:21:36
【问题描述】:

我是编程初学者!我正在尝试创建一个将在特定时间发送通知的应用程序。通知的描述必须来自先前在应用程序中定义的数组。 现在,我分部分进行:通知由 WorkManager 创建,由按钮激活。现在是 OneTimeWorkRequest。

我现在的问题是:如何获取通知以从数组中获取其描述?我尝试使用 while 循环,但它只使用数组中的第一个字符串。

我的活动代码:

class CatPicsActivity : AppCompatActivity() {

lateinit var notifBtn: MaterialButton;
lateinit var catBtn: ImageButton;
lateinit var title: String;
lateinit var catImg: ImageView;
var url: String = "https://api.thecatapi.com/v1/"

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_cat_pics)

    notifBtn = findViewById(R.id.botaoNotificacao);
    catBtn = findViewById(R.id.catbtn);
    catImg = findViewById(R.id.imgCat);

    title = getResources().getString(R.string.titulo_notificacao);

    notifBtn.setOnClickListener {


        Log.i("WorkButton", "clicado")

        val notifcWorker: OneTimeWorkRequest =
                OneTimeWorkRequestBuilder<NotificationWorker>()
                        .build()

        WorkManager.getInstance(this)
                .enqueueUniqueWork(
                        "notification_worker",
                        ExistingWorkPolicy.KEEP,
                        notifcWorker
                )
    }

    catBtn.setOnClickListener {
        catFunction();
    }
}

private fun catFunction() {
    val retrofit = Retrofit.Builder()
            .baseUrl(url)
            .addConverterFactory(GsonConverterFactory.create())
            .build()

    val catService: CatService = retrofit.create(CatService::class.java)
    catService.randomCat().enqueue(object : Callback<List<Cat>> {
        override fun onResponse(call: Call<List<Cat>>, response: Response<List<Cat>>) {
            val randomCat = response.body()!!

            Picasso.get()
                    .load(randomCat[0].url)
                    .into(catImg)
        }

        override fun onFailure(call: Call<List<Cat>>, t: Throwable) {
            Toast.makeText(this@CatPicsActivity, "Deu errado! Tente novamente, por favor", Toast.LENGTH_SHORT).show()
            Log.i("CatPics", "Erro: $t")
        }
    })

}}

我的工人阶级:

class NotificationWorker(private val context: Context, params: WorkerParameters) : Worker(context, params) {


lateinit var descricao: String

fun generateDescription (): String {
    var razoes = arrayOf(
            "Esta é uma notificação de teste, por favor me avise no Telegram se chegou",
            "1 - ",
            "2 - ",
            "3 - ",
            "4 - ",
            "5 - ",
            "6 - ",
            "7 - ",
            "8 - ",
            "9 - ",
            "10 - ",
            "11 - ",
            "12 - ",
            "13 - ",
            "14 - ",
            "15 - ",
            "16 - ",
            "17 - ",
            "18 - ",
            "19 - ",
            "20 - ",
            "21 - ",
            "22 - ",
            "23 - ",
            "24 - ",
            "25 - ",
            "26 - ",
            "27 - ",
            "28 - ",
            "29 - ",
            "30 - ")

    var array = razoes
    var i = 0

    while(i < array.size){
        descricao = array[i]
        i += 1
        return descricao
    }

    return descricao
}

var title: String = "Você recebeu uma nova mensagem!"

override fun doWork(): Result {

    generateDescription()
    Log.i("WorkerDescricao2", descricao)
    Log.i("WorkBeforeNotification", "Trabalho criado")

    NotificationUtils.createNotification(context, title, descricao)

    Log.i("WorkAfterNotification", "notificação enviada")

    return Result.success()

}}

那么,如何从数组“razoes”中获取“descricao”变量?

谢谢!

编辑:

我希望数组中的每个值都用于不同的通知,这些通知将在单击按钮后(或将来的每一天)发送。

【问题讨论】:

  • 您的 generateDescription() 函数创建了一个数组。然后它尝试遍历数组,一次将每个结果分配给descricao,但它在第一次迭代时立即返回descricao。因此,当函数完成时,descricao 具有数组中第一项的值。但我不知道你想要完成什么,所以我不知道还能说什么。创建通知时,您希望显示整个文本数组,还是什么?
  • @Tenfour04 感谢您的评论和回答!我想在一个通知中使用数组的每个元素。我的想法是每天 WorkManager 都会创建一个通知,并且这些通知中的每一个都基于数组的一项。现在,我只希望 WorkManager 通过单击按钮关闭。每次点击都是数组的一项。除此之外,我尝试从循环中删除返回,但它做了同样的事情,使用数组中的 [0] 创建了一个通知。

标签: android arrays kotlin notifications


【解决方案1】:

在您的代码中,您在 while 循环中有一个返回。因此,在第一次迭代中,您将退出 while 循环并在您的 descricao 变量中返回 razoes[0] 的值。也不需要使用额外的数组,你可以立即访问 razo:

 var i = 0
    while(i < razoes.size) {
        descricao = razoes[i]
        i += 1
        //return descricao
    }

所以我不知道你想保持什么价值。如果你想要所有的剃须刀,那么你应该打电话给NotificationUtils.createNotification(context, title, descricao) 在一个循环中。如果您想从 razoes 中获得特定值,您应该更改您的 generateDescription fun 之类的东西

fun generateDescription(position: Int): String {
    var razoes = arrayOf(
            "Esta é uma notificação de teste, por favor me avise no Telegram se chegou",
            "1 - ",
            "2 - ",
            "3 - ",
            "4 - ",
            "5 - ",
            "6 - ",
            "7 - ",
            "8 - ",
            "9 - ",
            "10 - ",
            "11 - ",
            "12 - ",
            "13 - ",
            "14 - ",
            "15 - ",
            "16 - ",
            "17 - ",
            "18 - ",
            "19 - ",
            "20 - ",
            "21 - ",
            "22 - ",
            "23 - ",
            "24 - ",
            "25 - ",
            "26 - ",
            "27 - ",
            "28 - ",
            "29 - ",
            "30 - ")
    descricao = razoes[position]
    return descricao
}

如果我理解正确,您希望在每次下一个剃须刀数组项时单击按钮发送带有描述的通知。所以这里是一个处理点击按钮的例子(我烤了一个虚拟消息,只是为了展示逻辑):

private var razoes = intArrayOf(1, 2, 3, 4, 5)
private var position: Int = -1

 binding.button.setOnClickListener {
            handleButtonClick()
        }

 private fun handleButtonClick() {
        position += 1
        if (position > razoes.size -1) {
            Toast.makeText(this@DemoActivity, "There are no other items in razoes", Toast.LENGTH_SHORT).show()
        } else {
            Toast.makeText(this@DemoActivity, razoes[position].toString(), Toast.LENGTH_SHORT).show()
        }
    }

【讨论】:

  • 感谢您的回答!但是,当我删除 return 语句时,它保持不变。我忘记了我放的额外数组?那是因为数组应该在一个单独的文件中,但我无法正确引用它并忘记删除变量。我想在通知中使用数组中的每个值。你的意思是在一个while循环中?对不起,你能给我举个例子吗?非常感谢!
  • @Isadora 我更新了我的答案,请检查。
【解决方案2】:

我认为您尝试做的是让 generateDescription() 函数在每次调用它时继续在 while 循环中停止的地方。函数根本不是那样工作的。每次您调用它们时,它们都会从一开始就运行(不记得以前调用过它的任何时间),直到遇到return

因此,您必须保留一个属性来跟踪您离开的位置。因此,对代码进行最小更改并使其正常工作的方法是创建一个属性来跟踪您接下来要显示的数组索引。每次调用此函数时,都会增加此变量并使用它来获取数组的下一个值。要让它在到达末尾时绕回数组的开头,您可以使用带有数组大小的余数运算符%

您可以去掉descricao 属性,因为它除了保存此函数调用的结果之外没有其他用途。您可以使用局部变量将结果保存在您使用它的位置。

我使用迭代器使数组的创建更加简洁,但我意识到您可能计划每天更改值,因此您无法长期这样做。

private var notificationIndex = -1

fun generateDescription (): String {
    val razoes = Array<String>(31) {
        if (it == 0)
            "Esta é uma notificação de teste, por favor me avise no Telegram se chegou"
        else
            "$it - "
    }
    notificationIndex = (notificationIndex + 1) % razoes.size
    return razoes[notificationIndex]
}

override fun doWork(): Result {

    val descricao = generateDescription()
    Log.i("WorkerDescricao2", descricao)
    Log.i("WorkBeforeNotification", "Trabalho criado")

    NotificationUtils.createNotification(context, title, descricao)

    Log.i("WorkAfterNotification", "notificação enviada")

    return Result.success()

}

为了使代码更合理,还有更多工作要做。例如,如果描述是常量,则不应在函数中创建数组。整个数组应该只创建并存储在声明站点的属性中。并且文字字符串不应该像这样硬编码,而应该从 XML 资源中提取。

您还在 cmets 中提到您希望每天收到不同的通知。这使得这更复杂,而且比我想在这里解释的要多得多。如果每天都不一样,你不能只依赖上面的notificationIndex 属性,因为下次应用程序出现时它会被遗忘。您需要保留该值,您可以在 Android 文档中了解该值。

【讨论】:

    猜你喜欢
    • 2021-11-29
    • 2015-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-25
    相关资源
    最近更新 更多