应用程序关闭时服务和接收器不起作用

Posted

技术标签:

【中文标题】应用程序关闭时服务和接收器不起作用【英文标题】:Service and Receiver don't work when app is closed 【发布时间】:2018-03-27 14:20:09 【问题描述】:

我在一个项目中使用日历安排任务并在特定时间完成工作,漏洞代码没问题,可以正常工作,但是如果我在我输入的特定时间强制关闭我的 android 应用程序应用程序开始时不要执行我的任务,它给了我一个“不幸的是 TransferirLigações 已停止”。 我认为计时器和 AlarmManager 正在工作,但不要执行我的任务,报错。

我尝试了各种调度任务来执行此操作,AlarmManager 和 Receiver、Service、IntentService、Job Scheduler 和一些插件来执行此操作,但没有任何效果,都给我“不幸的是 TransferirLigações 已停止”。

有人可以帮助我吗?我认为这是 Manifest 或 Permisions 中的一些错误,但我不知道。

代码:

MainActivity、startAlarm 类:

 private void startAlarm() 
            Intent intent = new Intent(getApplicationContext(), AlarmToastReceiver.class);
            final PendingIntent pIntent = PendingIntent.getBroadcast(this, AlarmToastReceiver.REQUEST_CODE,
                    intent, PendingIntent.FLAG_UPDATE_CURRENT);
            AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
            alarm.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pIntent);

        

接收器类: 包 com.example.usuario.tranferircalls;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;


public class AlarmToastReceiver extends BroadcastReceiver 
    public static final int REQUEST_CODE = 12345;


    @Override
    public void onReceive(Context context, Intent intent) 
        Intent i = new Intent(context, MyTestService.class);
        i.putExtra("foo", "bar");
        context.startService(i);
    

意图服务:

package com.example.usuario.tranferircalls;

import android.app.IntentService;

import android.content.Intent;

import java.util.concurrent.TimeUnit;

import static com.example.usuario.tranferircalls.MainActivity.cancelAlarm;
import static com.example.usuario.tranferircalls.MainActivity.retornarChamada;


public class MyTestService extends IntentService 
    public MyTestService() 
        // Used to name the worker thread
        // Important only for debugging
        super(MyTestService.class.getName());
    


    @Override
    protected void onHandleIntent(Intent intent) 
        retornarChamada(0); //My Task, that i want to do when certain time pass.
        try 
            TimeUnit.SECONDS.sleep(10);
         catch (InterruptedException e) 
            e.printStackTrace();
        
        retornarChamada(1);
        cancelAlarm();
    

我的清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.usuario.tranferircalls">

    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:installLocation="internalOnly"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver
            android:name=".AlarmToastReceiver"
            android:exported="true"
            android:process=":remote"
            android:enabled="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"></action>
            </intent-filter>
        </receiver>
        <service
            android:name=".MyTestService"
            android:enabled="true"
            android:exported="false"/>
    </application>
</manifest>

基本上,这就是我的应用程序,它 90% 都在工作,但我想关闭应用程序并且它可以工作,因为确定我的工作/任务会很好地工作。

已经很感激了,Noninus。

【问题讨论】:

android:process=":remote" 需要什么? 我认为,这段代码使接收器在另一个线程中运行,理论上,可以在应用程序关闭的情况下工作,但事实并非如此。 @ShaluTD 【参考方案1】:

计算时间的代码,它是一个获取时间的 TimePicker,设置在静态日历校准中,我用它来启动 AlarmManager!

Calendar mcurrentTime;
                    mcurrentTime = Calendar.getInstance();
                    mcurrentTime.setTimeInMillis(System.currentTimeMillis());


                    int hour = mcurrentTime.get(Calendar.HOUR_OF_DAY);
                    int minute = mcurrentTime.get(Calendar.MINUTE);

                    TimePickerDialog mTimePicker;
                    mTimePicker = new TimePickerDialog(MainActivity.this, new TimePickerDialog.OnTimeSetListener() 


                        @Override
                        public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute)            
                            cal.set(Calendar.HOUR_OF_DAY,selectedHour);
                            cal.set(Calendar.MINUTE,selectedMinute);
                            endTime = cal.getTime();
                        
                    , hour, minute, true);//Yes 24 hour time

                    mTimePicker.setTitle("Escolha a Hora para as chamadas voltarem!");
                    mTimePicker.show();

【讨论】:

【参考方案2】:

我会尝试:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;


public class AlarmToastReceiver extends BroadcastReceiver 
    public static final int REQUEST_CODE = 12345;


    @Override
    public void onReceive(Context context, Intent intent) 
        Intent i = new Intent(context, MyTestService.class);
        i.putExtra("foo", "bar");
        context.startService(i);
    

【讨论】:

【参考方案3】:

试试这个:

AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
int ALARM_TYPE = AlarmManager.RTC_WAKEUP;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
    am.setExactAndAllowWhileIdle(ALARM_TYPE, calendar.getTimeInMillis(), pendingIntent);
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
    am.setExact(ALARM_TYPE, calendar.getTimeInMillis(), pendingIntent);
else
    am.set(ALARM_TYPE, calendar.getTimeInMillis(), pendingIntent);

【讨论】:

我尝试从 Manifest 中删除此代码,但不工作,不要更改任何内容,当应用程序打开时运行良好,但当应用程序关闭时给我一条错误消息“不幸的是 TransferirLigações 有停止”。 如果这不起作用,请输入您的时间计算代码。 cal.getTimeInMillis()。粘贴您的代码如何计算 cal。 也不行,你认为是manifest上的错误吗?这么多权限? 还是 ? @Shalu T D “不幸的是,TransferirLigações 已经停止了”这个代码和这个新的 AlarmManager,但感谢您的帮助!打开应用程序时代码运行良好,但是当我强制关闭它时它不起作用 使用Calendar.getInstance().getTimeInMillis() + 5min替换cal.getTimeInMillis()

以上是关于应用程序关闭时服务和接收器不起作用的主要内容,如果未能解决你的问题,请参考以下文章

应用程序未运行时广播接收器不起作用

位置服务关闭和打开时地理定位不起作用

屏幕关闭时 Android 通知不起作用

广播接收器在 Android 8 的前台服务中不起作用

推送通知在 UIApplicationLaunchOptionsRemoteNotificationKey 中不起作用

YouTube Data API v3 在生产服务器上部署时不起作用 [关闭]