Launch FCM services on boot without the activity - android-studio

I've followed the Firebase Quickstart Messaging Tutorial, and I've a problem.
I'd like to launch the two services (MyFirebaseMessagingService and MyFirebaseInstanceIDService) on the boot of the system.
For that, I've added the RECEIVE_BOOT_COMPLETED permission to my AndroidManifest.xml.
I've also added this to the Manifest :
<receiver android:name=".AutoStart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
In my AutoStart class, there is this :
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, MyFirebaseInstanceIDService.class));
context.startService(new Intent(context, MyFirebaseMessagingService.class));
}
The two services are nearly the same as on the links I've provided above. And my MainActivity only contains a few Views.
But it doesn't work : as soon as the services are launched, the services are automatically killed and I get a message like this in the logcat :
I/ActivityManager﹕ Killing 3100:com.company.E/u0a85 (adj 15): empty #17
I've searched for solutions about this "killing problem", and I think I've found something interesting here (about WakefulBroadcastReceiver).
If this part of the solution, I met another problem with this answer...
The onHandleIntent() override method he talks about is part of IntentService where my two services are Service.
If this is not part of the solution, I don't know how to prevent my app to be killed...

Related

ToastNotification causing error stating "you'll need a new app to open this Foo link" but app still processes response

Creating a ToastNotification using electron-windows-notifications using the following code.
let notification = new ToastNotification({
appId: app.name,
title: "title",
template: `<toast>
<visual>
<binding template="ToastText02">
<text id="1">Incoming: %s</text>
</binding>
</visual>
<actions>
<action content="Accept" activationType="protocol" arguments="Foo://accept" />
<action content="Decline" activationType="protocol" arguments="Foo://decline" />
</actions>
</toast>`,
strings: [callerid]
})
notification.on('activated', (toast, arguments) =>
{
win.show()
win.webContents.send('call-notification-response', sip, arguments)
})
notification.show()
When the ToastNotification pops up, clicking the notifcation successfully brings the app to the foreground, but clicking either accept or decline causes the you'll need a new app to open this Foo link Windows dialog to appear but the app still processes the response successfully, which suggests that Windows is having no issue finding the app
I have attempted to use both activationType="foreground" as we as activationType="background" hoping that it would stop windows believing I am opening another app but both of these just cause the actions to not appear. I attempted to remove the app name from arguments e.g. arguments="accept" this stops the error/dialog box but also stops the app from receiving the accept command. Looked through the very minimal documentation for electron-windows-notifications as well as looking into the WinRT Documentation for ToastNotifications but still can't find anything that explains this behaviour

How to start companion app on mobile from smartwatch using RemoteIntent

I have an android wear app, in which I want to have a continue on device button which launches the companion app on the mobile device.
When the App is already launched I can "restart" it using this Remote Intent.
How can I start the companion app from a standstill?
Intent intentAndroid = new Intent(Intent.ACTION_VIEW)
.addCategory(Intent.CATEGORY_BROWSABLE)
.setData(Uri.parse("myApplication"));
RemoteIntent.startRemoteActivity(context, intentAndroid, null);
Thanks in advance.
I finally figured it out.
I missed adding an intent filter in the android manifest for the activity I wanted to start.
For example:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myAppName" android:host="MainActivity" />
</intent-filter>
Then you can start it from the watch using:
Intent intentAndroid = new Intent(Intent.ACTION_VIEW)
.addCategory(Intent.CATEGORY_BROWSABLE)
.setData(Uri.parse("myAppName://MainActivity"));
RemoteIntent.startRemoteActivity(context, intentAndroid, null);

Using Trusted Web Activity to link multiple websites with native application

I've managed to link my native application to a website and launch the same on a button click. As the website is trusted, the URL bar is not visible. In the launched website there is a button which then further redirects to another website. I've created a digital asset link for both and have added the JSON file in <websitename>/.well-known/<json-file>.
Both the websites have also been referenced in strings.xml under
asset_statements. However, on launching the first website and then redirecting to the second website from the first, the second website launches as a regular custom chrome tab with the URL bar visible.
Is it possible to hide both the URL's? If so, how?
To enable multi-domain, you need to check 3 things
Each origin has a .well-known/assetlinks.json file
The android asset_statements contains all origins
Tell the Trusted Web Activity about additional origins when launching.
It seems you have the first two points covered, but not the last one.
Using the support library LauncherActivity:
If using the LauncherActivity that comes with the library, you can provide additional origins by updating the AndroidManifest:
Add a list of additional origins to res/values/strings.xml:
<string-array name="additional_trusted_origins">
<item>https://www.google.com</item>
</string-array>
Update AndroidManifest.xml:
<activity android:name="com.google.androidbrowserhelper.trusted.LauncherActivity"
android:label="#string/app_name">
<meta-data
android:name="android.support.customtabs.trusted.ADDITIONAL_TRUSTED_ORIGINS"
android:resource="#array/additional_trusted_origins" />
...
</activity>
Using a custom LauncherActivity
If using your own LauncherActivity, launching with additional origins can implemented like this:
public void launcherWithMultipleOrigins(View view) {
List<String> origins = Arrays.asList(
"https://checkout.example.com/"
);
TrustedWebActivityIntentBuilder builder = new TrustedWebActivityIntentBuilder(LAUNCH_URI)
.setAdditionalTrustedOrigins(origins);
new TwaLauncher(this).launch(builder, null, null);
}
Resources:
Article with more details here: https://developers.google.com/web/android/trusted-web-activity/multi-origin
Sample multi-origin implementation: https://github.com/GoogleChrome/android-browser-helper/tree/master/demos/twa-multi-domain

Cannot inject dependencies to Azure WorkerRole object using Spring.NET

I have moderate experience in developing web applications using spring.net 4.0 , nhibernate 3.0 for ASP.net based web applications. Recently I ran into a situation where I needed to use spring.net to inject my service dependencies which belong to the WorkerRole class. I created the app.config file as I normally did with the web.config files on for spring. Here it is for clarity. (I have excluded the root nodes)
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web" requirePermission="false" />
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" requirePermission="false" />
<section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core" />
</sectionGroup>
</configSections>
<spring>
<context>
<!-- Application services and data access that has been previously developed and tested-->
<resource uri="assembly://DataAccess/data-access-config.xml" />
<resource uri="assembly://Services/service-config.xml" />
<resource uri="AOP.xml" />
<resource uri="DI.xml"/>
</context>
<parsers>
<parser type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data" />
<parser type="Spring.Transaction.Config.TxNamespaceParser, Spring.Data" />
<parser type="Spring.Aop.Config.AopNamespaceParser, Spring.Aop" />
</parsers>
</spring>
Similarly Here's the AOP.xml
<object id="FilterServiceProxy" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
<property name="proxyInterfaces" value="Domain.IFilterService"/>
<property name="target" ref="FilterService"/>
<property name="interceptorNames">
<list>
<value>UnhandledExceptionThrowsAdvice</value>
<value>PerformanceLoggingAroundAdvice</value>
</list>
</property>
</object>
</objects>
and the DI.xml
<object type="FilterMt.WorkerRole, FilterMt" >
<property name="FilterMtService1" ref="FilterServiceProxy"/>
</object>
However, I was unable to inject any dependencies into the worker role. Can someone please let me know what I am doing wrong here ? Is there a different way to configure Spring.net DI for windows azure applications ?
I don't get any configuration errors but I see that the dependencies have not been injected because the property object to which I've tried injection, remains null.
Based on my experience, you cannot inject anything into your WorkerRole class (the class that implements RoleEntryPoint). What I do, so far with Unity (I also built my own helper for Unity to help me inject Azure settings), is that I have my own infrastructure that runs and is built by Unity, but I create it in the code for the worker role.
For example, I initialize the dependency container in my OnStart() method of RoleEntry point, where I resolve anything I need. Then in my Run() method I call a method on my resolved dependency.
Here is a quick, stripped off version of my RoleEntryPoint's implementation:
public class WorkerRole : RoleEntryPoint
{
private UnityServiceHost _serviceHost;
private UnityContainer _container;
public override void Run()
{
// This is a sample worker implementation. Replace with your logic.
Trace.WriteLine("FIB.Worker entry point called", "Information");
using (this._container = new UnityContainer())
{
this._container.LoadConfiguration();
IWorker someWorker = this._container.Resolve<IWorker>();
someWorker.Start();
IWorker otherWorker = this._container.Resolve<IWorker>("otherWorker");
otherWorker.Start();
while (true)
{
// sleep 30 minutes. we don't really need to do anything here.
Thread.Sleep(1800000);
Trace.WriteLine("Working", "Information");
}
}
}
public override bool OnStart()
{
// Set the maximum number of concurrent connections
ServicePointManager.DefaultConnectionLimit = 12;
// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
this.CreateServiceHost();
return base.OnStart();
}
public override void OnStop()
{
this._serviceHost.Close(TimeSpan.FromSeconds(30));
base.OnStop();
}
private void CreateServiceHost()
{
this._serviceHost = new UnityServiceHost(typeof(MyService));
var binding = new NetTcpBinding(SecurityMode.None);
RoleInstanceEndpoint externalEndPoint =
RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["ServiceEndpoint"];
string endpoint = String.Format(
"net.tcp://{0}/MyService", externalEndPoint.IPEndpoint);
this._serviceHost.AddServiceEndpoint(typeof(IMyService), binding, endpoint);
this._serviceHost.Open();
}
As you can see, my own logic is IWorker interface and I can have as many implementations as I want, and I instiate them in my Run() method. What I do more is to have a WCF Service, again entirely configured via DI with Unity. Here is my IWorker interface:
public interface IWorker : IDisposable
{
void Start();
void Stop();
void DoWork();
}
And that's it. I don't have any "hard" dependencies in my WorkerRole, just the Unity Container. And I have very complex DIs in my two workers, everything works pretty well.
The reason why you can't interfere directly with your WorkerRole.cs class, is that it is being instantiated by the Windows Azure infrastructure, and not by your own infrastructure. You have to accept that, and built your infrastructure within the WorkerRole appropriate methods. And do not forget that you must never quit/break/return/exit the Run() method. Doing so will flag Windows Azure infrastructure that there is something wrong with your code and will trigger role recycling.
Hope this helps.
I know this is an old question, but I'm going through the same learning curve and would like to share my findings for someone who struggles to understand the mechanics.
The reason you can't access DI in your worker role class is because this is run in a separate process in the OS, outside of IIS. Think of your WebRole class as being run in a Windows Service.
I've made a little experiment with my MVC web-site and WebRole class:
public class WebRole : RoleEntryPoint
{
public override void Run()
{
while (true)
{
Thread.Sleep(10000);
WriteToLogFile("Web Role Run: run, Forest, RUN!");
}
}
private static void WriteToLogFile(string text)
{
var file = new System.IO.StreamWriter("D:\\tmp\\webRole.txt", true); // might want to change the filename
var message = string.Format("{0} | {1}", DateTime.UtcNow, text);
file.WriteLine(message);
file.Close();
}
}
This would write to a file a new string every 10 seconds (or so). Now start your Azure site in debugging mode, make sure the site deployed to Azure emulator and the debugger in VS has started. Check that the site is running and check that WebRole is writing to the file in question.
Now stop the IIS Express (or IIS if you are running it in full blown installation) without stopping the VS debugger. All operations in your web-site are stopped now. But if you check your temp file, the process is still running and you still get new lines added every 10 seconds. Until you stop the debugger.
So whatever you have loaded in memory of web-application is inside of the IIS and not available inside of Worker Role. And you need to re-configure your DI and other services from the scratch.
Hope this helps someone to better understand the basics.

nservicebus using generic host with azure queues causes msmq error

I have an on premise service bus that is configured to handle messages from an azure queue. The problem i am having is that the host is reporting an msmq error saying that it could not create the error queue. Aside from the fact that it should not be using msmq, it also handles the messages with no problems despite the error so it does not seem to be critical.
My Host is running as a class library configured to start with the nservicebus.host.exe process.
Here is my host code and config:
internal class EndpointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
#region IWantCustomInitialization Members
public void Init()
{
Configure.With()
.DefaultBuilder()
.AzureMessageQueue()
.JsonSerializer()
.UnicastBus()
.IsTransactional(true)
.InMemorySubscriptionStorage();
}
#endregion
}
Config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
<section name="AzureQueueConfig" type="NServiceBus.Config.AzureQueueConfig, NServiceBus.Azure"/>
<section name="MessageForwardingInCaseOfFaultConfig" type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core" />
</configSections>
<MessageForwardingInCaseOfFaultConfig ErrorQueue="error" />
<AzureQueueConfig QueueName="sender" ConnectionString="UseDevelopmentStorage=true" PeekInterval="5000" MaximumWaitTimeWhenIdle="60000" />
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedruntime version="v4.0" />
<requiredruntime version="v4.0.20506" />
</startup>
</configuration>
And Here is the actual Error Message:
2012-04-24 07:57:10,973 [1] ERROR NServiceBus.Utils.MsmqUtilities [(null)] <(nul
l)> - Could not create queue error#UseDevelopmentStorage=true or check its exist
ence. Processing will still continue.
System.Messaging.MessageQueueException (0x80004005): Message Queue service is no
t available.
at System.Messaging.MessageQueue.Create(String path, Boolean transactional)
at NServiceBus.Utils.MsmqUtilities.CreateQueue(String queueName, String accou
nt)
at NServiceBus.Utils.MsmqUtilities.CreateQueueIfNecessary(Address address, St
ring account)
EDIT: Adding .MessageForwardingInCaseOfFault() to the initialization corrected the issue.
Looks like AsA_Server assumes msmq, guess you'll have to configure the process manually
Adding .MessageForwardingInCaseOfFault() to the init method resolved the issue. Still feels like there is an underlying bug, but it is working.
I suspect that below described the next hurdle (not handling errors correctly) but i will have to try to force a failed message to verify.
As described in:
NServiceBus error queues in Azure

Resources