what wrong with my code? - c#

My app always crashes when emulating the output shows unhandled exception.
I'm new to android and c#, so a little patience will be appreciated!!
namespace timer2
{
[Activity(Label = "timer2", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity
{
static Button start, stop;
static TextView time;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
start = FindViewById<Button>(Resource.Id.start);
stop = FindViewById<Button>(Resource.Id.stop);
time = FindViewById<TextView>(Resource.Id.textView1);
SetContentView(Resource.Layout.Main);
time.Text = "00:03:00";
Counterclass timer = new Counterclass(180000, 1000);
start.Click += delegate
{
timer.Start();
};
stop.Click += delegate
{
timer.Cancel();
};
}
public class Counterclass : CountDownTimer
{
public Counterclass(long millisInFuture, long countDownInterval) :base(millisInFuture, countDownInterval)
{
}
public override void OnFinish()
{
time.Text = "Ready";
}
public override void OnTick(long millisUntilFinished)
{
long millis = millisUntilFinished;
string hms = String.Format("%02d:%02d:%02d", TimeSpan.FromMilliseconds(millis).Hours,
TimeSpan.FromMilliseconds(millis).Minutes - TimeSpan.FromHours(TimeSpan.FromMilliseconds(millis).Hours).Minutes,
TimeSpan.FromMilliseconds(millis).Seconds - TimeSpan.FromMinutes(TimeSpan.FromMilliseconds(millis).Minutes).Seconds);
time.Text = hms;
}
}
}
}

You need to set the content view before finding the controls:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
start = FindViewById<Button>(Resource.Id.start);
stop = FindViewById<Button>(Resource.Id.stop);
time = FindViewById<TextView>(Resource.Id.textView1);

Related

Running a periodic service/ task/ function in mobile development on an android device

I am trying to collect location data from my own android phone for a project, but so far I'm not successful in letting functions run in the background.
I have tried the following:
Run repeated functions OnSleep()
This process automatically stopped after a few minutes
Use a Foreground Service with a repeated function inside of it
This is what I attempted with my Foreground Service:
AndroidManifest.xml
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
MainActivity.cs
[Activity(Label = "LocationApp", Icon = "#mipmap/icon", Theme = "#style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
public static Activity ActivityCurrent { get; private set;}
protected override void OnCreate(Bundle savedInstanceState)
{
ActivityCurrent = this;
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
RequestPermissions();
}
private async void RequestPermissions()
{
await CrossPermissions.Current.RequestPermissionAsync<StoragePermission>();
await CrossPermissions.Current.RequestPermissionAsync<LocationAlwaysPermission>();
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
TracingServices.cs
[assembly:Xamarin.Forms.Dependency(typeof(LocationApp.Droid.TracingServices))]
namespace LocationApp.Droid
{
[Service(ForegroundServiceType = Android.Content.PM.ForegroundService.TypeDataSync)]
public class TracingServices : Service,ITracingServices
{
private List<Timer> Timerlist = new List<Timer>();
private double initialLon;
private double initialLat;
public override IBinder OnBind(Intent intent)
{
throw new NotImplementedException();
}
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
if(intent.Action=="START_SERVICE")
{
Console.WriteLine("Started service");
RegisterNotification();
TrackLocation();
}
else if(intent.Action=="STOP_SERVICE")
{
Console.WriteLine("Stopping service");
StopForeground(true);
StopSelfResult(startId);
}
return StartCommandResult.NotSticky;
}
public void Start()
{
Intent startService = new Intent(MainActivity.ActivityCurrent, typeof(TracingServices));
startService.SetAction("START_SERVICE");
MainActivity.ActivityCurrent.StartService(startService);
}
public void Stop()
{
Intent stopIntent = new Intent(MainActivity.ActivityCurrent, this.Class);
stopIntent.SetAction("STOP_SERVICE");
MainActivity.ActivityCurrent.StartService(stopIntent);
// stop the timer
foreach (Timer timer in Timerlist)
{
timer.Stop();
}
}
private void RegisterNotification()
{
NotificationChannel channel = new NotificationChannel("Servicechannel", "Service demo", NotificationImportance.Max);
NotificationManager manager = (NotificationManager)MainActivity.ActivityCurrent.GetSystemService(Context.NotificationService);
manager.CreateNotificationChannel(channel);
Notification notification = new Notification.Builder(this, "Servicechannel")
.SetContentTitle("Testing service")
.SetOngoing(true)
.Build();
StartForeground(100, notification);
}
private async void TrackLocation()
{
// track initial coordinates
Location result = await Geolocation.GetLocationAsync();
initialLat = result.Latitude;
initialLon = result.Longitude;
// set timer to launch every 3 minutes
Timer timer = new Timer(3 * 60 * 1000);
timer.Elapsed += (sender, e) => OnTimedEvent(sender, e, initialLat, initialLon);
timer.AutoReset = true;
timer.Enabled = true;
Timerlist.Add(timer);
}
private static async void OnTimedEvent(object source, ElapsedEventArgs e, double lat, double lon)
{
Location result = await Geolocation.GetLocationAsync();
Console.WriteLine($"Final stuff: {result.Latitude},{result.Longitude},{result.Timestamp.DateTime:dd/MM},{result.Timestamp.DateTime:HH:mm}");
await App.Database.SaveLocationAsync(new LocationData
{
Latitude = result.Latitude - lat,
Longitude = result.Longitude - lon,
Day = result.Timestamp.DateTime.ToString("dd/MM"),
Time = result.Timestamp.DateTime.ToString("HH:mm")
});
}
}
}
MainPage.xaml.cs function
async private void ToggleTracking(object send, EventArgs args)
{
var status = await SecureStorage.GetAsync("Tracking");
// if the status starts as false, set it to true, update the button text and execute the Foreground service
if (status != "true")
{
await SecureStorage.SetAsync("Tracking", "true");
ToggleButton.Text = "Stop tracking";
DependencyService.Get<ITracingServices>().Start();
}
// if the status starts as true, set it to false, update the button text and end the Foreground service
else
{
await SecureStorage.SetAsync("Tracking", "false");
ToggleButton.Text = "Start tracking";
DependencyService.Get<ITracingServices>().Stop();
}
}
I am sure the ToggleTracking function is called, as my device displays the Foreground Service as being active, but the function isn't being executed.
Is it possible to edit the Foreground Service so that it still runs the function with an interval or is there a different option that can run functions at an interval in the background?
Changing the order of operations in the TracingServices class has caused the application to be called, though not with regular interval. Sometimes it executes, sometimes it doesn't for a few intervals. This is how I changed the order:
[Service(ForegroundServiceType = Android.Content.PM.ForegroundService.TypeDataSync)]
public class TracingServices : Service,ITracingServices
{
private List<Timer> Timerlist = new List<Timer>();
private double initialLon;
private double initialLat;
public override IBinder OnBind(Intent intent)
{
throw new NotImplementedException();
}
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
if(intent.Action=="START_SERVICE")
{
Console.WriteLine("Started service");
RegisterNotification();
}
else if(intent.Action=="STOP_SERVICE")
{
Console.WriteLine("Stopping service");
StopForeground(true);
StopSelfResult(startId);
}
return StartCommandResult.NotSticky;
}
public void Start()
{
Intent startService = new Intent(MainActivity.ActivityCurrent, typeof(TracingServices));
startService.SetAction("START_SERVICE");
MainActivity.ActivityCurrent.StartService(startService);
}
public void Stop()
{
Intent stopIntent = new Intent(MainActivity.ActivityCurrent, this.Class);
stopIntent.SetAction("STOP_SERVICE");
MainActivity.ActivityCurrent.StartService(stopIntent);
// stop the timer
foreach (Timer timer in Timerlist)
{
timer.Stop();
}
}
private void RegisterNotification()
{
NotificationChannel channel = new NotificationChannel("Servicechannel", "Service demo", NotificationImportance.Max);
NotificationManager manager = (NotificationManager)MainActivity.ActivityCurrent.GetSystemService(Context.NotificationService);
manager.CreateNotificationChannel(channel);
Notification notification = new Notification.Builder(this, "Servicechannel")
.SetContentTitle("Testing service")
.SetOngoing(true)
.Build();
StartForeground(100, notification);
TrackLocation();
}
private async void TrackLocation()
{
Console.WriteLine("Tracking called");
// track initial coordinates
Location result = await Geolocation.GetLocationAsync();
initialLat = result.Latitude;
initialLon = result.Longitude;
// set timer to launch every 3 minutes
Timer timer = new Timer(3 * 60 * 1000);
timer.Elapsed += (sender, e) => OnTimedEvent(sender, e, initialLat, initialLon);
timer.AutoReset = true;
timer.Enabled = true;
Console.WriteLine("Timer set");
Timerlist.Add(timer);
}
private static async void OnTimedEvent(object source, ElapsedEventArgs e, double lat, double lon)
{
Location result = await Geolocation.GetLocationAsync();
Console.WriteLine($"Final stuff: {result.Latitude},{result.Longitude},{result.Timestamp.DateTime:dd/MM},{result.Timestamp.DateTime:HH:mm}");
await App.Database.SaveLocationAsync(new LocationData
{
Latitude = result.Latitude - lat,
Longitude = result.Longitude - lon,
Day = result.Timestamp.DateTime.ToString("dd/MM"),
Time = result.Timestamp.DateTime.ToString("HH:mm")
});
}
}
If there is a way for the function to fire every time at an interval, I'd love to hear it.

How to set ,reset a timer using CountDownTimer class in Xamarin.Android

I made a simple Countdowntimer app for another project , I tried my best to run this simple timer to start,pause and reset the timer.My first problem was the fact that,
Since a MainActivity cannot inherit multiple classes I had to make a new one just so I can Inherit the abstract class CountDownTimer,Secondly I do not know completely that I was able to call the CountDownTimer constructor from the abstract class because I cannot intialize an abstract class only call it form within the subclass constructor .Also , I dont understand how do I wire it up with my UI.I'm completely lost in this, Can anyone help me on this?? .I have also published the code on github
GitHub : https://github.com/owais19m/TimerApp_Test
Thanks ,
Blockquote
using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Runtime;
using Android.Widget;
using Android.Content;
using Android.Telephony;
using Android.Provider;
using Android.Util;
using Java.Lang;
using System.Text.RegularExpressions;
using Xamarin.Essentials;
using System;
using Android;
using Android.Support.V4.Content;
using Android.Content.PM;
namespace TimerApp_Test
{
[Activity(Label = "#string/app_name", Theme = "#style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
private static System.Boolean mTimerRunning;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
//------------ Views -------------
Button ResetBtn = FindViewById<Button>(Resource.Id.ResetButton);
Button StartBtn = FindViewById<Button>(Resource.Id.StartButton);
TextView TimerText = FindViewById<TextView>(Resource.Id.CountdownText);
//--------------------------------
StartBtn.Click += (s, e) =>
{
if (mTimerRunning)
{
pauseTimer();
}
else
{
startTimer();
}
};
ResetBtn.Click += (s, e) =>
{
resetTimer();
};
}
public void startTimer()
{
CountDown1 Coutdwn = new CountDown1(6000,1000);
Coutdwn.OnTick(1000);
Coutdwn.Start();
mTimerRunning = true;
}
public void resetTimer()
{
}
public void pauseTimer()
{
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
public class CountDown1 : CountDownTimer
{
public static long Start_Time_Milliseconds = 600000;
public static CountDownTimer mcountDownTimer;
public static long mTimeLeftInMillis = Start_Time_Milliseconds;
public CountDown1(long mTimeLeftInMilli, long countDownInterva) : base(mTimeLeftInMilli,countDownInterva)
{
}
public override void OnFinish() { }
public override void OnTick(long millisUntilFinished)
{
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
public string updateCountDownText()
{
int minutes = (int)mTimeLeftInMillis / 1000 / 60;
int seconds = (int)mTimeLeftInMillis / 1000 % 60;
string timeLeftFormatted = string.Format("%02d:%02d", minutes, seconds);
return timeLeftFormatted;
}
public void Cancellation()
{
mcountDownTimer.Cancel();
}
}
}
Blockquote
You could pass the TextView which you would display the time as the parameter into your custom CountDownTimer like below:
[Activity(Label = "#string/app_name", Theme = "#style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
CountDown1 Coutdwn;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
//------------ Views -------------
Button ResetBtn = FindViewById<Button>(Resource.Id.ResetButton);
Button StartBtn = FindViewById<Button>(Resource.Id.StartButton);
TextView TimerText = FindViewById<TextView>(Resource.Id.CountdownText);
Coutdwn = new CountDown1(60000, 1000, TimerText);
//--------------------------------
StartBtn.Click += (s, e) =>
{
startTimer();
};
ResetBtn.Click += (s, e) =>
{
resetTimer();
};
}
public void startTimer()
{
Coutdwn.Start();
}
public void resetTimer()
{
myTimer.Cancel();
myTimer.Start();
}
public void pauseTimer()
{
myTimer.Cancel();
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
public class CountDown1 : CountDownTimer
{
TextView timeTextView;
public CountDown1(long mTimeLeftInMilli, long countDownInterva,TextView textView) : base(mTimeLeftInMilli,countDownInterva)
{
timeTextView = textView;
}
public override void OnFinish() { }
public override void OnTick(long millisUntilFinished)
{
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
public void updateCountDownText()
{
int minutes = (int)mTimeLeftInMillis / 1000 / 60;
int seconds = (int)mTimeLeftInMillis / 1000 % 60;
string timeLeftFormatted = string.Format("%02d:%02d", minutes, seconds);
timeTextView.Text = timeLeftFormatted;
}
}
Thanks, This worked great ,just regarding this, I coded a simple notification program when my timer stops in OnFinished() method in the CountDown1 class ,I get a "Java.Lang.IllegalStateException: 'System services not available to Activities before onCreate()' " error ,is there a work around for this ?
public NotificationCompat.Builder builder;
MainActivity activity = new MainActivity();
NotificationManagerCompat notificationManager;
public override void OnFinish()
{
Toast.MakeText(Application.Context ,"Finished",ToastLength.Short).Show();
builder = new NotificationCompat.Builder(this.activity, CHANNEL_ID).SetAutoCancel(true)
.SetContentTitle("CountDownTimer !!")
.SetSmallIcon(Resource.Drawable.abc_ic_star_black_48dp)
.SetContentText($" Stopped"); // display.
notificationManager = NotificationManagerCompat.From(this.activity); Error // Java.Lang.IllegalStateException: 'System services not available to Activities...
notificationManager.Notify(NOTIFICATION_ID, builder.Build());
}

java.lang.IllegalArgumentException: No such service ComponentInfo{/com.SampleApp.AttendanceApp.ServiceClass}

I am using Xamarin Android to build an app which should allow the app to keep sending a driver's location every 15 minutes so that I can keep track of his movement. I used JobScheduler to get this done. My project is very simple now and only contains the following 3 files:
MainActivity.cs
AttendancePage.cs (Content page, interact with UI button to start the service)
ServiceClass.cs
Methods in Main Activity.cs
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
scheduler = (JobScheduler)GetSystemService(JobSchedulerService);
LoadApplication(new App()); //This line will then jump to AttendancePage.cs
}
public void ScheduleJob()
{
ComponentName componentName = new ComponentName(this, Java.Lang.Class.FromType(typeof(ServiceClass)));
JobInfo info = new JobInfo.Builder(123, componentName)
.SetPersisted(true)
.SetPeriodic(60000)
.Build();
int resultCode = scheduler.Schedule(info); //The error show when hit this line.
if (resultCode == JobScheduler.ResultSuccess)
{
Log.Info("Message", "Job Schedule!");
}
else
{
Log.Info("Message", "Job shceduling failed");
}
}
public void CancelJob()
{
scheduler.Cancel(123);
}
AttendancePage.cs
public partial class AttendancePage : ContentPage
{
MainActivity main = new MainActivity();
public AttendancePage()
{
InitializeComponent();
Title = "Attendance App";
}
//Button OnClickEvent
async void ScheduleJob(object s, EventArgs e)
{
main.ScheduleJob();
}
//Button OnClickEvent
async void CancelJob(object s, EventArgs e)
{
main.CancelJob();
}
}
ServiceClass.cs
[Service(Name = "com.SampleApp.AttendanceApp.ServiceClass", Permission = "android.permission.BIND_JOB_SERVICE")]
public class ServiceClass : JobService
{
public ServiceClass()
{
}
public override bool OnStartJob(JobParameters jobParamsOnStart)
{
doBackgroundWork(jobParamsOnStart);
return true;
}
private void doBackgroundWork(JobParameters jobParam)
{
//My code to send driver's location
TestingPage.GetGPS();
JobFinished(jobParam, false);
}
public override bool OnStopJob(JobParameters jobParamsOnStop)
{
return false;
}
}
I have added the service tag inside AndroidManifest.xml as well.
<service android:name=".ServiceClass"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true" />
I have no idea why the error is still there. The error is from the line scheduler.Schedule(JobInfo). Anyone has another possible solution? I am frustrated on solving this. Will the reason be I can't debug on the service but only can straight away run in release mode? Please help.
Froms shared code it works in Xamarin.Android project , however here is a Xamarin.Forms project . It can not work.
In AttendancePage.cs , you create a new MainActivity to invoke the native method ScheduleJob and CancelJob . This will not find the JobScheduler in native ,then it will return null .
No such service ComponentInfo{/com.SampleApp.AttendanceApp.ServiceClass}
If you want to invoke native method , you can have a try with DependencyService in Xamarin Forms .
At least need to create a Interface in Forms to invoke :
public interface IJobSchedulerService
{
//Start JobSchedule
void StartJobSchedule();
//Cancel JobSchedule
void CancelJobSchedule();
}
Then can invoke in Xamarin Forms as follow :
async void ScheduleJob(object s, EventArgs e)
{
DependencyService.Get<IJobSchedulerService>().StartJobSchedule();
}
//Button OnClickEvent
async void CancelJob(object s, EventArgs e)
{
DependencyService.Get<IJobSchedulerService>().CancelJobSchedule();
}
Now you need to implement the IJobSchedulerService in native android .Create the JobSchedulerDependcenyService:
public class JobSchedulerDependcenyService : IJobSchedulerService
{
JobScheduler jobScheduler;
public JobSchedulerDependcenyService()
{
jobScheduler = (JobScheduler)MainActivity.Instance.GetSystemService(Android.Content.Context.JobSchedulerService);
}
public void StartJobSchedule()
{
ComponentName componentName = new ComponentName(MainActivity.Instance, Java.Lang.Class.FromType(typeof(DownloadJob)));
JobInfo jobInfo = new JobInfo.Builder(1, componentName)
.SetOverrideDeadline(0)
.Build();
//var jobScheduler = (JobScheduler)GetSystemService(JobSchedulerService);
var scheduleResult = jobScheduler.Schedule(jobInfo);
if (JobScheduler.ResultSuccess == scheduleResult)
{
var snackBar = Snackbar.Make(MainActivity.Instance.FindViewById(Android.Resource.Id.Content), "jobscheduled_success", Snackbar.LengthShort);
snackBar.Show();
}
else
{
var snackBar = Snackbar.Make(MainActivity.Instance.FindViewById(Android.Resource.Id.Content), "jobscheduled_failure", Snackbar.LengthShort);
snackBar.Show();
}
}
public void CancelJobSchedule()
{
jobScheduler.CancelAll();
}
}
Here you will find the MainActivity.Instance inside it , that's a static instance defined by self in MainActivity.
public static MainActivity Instance { set; get; }
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Instance = this;
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}

Xamarin Android Background Service crashes when the Application get closed

Hello, I want to build an app, in which you can start a service, which runs intependenly and creates a notification, and this service should constantly proof, if the DateTime.Now.Date is bigger than a spezific Date.
When I execute the code below, the notification gets displayed, but when I am closing the app, a few secondes later I get two times an information that the app crashed and I dont know why.
I cant even debug the code because this anly happens when the application is closed....
I hope you can help me thanks!
Here is my code:
namespace App
{
[Activity(Label = "App", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity
{
int count = 1;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
Button button = FindViewById<Button>(Resource.Id.MyButton);
button.Click += delegate {
button.Text = string.Format("{0} clicks!", count++);
StartService(new Intent(this, typeof(backgroudservice)));
};
}
}
public class backgroudservice : Service
{
public override IBinder OnBind(Intent intent)
{
return null;
}
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
newnotification("Title", "Text: ", 0);
new Task(() => {
DoWork();
Thread.Sleep(1000);
}).Start();
return StartCommandResult.Sticky;
}
public void DoWork()
{
if (DateTime.Now.Date > Convert.ToDateTime("2016-03-29").Date)
{
cancelnotification(0);
StopSelf();
}
}
public override void OnDestroy()
{
base.OnDestroy();
cancelnotification(0);
}
private void newnotification(string titel, string text, int id)
{
Notification.Builder builder = new Notification.Builder(this)
.SetContentTitle(titel)
.SetContentText(text)
.SetSmallIcon(Resource.Drawable.droidlogo_small)
.SetAutoCancel(false)
.SetVisibility(NotificationVisibility.Public)
.SetContentIntent(PendingIntent.GetActivity(this, 0, new Intent(this, typeof(MainActivity)), PendingIntentFlags.OneShot));
// Build the notification:
Notification notification = builder.Build();
notification.Flags = NotificationFlags.NoClear;
//notification.ContentIntent = new Intent(this,typeof(login));
// Get the notification manager:
NotificationManager notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;
// Publish the notification:
notificationManager.Notify(id, notification);
}
private void cancelnotification(int id)
{
NotificationManager notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;
notificationManager.Cancel(id);
}
}
}
I solved it, I forgot the [Service] above my class, now it works!
[Service]
public class backgroudservice : Service
{
...
}
You might try moving the call to cancelnotification in your service's OnDestroy to before the call to the base method, i.e.:
public override void OnDestroy()
{
cancelnotification(0);
base.OnDestroy();
}

Android OnActivityResult not being called (C#, Xamarin)

I am having quite an interesting issue. Let me emphasize that I haven't been programming much for android and it seems I might have gone off track somewhere.
My problem is the triggering of the event onActivityResult(). I have read the Xamarin receipies but somehow it does not work. The routine does not get called in the MainActivity.
I even tried to do a similar example on java, and there it worked like a charm.
So, now to business. I have a MainActivity, which can start the Configuration Activity. This activity is supposed to collect the IP from the server (user manually puts it in), and return the String back to MainActivity. Fair and simple.
MainActivity code snippet:
[Activity(Label = "Test", MainLauncher = true, Icon = "#drawable/ax")]
public class MainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
setBindigs();
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
switch (resultCode)
{
case Result.Ok:
//do something
break;
}
}
private void setBindigs()
{
ImageView ax = FindViewById<ImageView>(Resource.Id.ax);
ax.Click += HandleImageClick;
}
private void HandleImageClick(object sender, EventArgs e)
{
var conf = new Intent(this, typeof(Configuration));
StartActivityForResult(conf, Convert.ToInt32(Result.Ok));
}
And the Configuration snippet:
[Activity(Label = "Configuration")]
public class Configuration : Activity
{
private Button[] Connects;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Configuration);
setBindigs();
}
private void setBindigs()
{
const int KeyboardLength = 2;
Connects = new Button[KeyboardLength];
for (int I = 0; I < KeyboardLength; ++I)
{
Connects[I] = FindViewById<Button>(Resource.Id.ConnectButton + I);
Connects[I].Click += HandleKeyboardClick;
}
}
private void HandleKeyboardClick(object sender, EventArgs e)
{
Button Clicked = sender as Button;
Result ActivityResult = Result.Ok;
String IpText = String.Empty;
switch(Clicked.Id)
{
case Resource.Id.ConnectButton:
EditText IP = FindViewById<EditText>(Resource.Id.ServerIP);
IpText = IP.Text;
break;
case Resource.Id.DisconnectButton:
ActivityResult = Result.Canceled;
break;
}
Intent myIntent = new Intent (this, typeof(MainActivity));
myIntent.PutExtra ("IP", IpText);
SetResult (Result.Ok, myIntent);
Finish();
}
Would you have any ideas? In java I used the option getIntent(); instead of Intent myIntent = new Intent (this, typeof(MainActivity));
I have just found the problem in my code. For future reference, here is what seems to be the problem:
When calling StartActivityForResult() I used the arguments StartActivityForResult(conf, Convert.ToInt32(Result.Ok));. It seems that the expected result should not be passed as Convert.ToInt32(Result.Ok) but rather as a 0.
This solved my problem

Categories