Xamarin Android 后台一直运行 后台定位

一、开发环境:

VS2019-16.10.0

Xamarin-16.10.000.228

Xamarin.Android SDK-11.3.0.1

荣耀20Pro真机调试

二、预实现目的

使程序可以一直保持后台运行,进行定位,并且程序可以开机自启。

三、详细方法

原理:通过创建前台服务的方式保持App处于活动状态。

1.AndroidManifest.xml配置权限

   <application android:label="MyTest" android:theme="@style/MainTheme" android:icon="@drawable/icon" android:debuggable="true" android:allowBackup="true">
		<!--前台服务想要调用定位功能,必须加上这个;服务名字前面要加上命名空间,MyTest.Droid就是我的服务类所在命名空间-->
		<service android:name="MyTest.Droid.GaodeService" android:foregroundServiceType="location" />
	
	</application>


    <!--允许程序打开网络套接字-->
	<uses-permission android:name="android.permission.INTERNET" />
	<!--允许程序设置内置sd卡的写权限-->
	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
	<!--允许程序获取网络状态-->
	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
	<!--允许程序访问WiFi网络信息-->
	<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
	<!--允许程序读写手机状态和身份-->
	<uses-permission android:name="android.permission.READ_PHONE_STATE" />
	<!--允许程序访问CellID或WiFi热点来获取粗略的位置-->
	<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
	<!--用于访问GPS定位-->
	<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
	<!--这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
	<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
	<!--这个权限用于允许程序在手机屏幕关闭后后台进程仍然运行-->
	<uses-permission android:name="android.permission.WAKE_LOCK" />
	<!--用于申请获取蓝牙信息进行室内定位-->
	<uses-permission android:name="android.permission.BLUETOOTH" />
	<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
	<!--用于申请调用A-GPS模块-->
	<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
	<!--用于创建前台服务-->
	<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

2.创建通知管道

创建最简单最粗略的通知管道的方法,主要的参数是管道id,创建通知时要使用

public static void CreateNotificationChannel(Context context, string channelID, string channelName)
        {
            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
            {
                ((NotificationManager)context.GetSystemService(Context.NotificationService))
                            .CreateNotificationChannel(new NotificationChannel(channelID, channelName, NotificationImportance.Default));
            }
        }

3.创建通知

下面是创建通知的简化方法, 一个通知标题,文本,图标,一个前台服务貌似必须设置为True的项, 通知管道id在NotificationCompat.Builder构造函数填入

public static Notification CreateServerNotification(string contentTitle, string contentText, Context context, string channelID)
        {
            return new NotificationCompat.Builder(context, channelID)
                               .SetContentTitle(contentTitle)
                               .SetContentText(contentText)
                               .SetSmallIcon(Resource.Mipmap.icon)
                               .SetOngoing(true)
                               .Build();
        }

4.开启服务的方法

android 8.0及以上版本开启前台服务需要使用StartForegroundService,这个方法可以放在你想要调用服务的类中,比如MainActivity

public static void StartServer(Context context, Intent intent)
        {
            context.StartForegroundService(intent);
        }

5.声明服务

[Service]  //此处Service不可写成Service(IsolatedProcess=true),否则普通调用服务方法不起作用
    public sealed class MyServer : Service
    {
        
        public override void OnCreate()
        {
            base.OnCreate();

            //此处在第一次调用服务,即服务创建时触发,第二次及以后再调用不会再触发
            const int NOTIFICATION_ID = 345;

            const string CHANNEL_ID = "自己起一个id";

            const string CHANNEL_NAME = "自己起一个name";

            CreateNotificationChannel(this, CHANNEL_ID, CHANNEL_NAME);

            var notification = CreateServerNotification("标题", "内容", this, CHANNEL_ID);

            StartForeground(NOTIFICATION_ID, notification);
        }


        [return: GeneratedEnum]
        public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
        {
               //此处可添加自己想要通过前台服务做的事情,比如后台定位功能,每次调用服务都会触发
               //startlocation()
            return StartCommandResult.RedeliverIntent;  //此返回值可以在服务被终止时尝试重启服务,并可传回当时的Intent
        }


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

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

6.在MainActivity中调用服务

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, IAMapLocationListener
    {

//...

 protected override void OnStart()
        {
            base.OnStart();
           Intent serviceToStart = new Intent(this, typeof(MyServer));
           StartServer(this, serviceToStart);
           
        }
 public static void StartServer(ContextWrapper context, Intent intent)
        {
            if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
            {

                context.StartForegroundService(intent);

            }
            else
            {
                context.StartService(intent);
            }
        }

//...

}

四、注意事项

服务本身还会受到下面一些因素的影响

1.是否允许后台活动,

2.是否忽略电池优化

3.针对荣耀机型,

1>可以在“手机管家-应用启动管理”中设置应用手动管理,允许后台运行。

2>打开应用后,在手机任务列表视图中,下拉app界面,app右上角会有小锁图标出现,手机就会把app加入保护列表,不会随便杀死该app。


参考连接:

Xamarin Android 创建前台服务的个人粗略总结 - 雷开封 - 博客园 (cnblogs.com)

服务概览  |  Android 开发者  |  Android Developers (google.cn)

Foreground services  |  Android 开发者  |  Android Developers (google.cn)

Xamarin.Android服务的实现 - y-z-f - 博客园 (cnblogs.com)

相关说明: ConsoleApplication1_sERVER ----PC-服务端 MyNetTest --------------------IOS-客户端 1、PC-服务端 只是一个运行在windows系统下的 控制台程序。接收来自客户端的信息。 2、IOS-客户端 运行在ios模拟器上,连接PC服务端的ip,发生相关信息。 3、两台主机,一台是运行windows系统的计算机。另外一台是MacBook计算机。运行ios模拟器。 4、pc-服务端,可以用vs2008打开并且编辑。 5、ios客户端,使用的是XamarinStudio 打开并且编辑。 以下是这个例子中的特别提到的地方 A、这个例子是完全用C#写的。 B、ios由于是伪后台,当程序退回到后台,系统留给程序的可运行时间就只有3分钟。 过了3分钟,就会把这个程序的所有线程挂起(当然内部预留了长任务运行这一后招)。 经过多次试验后,可以借助着3分钟的长任务运行,然后通过简单的修改来突破这个界限。 在本例子中,所有线程共享一个线程ID。 其中只需要一条线程负责不停的延长这个线程ID的运行时间,然后其他的线程就只需要专注于其本应该要做的任务即可。 C、本例子中,还实现了另外一个功能,就是ios程序与PC程序进行socket。当然是最为简单的。 ---------------- 由于本人也是刚刚使用c#开发ios程序,初入门,为了这两个问题,也是研究了很久,可查的资料又很少。 希望能够帮助到同样遇到困难的你。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值