startActivity within a subclass of Application - android-activity

I have a little Android application in which I specify my application directly and do some application-wide setup in the ApplicationSubclass' onCreate, but I am getting the following error (Note, I know about FLAG_ACTIVITY_NEW_TASK):
Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
at android.app.ContextImpl.startActivity(ContextImpl.java:644)
at android.content.ContextWrapper.startActivity(ContextWrapper.java:258)
at somePart.ofA.nameSpace.ApplicationSubclass.sendNotificationEmail(ApplicationSubclass.java:186)
I am calling this sendNotificationEmail when some exceptions are thrown and I catch them, so that the user of the app can send in a little e-mail with information on the exception so that I can more easily fix anything that might arise or guide them on fixing their issue.
Here is some of the relevant code:
manifest.xml:
<application android:label="#string/app_name" android:icon="#drawable/icon" android:name=".ApplicationSubclass">
// ... some stuff, including all of my app's activities
</application>
the ApplicationSubclass is defined as:
public class ApplicationSubclass extends Application {
// Multiple methods, including an override of onCreate
public void sendNotificationEmail(String emailBody) {
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
emailIntent.setType("text/html");
emailIntent.putExtra(Intent.EXTRA_EMAIL, notificationRecipients);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "MyAppName Error");
emailIntent.putExtra(Intent.EXTRA_TEXT, emailBody);
try {
startActivity(Intent.createChooser(emailIntent, "An error has occurred! Send an error report?"));
} catch (ActivityNotFoundException e) {
// If there is nothing that can send a text/html MIME type
e.printStackTrace();
}
}
}
I'd like to know why this is happening. I read some documentation, I looked for some answers on StackOverflow and the Internet at large. It seems to me that I should be fine since I am setting FLAG_ACTIVITY_NEW_TASK, however that's clearly not the case!
Is it simply that I may not even attempt to do this from the Application's context? Must I be within a Activity in my application when I attempt this? It would be sort of annoying to need to re-engineer around this, and being able to send exception e-mails would be quite useful!
EDIT: Rich asked a good question, and that's why the heck would I want to be doing this in the first place? The answer is simply that there is data being loaded in the Application that could fail, and I'd like the user to be able to send some of that failure data when this occurs.
The reason this is in the Application and not the activity is that there are application state variables I don't want to lose every time someone rotates the device. When I found out about the fact that onPause and onCreate are called when you rotate (for Activies) I refactored this code out into the Application (which works great!). I had actually tried the solution to send these to onConfigurationChanged and Override that method in my activity, but that's messy and for whatever reason despite putting android:configChanges="keyboardHidden|orientation" in my manifest it wasn't correctly working for me. I'm sure I could pursue this option, but I'd rather leave things as they are (it's cleaner) and get the ability for someone to e-mail!

Ah! I figured out what I did, it's quite simple! I was setting the FLAG_ACTIVITY_NEW_TASK on the wrong intent! Silly me, I missed that Intent.createChooser(...,...) will return a new Intent, so you must set the flag on the chooser Intent rather than on the ACTION_SEND Intent.
Not all that confusing when you think about it, and I can't believe I overlooked that!
So if anyone ever does what I did, here you go:
public void sendNotificationEmail(String emailBody) {
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("text/html");
emailIntent.putExtra(Intent.EXTRA_EMAIL, notificationRecipients);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "MyAppName Error");
emailIntent.putExtra(Intent.EXTRA_TEXT, emailBody);
Intent emailChooser = Intent.createChooser(emailIntent, "An error has occurred! Send an error report?");
emailChooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
startActivity(emailChooser);
} catch (ActivityNotFoundException e) {
// If there is nothing that can send a text/html MIME type
e.printStackTrace();
}
}

I have launch an activity(to relogin the user when loss the session) from my class which subclass from Application as follow:
public boolean relogin(Activity act) {
Intent intent = new Intent(act,ActivityLogin.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
act.finish();// here i finish my current activity
}

Related

Grails async mail plugin with DatabaseMessageSource

In my Grails application, there is a requirement to allow different text to be shown to users on a per 'organisation' basis, but to fall back to reading the text from messages.properties if no overriding text is defined for an organisation.
I'm using an approach similar to the one detailed here, which works well in the scope of an http request, however I now also need to define email content on a per organisation basis which is a bit problematic as emails are sent asynchronously (using the async mail plugin). My current resolveCode() implementation looks like this:
public MessageFormat resolveCode(String code, Locale locale) {
Message msg = null
try {
Organisation currentOrganisation = currentOrganisationSessionProxy.currentSessionOrganisation
msg = Message.findByCodeAndLocaleAndOrganisation(code, locale, currentOrganisation)
} catch (Exception e) {
//handle exception
}
def format
if (msg) {
format = new MessageFormat(msg.text, msg.locale)
} else {
format = messageBundleMessageSource.resolveCode(code, locale)
}
return format
}
I've modified the DatabaseMessageSource implementation slightly as I need to resolve the current 'session' organisation using a session-scoped proxy.
Can anyone suggest a good approach for sending localized, organisation-specific emails asynchronously? I guess I would need to persist the organisation id along with the email, and then retrieve it some how in my DatabaseMessageSource. Any help is appreciated.
This actually turned out to be simpler than I thought. I didn't need to modify the async mail plugin, but I did need to override the ValidationTagLib g:message implementation so that I could pass in an organisationId. I also needed to provide alternate implementations of AbstractMessageSource.getMessage methods that also took an organisationId argument.

How can I determine why onFailure is triggered in GWT-RPC?

I have a project that does 2 RPC calls and then saves the data that the user provided in tha datastore. The first RPC call works ok, but from the second I always recieve the onFailure() message. How can I determine why the onFailure() is triggered? I tried caught.getCause() but it doesn't return anything.
feedbackService.saveFeedback(email,studentName,usedTemplates,
new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
caught.getCause();
Window.alert("Failure!");
}
public void onSuccess(String result) {
Window.alert("Saved!");
}
});
Throwable instance is instance of an Exception. You can check if it is a custom Exception like this:
if (caught instanceOf CustomException){
or if you want to show the message of exception you can use the getMessage():
Window.alert("Failure: " + caught.getMessage());
GWT-rpc is not not easy to ebug if an error occurs.
The easiest part is th check if the Exception is part of StatusCodeException.
A Statuscode of 404 means, you are pointing to a wrong endpoint
0 means, that
The searver is unreachable
You don't have permissions to check, if the server is available (X-domain-request)
You can use the Chrome-Web-Inspector to bedug GWT-RPC
You should be able to see all calls from the browser to you backend.
The most common failures are because of serialization of object. You have to ensure, that all dtransferred object implement java.io.Serializable
Most of the time it will just be a server side exception being raised which fires the onFailure() method.
Try putting breakpoints on your server side. That should help you pinpoint what's going wrong.

Overrided broadcast(Object message, GwtAtmosphereResource resource) method in Atmosphere with GWT not working

We are trying to handle a scenario that when a user in quitting a room ,we send a message using MetaBroadcaster to all room .We implemented this feature by override broadcast method of AtmosphereGwtHandler .
The feature is good when we testing in development mode, but when we test it in Jetty8 production mode, telling by log, the override method is void which never get called.
So anybody know what's wrong with it, or do we have a better solution to this feature.
here is our code snippet:
public class ChatHandler extends AtmosphereGwtHandler {
...
#Override
public void broadcast(Object message, GwtAtmosphereResource resource) {
MsgType msgtype=((ChatMessage)message).getMsgtype();
if(msgtype==MsgType.Broad){
MetaBroadcaster.getDefault().broadcastTo(((ChatMessage)message).getChanel(), message);
System.out.println("Doing to all room);
}else{
super.broadcast(message, resource);
System.out.println("Doing to myself);
}
}
}
Can't really give an answer on the info provided.
Where have you configured your handler?
web.xml or atmosphere.xml
What servlet are you using Meteor/Atmosphere?
What version of Atmosphere?

Send a empty Message or Notification with MVVM toolkit light

I'm using the MVVM Light Toolkit. I could not find any Ctor of Messenger or Notification class to send a empty message.
ViewModel1:
private int _selectedWeeklyRotation;
public int SelectedWeeklyRotation
{
get { return _selectedWeeklyRotation; }
set
{
if(_selectedWeeklyRotation == value)
return;
_selectedWeeklyRotation = value;
this.OnPropertyChanged("SelectedWeeklyRotation");
if(value > 1)
Messenger.Default.Send();
}
}
ViewModel2:
Ctor:
Messenger.Default.Register(this, CreateAnotherTimeTable);
private void CreateAnotherTimeTable()
{
}
I just need to send a Notification to another ViewModel, no sending of data at all.
Is that possible with MVVM Light Toolkit library?
Unless I'm misunderstanding something, couldn't you accomplish this by creating and sending a custom "signal message" type via the Messenger?
public class WeeklyRotationSignal {}
Messenger.Default.Send(new WeeklyRotationSignal());
Then register to that in another view model:
Messenger.Default.Register<WeeklyRotationSignal>(this, msg => doWork);
You can try sending a simple message with a string tag and receive that message by matching the string tag. Something like this:
Sender portion of the code located possibly in something like ViewModel1.cs
Messenger.Default.Send<string>("Dummy text message", "String_ToHelpMatchTheMsg");
Receiving end portion of the code responding to that message above, possibly located in some other file, something like ViewModel2.cs
...
Messenger.Default.Register<string>(this, "String_ToHelpMatchTheMsg", executeThisFunction);
private void executeThisFunction(string strMsg)
{
//your code would go here to run upon receiving the message
// The following line will display: "Dummy text message"
System.Windows.Browser.HtmlPage.Window.Alert("msg passed: " + strMsg);
}
Please note that you dont have to do anything with the text message that is passed around with the messaging code above. Just one part of the code sending some ping to another part of the code to ask some other section to execute some code. The important string is the one where I used "String_ToHelpMatchTheMsg" because that is the key used to match the sender and the receiver. Almost like creating your own quasi-event, once the Send method runs, the Register method is notified and fire its own function to run also.
I used this with a Close button on a Child Window to close it. The Close button on the View of the Child Window binds to a relay command on its childWindowViewModel. That relay command has the code above to send a message to the ParentViewModel. The Register portion on the ParentViewModel responds to that message by firing a method that closes the ChildWindow which was initially instantied from that parentViewModel.
Once you get more familiar with messaging, there are more attributes that you will be able to use so that the receiver can call back the sender to give a status or some data back. Look for Delegates and lambda function to achieve this.
All this to avoid placing code in the code behind to close the child window! :-)
Use as you see fit.
Cheers.
Mario
There really isn't a way to accomplish this and in someways defies the point of the messenger class. I didn't want to write a your doing it wrong post, but I feel I am stuck. The way the messenger class works is that you have two parties that both subscribe to the same concept, its an observer model. Without that similar concept or message there really isn't a way to tie the two objects together. The generic message whether a simple string or custom message act as the meeting point of the Subscribing and Publishing classes.
If the ViewModel publishing knows the type of ViewModel its trying to Send to it could...
Messenger.Default.Send<Type>(typeof(ViewModelToSendTo);
This would act as a very simple interaction point, you also wouldn't have to create a custom class. Some purist may have an issue with this approach as it couples the publishing class to the subscriber.
I don't think that it is possible and frankly I don't see the point of having that kind of message. You could just as well send a string "SelectedWeeklyRotation". It seems strange to have an empty message that has some kind of meaning as you increase the number of broadcast messages - and receivers in your application.
In the version of MVVM Light that I'm using it is not even possible to send an empty message.
However I did see a method in the ViewModelBase that is :
// Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
RaisePropertyChanged(MyPropertyPropertyName, oldValue, value, true);
This might be of interest for you.

Properly disposing resources used by SmtpClient

I have a C# service that runs continuously with user credentials (i.e not as localsystem - I can't change this though I want to). For the most part the service seems to run ok, but ever so often it bombs out and restarts for no apparent reason (servicer manager is set to restart service on crash).
I am doing substantial event logging, and I have a layered approach to Exception handling that I believe makes at least some sort of sense:
Essentially I got the top level generic exception, null exception and startup exception handlers.
Then I got various handlers at the "command level" (i.e specific actions that the service runs)
Finally I handle a few exceptions handled at the class level
I have been looking at whether any resources aren't properly released, and I am starting to suspect my mailing code (send email). I noticed that I was not calling Dispose for the MailMessage object, and I have now rewritten the SendMail code as illustrated below.
The basic question is:
will this code properly release all resources used to send mails?
I don't see a way to dispose of the SmtpClient object?
(for the record: I am not using object initializer to make the sample easier to read)
private static void SendMail(string subject, string html)
{
try
{
using ( var m = new MailMessage() )
{
m.From = new MailAddress("service#company.com");
m.To.Add("user#company.com");
m.Priority = MailPriority.Normal;
m.IsBodyHtml = true;
m.Subject = subject;
m.Body = html;
var smtp = new SmtpClient("mailhost");
smtp.Send(m);
}
}
catch (Exception ex)
{
throw new MyMailException("Mail error.", ex);
}
}
I know this question is pre .Net 4 but version 4 now supports a Dispose method that properly sends a quit to the smpt server. See the msdn reference and a newer stackoverflow question.
There are documented issues with the SmtpClient class. I recommend buying a third party control since they aren't too expensive. Chilkat makes a decent one.