【问题标题】:xamarin.android Receiver on BOOT_COMPLETED errorxamarin.android 接收器出现 BOOT_COMPLETED 错误
【发布时间】:2018-08-30 09:07:40
【问题描述】:

我正在尝试创建一个从设备启动开始的简单服务。问题是设备返回消息“不幸的是,[app_name] 已停止。”

我在几个小时内一直在努力解决这个问题,寻找错误,但这太简单了。希望你们能帮助我解决这个问题。

这是我的代码:

AndroidManifest.xml

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

<application android:allowBackup="true" android:label="@string/app_name">


    <receiver android:name=".StartReceiver">
          <intent-filter>
              <action android:name="android.intent.action.BOOT_COMPLETED"/>
          </intent-filter>
    </receiver>

  <service android:name=".PService" />
</application>

StartReceiver.cs

[BroadcastReceiver]
[IntentFilter(new[] { Intent.ActionBootCompleted })]
public class StartReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        Intent startIntent = new Intent(context, typeof(PService));
        context.StartService(startIntent);
    }
}

最后是 PService.cs

[Service]
    public class PService : Service
    {
        public override void OnCreate()
        {
            base.OnCreate();
        }

        public override IBinder OnBind(Intent intent)
        {
            return null;
        }


        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            Toast.MakeText(this, "Start", ToastLength.Short).Show();
            return StartCommandResult.Sticky;
        }

        public override void OnDestroy()
        {
            base.OnDestroy(); 

            Toast.MakeText(this, "Stop", ToastLength.Short).Show();
        }
    }

此外,此服务应用程序针对 API 19 (4.4.2 KitKat) Android 版本。

我认为会有一个非常小的错误,是我犯的,但我真的找不到它。在此先感谢您的帮助。

【问题讨论】:

  • 为了能够捕获 BOOT_COMPLETED 意图,您的应用还应该有 UI,并且您的用户应该至少打开一次应用。 - 出于安全原因。
  • 是的,我有 Activity 类,我在其中启动服务。 (服务正常启动)问题是重启设备后

标签: c# android visual-studio xamarin service


【解决方案1】:

通过在清单中添加接收器并通过 BroadcastReceiverAttribute,您的清单中有两个接收器。另外,您的清单中的那个将不起作用,因为它不是 Xamarin 默认创建的基于 MD5 的 Java 名称。

通过属性

1) 从清单中删除接收器和启动权限

2) 通过属性添加启动权限)

[assembly: UsesPermission(Manifest.Permission.ReceiveBootCompleted)]

3) 通过属性添加清单条目:

[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { Intent.ActionBootCompleted })]    
public class BootBroadcastReceiver : BroadcastReceiver

通过清单

1) 添加启动权限的清单条目

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

2) 添加接收者并使用完全限定的 Java 类名:

<receiver android:name="com.yourpackagename.app.BootBroadcastReceiver">
      <intent-filter>
          <action android:name="android.intent.action.BOOT_COMPLETED"/>
      </intent-filter>
</receiver>

3) 将 Name 参数添加到 BroadcastReceiverAttribute 以获取您在清单中使用的完全限定 Java 类名称

[BroadcastReceiver(Name = "com.yourpackagename.app.BootBroadcastReceiver", Enabled = true)]
[IntentFilter(new[] { Intent.ActionBootCompleted })]    
public class BootBroadcastReceiver : BroadcastReceiver

【讨论】:

  • 谢谢寿司,'Via manifest' 方法对我很有效。
  • @CDrosos 针对您的问题发布一个新问题,因为我知道这适用于 7.0(实际上是所有 API)
  • 是否有必要使用意图过滤器?我的意思是询问一般的 BroadcastReceiver 我们应该定义一个意图过滤器还是仅仅针对这种情况,因为 OP 在他的问题中写道。我的意思是在 via Manifest 解决方案中。您在清单中定义意图过滤器以及属性?不是双倍的吗?
  • @batmaci 在清单解决方案的“步骤 3”中,您必须为您在清单中手动定义的“完全限定的 Java 类”定义 Name 属性,以便使它们匹配实际上删除消除了“双重”添加的问题(自从我上次检查 Xamarin 的构建过程正确合并清单更改以来,您可能需要自己测试)
  • com.yourpackagename.app??这是整个包名吗?必须添加 .app 吗?
【解决方案2】:

2022 答案

在把我的头撞在墙上将近 3 个小时之后,我终于让它开始工作了。由于 Google 做了一些 API 更改,所有答案都已过时。无论如何,这对我有用。

我是如何测试的

  1. 在手机上启动应用程序(为了消除任何混淆,我什至使用调试器启动它以确认它不是由于“调试”模式造成的)。仅供参考,我正在使用小米 Pocophone F1。我的应用面向 API 级别 30。
  2. 让应用计划通知在 3 分钟后显示
  3. 重启手机
  4. 等待 3 分钟(请注意,我没有启动我的应用程序。我也没有为我启用应用程序自动启动权限。有一些旧答案建议必须启用自动启动。这是错误的,即不需要)
  5. 3 分钟后出现通知!这意味着在重新启动期间,Boot BroadcastReceiver 会启动。

代码

[assembly: UsesPermission (Manifest.Permission.ReceiveBootCompleted)]
namespace MyApp.Droid
{
    [BroadcastReceiver(Name = "com.myapp.whatever.BootReceiver", Enabled = true)]
    [IntentFilter(new[] { Intent.ActionBootCompleted })]    
    public class BootReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            RescheduleNotifications();
        }

        public void RescheduleNotifications()
        {
            try
            {
                AppCenter.Start("android=cfc33334-8f5e-4ab3-1232-e8712345c860;"
                    //"ios={Your iOS App secret here}",
                    , typeof(Crashes));
                
                //Make sure all services are instantiated
                AppCore.DeviceService = new DeviceService();
                AppCore.FbService = new FBService();
                AppCore.AppService = new AppService();
                AppCore.DeviceService.ScheduleNotifications(notif.Notifications, false);
            }
            catch (Exception e)
            {
                Crashes.TrackError(e);
            }
        
        }
    }
}

我的代码注释

  • 我正在使用 MS App Center 来跟踪崩溃。您可以省略这些部分。
  • 请记住,OnReceive 是单独触发的(没有触发 Main Activity)。因此,请确保您的代码可以运行并且不会引发任何异常。
  • 在“com.myapp.whatever.BootReceiver”中,将“com.myapp.whatever”替换为您的应用程序包名称

android 清单

<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" />
<application ....>
<receiver android:enabled="true" android:name="com.myapp.whatever.BootReceiver" android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            </intent-filter>
        </receiver>
    </application>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

【讨论】:

  • 我正在尝试这种方法,我如何找到我需要替换“com.myapp.whatever”的“应用程序包名称”?它是 Visual Studio 项目名称(在我的例子中为 AutoStartupApp)和 C# 类名称的某种组合吗?我还需要包含 C# 命名空间吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-12
  • 1970-01-01
相关资源
最近更新 更多