Running activity from remote service - android

iam trying to run an activity from diffrent package from my remote service:
this is how i implement the service.java
public class CurrencyService extends Service
{
public class CurrencyServiceImpl extends ICurrencyService.Stub
{
int CALL_PUSH_SERVICE_ACTIVITY=10;
#Override
public void callSomeActivity(int activityId) throws RemoteException
{
Intent pushActivity=new Intent("com.pushservice.PushActivity");
pushActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(pushActivity);
}
.....
}
ive also added a line in the manifest of the service:
the service works fine, but i cant run the activity -> PushActivity which is in diffrent package of diffrent application,
this is the error:
Activity not found Exception: No Activity found to handle Intent {act=com.pushservice.PushServiceActivity flq=0x10
...
thanks.

You shouldn't call start activity from your service. From Android developers best practice:
Instead of spawning Activity UIs
directly from the background, you
should instead use the
NotificationManager to set
Notifications. These will appear in
the status bar, and the user can then
click on them at his leisure, to see
what your application has to show him.

You are attempting to open an Activity that has an intent-filter with an action of "com.pushservice.PushActivity". You do not have an Activity that has an intent-filter with an action of "com.pushservice.PushActivity".
The best answer is to not display an activity from a service, since users will be very irritated with you if you interrupt them when they are using the device.

Related

Why does mvvmcross close current activity when StartActivityForResult is being called?

I am new to mobile cross platform development. I am using Xamarin and Mvvmcross to create an application.
The problem I am currently faced with is that when I want to make a request to turn on a Bluetooth, calling StartActivityForResult(), my active activity is closing and after clicking on the dialog activity is not shown back.
When I used this method before on a simple Xamarin.Android applicaiton it worked as expected, showing a dialog request for turning on bluetooth while activity is on the background still active.
The similar problem is also happens when I am using an Intent to start an activity for sending an e-mail via built-in mail app. After sending an e-mail I am not redirected to my application back and my application is being suspended.
Here is my method:
[Activity(NoHistory = true, ScreenOrientation = ScreenOrientation.Portrait)]
public class MainView : MvxAppCompatActivity
{
...
protected override void OnViewModelSet()
{
base.OnViewModelSet();
...
var bluetoothAdapter = BluetoothAdapter.DefaultAdapter;
if(!bluetoothAdapter.IsEnabled)
RequestEnableBluetooth();
...
}
public void RequestEnableBluetooth()
{
Intent turnOnBtIntent = new
Intent(BluetoothAdapter.ActionRequestEnable);
StartActivityForResult(turnOnBtIntent, 0);
}
...
}
MvvmCross does nothing like that. It is Android that does this. It does not give you any guarantee that your Activity lives on when it goes into background, it may kill it off whenever it likes.
However, your problem is that you are using NoHistory = true on your Activity this way no one can return to this Activity when navigated away from it.

What kind of broadcast Receiver to use?

I have read this answer here and also this here and I'm trying to figure out what fits best for my case.
I start a Service inside onCreate() where I make an HTTP requests and I get an id as a response. I then broadcast this id and receive it in my activity.
The problem is that the user can obviously navigate to another activity just by opening the drawer and selecting an option and I can miss the broadcast.
I can obviously have all my Activities extend an abstract class which extends Activity like is mentioned here but I'm not 100% sure its the best solution. What if user decides to quit the app before I receive the id ?
Edit : app architecture
User captures an image using an Intent to open camera app and get the path of the image file.
FormActivity starts where user can add some details about the image.
User clicks upload and I pass the data user has just entered to QuizActivity.
In onCreate() of QuizActivity I start an Service where I :
create an empty entry to server and I get an id as a response and
upload image to server
That id I get as a response from server I then broadcast it.
QuizActivity has an entryIdReceiver registered where receives the id and stores it in a private field until user decides to either leave the activity or click to upload the quiz ( if he entered data for the quiz of course )
If user clicks upload I start an IntentService with the id and the quiz data.
If User opens drawer and select another Activity or clicks cancel to create a quiz I start an IntentService to upload the id with the "empty quiz data" and move user to MainActivity.
The problem is : what if uer closes app while on QuizActivity and I haven't yet receive the id, or user decides to got to another Activity using the drawer without adding a quiz. I still have to start a service and upload the id with "empty quiz data".
It's pretty good, by using abstract class, where you handle all action, and just send callback to your activity. Using that example in your question above seems to me like EventBus.
And even better using special class and interfaces, instead of abstract class, because you may want use FragmentActivity, AppCombatActivity, etc.
For example, your have your own class, which receiving result from your service and send all registered to him activities. Invoking result from net requests with interfaces:
public class NetRequestReceiver extends BroadcastReceiver {
private List<Activities> registeredActivities;
public static void getInstance () {
//Continue singleton initialing!
//....
}
#Override
public void onReceive(Context context, Intent intent) {
for (Activity act : registeredActivities) {
if (act instanceOf ReceivingCallback) {
act.onReceiveMessage(intent);
} else throw Exception("Activity missing ReceivingCallback");
}
}
public void registerActivity (Activity, activity) {
if (!registeredActivities.contains(activity)) {
registeredActivities.add(activity);
}
}
public void unRegisterActivity (Activity, activity) {
if (registeredActivities.contains(activity)) {
registeredActivities.remove(activity);
}
}
public interface ReceivingCallback {
onReceiveMessage (Intent intent);
}
}
Then in all you activities add next listener. But (!) don't forget register receiver above in you Service for receiving result!
public class MainActivity extends Activity implements NetRequestReceiver.ReceivingCallback {
public void onStop () {
super.onStop()
NetRequestReceiver.getInstance().unRegisterActivity(this);
}
public void onResume () {
super.onResume()
NetRequestReceiver.getInstance().registerActivity(this);
}
#Override
public onReceiveMessage (Intent intent) {
//put here whaterver you want your activity
//to do with the intent received
}
}
What do you think, we get, using design above? We now have single Receiver and Callback as an interface. So you can use Fragment, Activity, FragmentActivity, and other class, for receiving result from Service via Broadcast and (!) without copy pasting same behavior!
Also it's looks nice, because we split of different layer - presentation, view, and receiver. You call net request in Service. This Service send result to Broadcast, and then he sends data to all registered activities.
Yes, it's seems like EventBus, but based on your question it's just what you need for listen connection from service to different activities, and with better structure.
Maybe you can send a sticky broadcast. The system will keep it even the activity destroyed and you can receive the intent immediately when your register property
receiver.
But notice sendStickyBroadcast is deprecated and don't forget declare
android.permission.BROADCAST_STICKY
in your AndroidManifest.xml if you decide to using it.

Display Alertbox from service

Is there any way to use alertbox in service rather then making another activity for it and then starting that activity from service?
A Service cannot show a Dialog , only you can show short lived Toast from there.
But If your Requirement is of showing dialog I will not disappoint you .You have got following options:
If you have a MainActivity use a LocalBroadcastReceiver to send a broadcast to your activity and let your MainActivity show a Dialog. (This will be possible only when your activity is visible)
The other option is Define a Dialog theme activity (take a look here) in your manifest and start that activity from service.
Another option could be , Define a Activitiy in Manifest whose sole purpose would be display a Dialog and start that activity from service
Edit
I have a suggestion , If you wish to present information to your users , you should use Notification . The main reason that you cannot show a dialog from service is that Google wants information to be decently presented to its users , instead of surprising them when suppose they are in middle of a call , or typing message etc.
if the user is interested, then he will touch the notification and you start your own activity, possibly resuming your activity, creating a new one, and then using a dialog requesting action to be performed, or whatever you want to do.
Alternative Solution
However If you persist I have another solution if you like hacking, (but I don't like hacks in good application).
Create a custom Broadcast Receiver
public class MyBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// AlertDialogue will be here
}
}
Register it in the manifest file
<receiver android:name="MyBroadcastReceiver">
<intent-filter>
<action android:name="com.sample.A_CUSTOM_INTENT">
</action>
</intent-filter>
</receiver>
Trigger the BroadcastReceiver from service
Intent intent = new Intent("MyCustomIntent");
EditText et = (EditText)findViewById(R.id.extraIntent);
// add data to the Intent
intent.putExtra("message", (CharSequence)et.getText().toString());
intent.setAction("com.sample.A_CUSTOM_INTENT");
sendBroadcast(intent);

start a remote service and receive a result in Android

I have two applications.
One app has the Activity and another one is a background service.
I can able to access the service app from my activity app using implicit intent filters.
I need to receive a result from the service.
For ex:
From activity app, i am going to start the service and send a data.
In the service app, i need to receive the data and do some inspections and need to return to the activity app as modified result.
I can able to send by putExtra and can able to retrieve it in the service by getExtra. I need to return a value from service and receive it in activity app.
PS: The thing i needed is, the same way what we do with finish() and onActivityResult() with the Activity results.
Thanks in advance to you masters...
First add a class like this:
package com.test.context; //For example
public class MyContext extends Application
{
//Here you define the attributes to share through the application
// with setters and getters
}
and in the AndroidManifest.xml, add the path of the class,
in the example is com.test.context so:
<application android:name="com.test.context.MyContext"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name">
Then in your code you can do some like this:
MyContext ctx = (MyContext)getApplication();
And you will be able to share data in all the app, btw activities and services, i did it this way in a Tasker , and works fine.
Why do you want to communicate through intent while there is a perfectly working binder protocol.
http://developer.android.com/guide/topics/fundamentals/bound-services.html
If an activity starts a service with 'bindService()' then the service will run until the activity calls 'unbindService()'.

What is the cleanest way to create a GUIless application?

Good Morning.
I have a question about how to create an application without GUI. It should start when the user pushes the icon. Reading other posts, seems that the natural way of doing this would be a Service.
Since the app has no GUI, it makes no sense to add any Activity. For this reason, the Service has to be unbinded. So, if there is no component calling startService, and no external component is sending an intent, ¿how does the service start?
Is there any attribute in the manifest to achieve this? Or maybe extending Application and using onCreate to start the service?
Thanks.
UPDATES:
-There's no way to start a Service in the same app without an Intent. Other options would be autostart or Broadcast receivers, but these don't fit my requirements.
-Tried a test app without Activities, and the icon isn't even showing in the launcher. Don't know the reason of this, maybe related to the manifest not having a LAUNCHER activity.
The list of applications shown in the Android launcher is basically the list of all activities in the system that have a LAUNCHER intent filter:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
If you put this intent filter on a <service>, it will not work (just tried). Thus, the only way to do what you want to do is through an Activity. I think the cleanest way is something like this:
public void onCreate(Bundle savedInstanceState) {
Intent service = new Intent(this, MyService.class);
startService(service);
Toast.makeText(this, "Service started.", Toast.LENGTH_SHORT).show();
finish();
}
The user will not see anything except a small message at the bottom of the screen saying "Service started." that will automatically disappear in a couple of seconds. It's clean and user-friendly.
The service is started either when somebody calls startService() or when somebody calls bindService(). Note that if service is only started via bindService() it will be automatically stopped when Activity either explicitly unbinds from it or is destroyed (and it was the only binder).
You can declare BOOT_COMPLETED_ACTION broadcast receiver in your AndroidManifest.xml and start your service on system boot. But you service will only start on next device reboot. And there are some issues with applications without activities and this broadcast event in Android 3.1. More info can be found here.
In general, its good to have at least one activity in your application, even if your primary component is service. This activity will start the service when user launches it, and also may expose some ability to configure the service behavior.
Example of activity that starts service:
public class ServiceStarterActivity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
startService(new Intent(this, ServiceA.class));
finish();
}
}

Categories

Resources