How would it be possible to create a private service? I mean my
custom service should not be accessible by other applications? What
parameters I should define in AndroidManifest.xml ?
Simply do not include an <intent-filter>. Then your service will only be accessible by components within your application. You would use an explicit Intent to interact with it (e.g., new Intent(this, MyPrivateService.class)).
As commonsware told that is a great answer.Also you can do in menifest also like this :
android:exported="false"
Related
I am building a Chromecast Android sender app that needs to have two receiver apps, one of type Default / Styled Receiver App and the other as Remote Display.
I am setting the CastOptionsProvider for my app in my AndroidManifest.xml as :
<meta-data
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="com.myapp.CastOptionsProvider" />
CastOptionsProvider.xml
class CastOptionsProvider : OptionsProvider {
override fun getCastOptions(context: Context): CastOptions {
// ... Other details
return CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.remote_app_id))
.setCastMediaOptions(mediaOptions)
.build()
}
//...other implementations
}
Since this class is not instantiated by me but by the SDK itself, how can I put receiver IDs for both the receiver apps here ?
R.string.remote_app_id is the place where I need to put receiver ids for both the apps.
Even if I create two options provider classes, one for each type, is it possible to put both the classes as meta-data in AndroidManifest.xml
I posted the same question on Github at Castvideo-android and got the following reply from Leon Nicholls
Only one receiver ID is supported by the Cast SDK.
Also, we highly recommend that you don't use the Remote Display API anymore since it is deprecated.
So in conclusion, it's not supported as of now.
I have two applications, one works as a main app, and the another as a service.
In the service app manifest file, I configure a service like:
<service android:name=".services.FirstService">
<intent-filter>
<action android:name="ch.service.action.FIRST_SERVICE"/>
</intent-filter>
</service>
And in the main app, I start a service like:
Intent intent = new Intent("ch.service.action.FIRST_SERVICE");
startService(intent);
Here, I have to duplicate "ch.service.action.FIRST_SERVICE".
How can I avoid this?
How can I share some common constants, for example define one in service app, and can be retrieve in main app?
Any answer is appreciated.
You should use SharedPreference between both of your application. In your Service application you should write the String ch.service.action.FIRST_SERVICE to SharedPreference :
SharedPreference sharedPreferences = getSharedPreferences("any_name", Context.MODE_WORLD_READABLE);
SharedPreference.Editor mEditor = sharedPreferences.edit();
mEditor.putString("service_string","ch.service.action.FIRST_SERVICE");
mEditor.commit();
When you want to get the value from other application, you first need to get Context of your service application :
Context mServiceAppContext = createPackageContext("com.example.service_app_package", 0);
You can use mServiceAppContext to get the String value :
SharedPreference sharedPreferences = mServiceAppContext.getSharedPreferences("any_name", Context.MODE_WORLD_READABLE);
// Context.MODE_WORLD_READABLE is important, it makes the value readable across other applications
sharedPreferences.getString("service_string", /* default value */ "service_string","ch.service.action.FIRST_SERVICE");
Best Explaination is given at : http://thedevelopersinfo.com/2009/11/25/getting-sharedpreferences-from-other-application-in-android/
for something like this you have to create a library project and include it to both your main and service application and define your name in the library you included. Hope this helps, not sure if there is any other better way :)
If you can merge two applications together, certainly you can share anything you want. Actually one application can contains many service and intent service.
If you have some reason to separate one application into two, or they are two irrelevant apps, using intent to communicate always need class name which is unavoidable I think.
There are different ways to archive the same thing, but why not keep it simple:
Do you have a reference to the service project? if it so, why not just create a setting in the service project and reuse it on the main one when create the intent:
Intent intent = new Intent(cxt.getString("service_string", default value));
or, like I did in my apps, just create a public static final variable on the service class and access it from the main app?
public static final String ACTION_FIRST_SERVICE = "ch.service.action.FIRST_SERVICE";
If you don't have a reference to the service project and don't want to add, the best way is to expose it to anyone ... or create a lib project that both use
Do I need to fill out the 'receiver ... /receiver' content in AndroidManifest.xml if I register a BroadcastReceiver dynamically using 'registerReceiver(mReceiver, pIntentFltr)' and unregisterReceiver(mReceiver). It seems like I don't need it.
No, you don't need it. The mechanisms complement each other, as stated in the documentation:
There are two ways to make a broadcast receiver known to the system: One is declare it in the manifest file with this element. The other is to create the receiver dynamically in code and register it with the Context.registerReceiver() method
My Service is only working if I have the MyService.java in a package like
com.test.app
, but NOT in a subpackage like
com.test.app.services.MyService
In the manifest I tried declaring it with
<service android:name=".services.MyService" />
or fully qualified
<service android:name="com.test.app.services.MyService" />
but neither way worked. I am using subpackages for a better structure of my files. So can I really not put my service file in a subpackage or am I missing something here?
(I am working with the Expansion Downloader Library provided by the Android team. This involves implementing a simple service.)
Yes, you can put it in whatever namespace you want.
Beyond subclassing DownloaderService you need to read the rest of the document, including Starting the download. Of particular interest is this line:
// Start the download service (if required)
int startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(this,
pendingIntent, SampleDownloaderService.class);
Note that you need to provide your custom Service class here.
Yes.
I've done this many times. Chances are there's something else going on. The first thing I'd check is to make sure your Intent is properly constructed.
I've got two separate applications that use a common background service (which is in a common library which both applications include) to collect Bluetooth data. Everything works fine on first installation of the applications.
The problem is that when one of the applications is re-deployed after having the common service changed, it still uses the service previously installed.
Here's some info and an example to clarify things:
The 2 applications are named BioSound, and BioZen. Each of them includes a common library called AndroidSpineServerLib, which in terns includes the common library AndroidBTService (which contains the background service)
For example, on first installation AndroidBTService has a version number of, say 1.0. When the applications are deployed everything is fine, Both BioZen and BioSound uses the V1.0 service.
Then I make a change to BioSound, and AndroidBTService, incrementing it's version to V1.1. When I deploy BioSound after this I would expect it to use the newly changed service V1.1, but it continues to use the V1.0 service. The only way to fix this is to remove the BioZen , then BioSound the correct service ( I don't even have to reinstall BioSound).
Programatically, when I start each application I bind to the service, and when each application exits I unbind the service.
Obviously I'm missing something but can't figure it out. Any ideas?
Your problem may be that you are using an implicit intent to communicate with your service that doesn't specific an application, only an action. That intent (which you're using in both applications) ends up getting resolved to one particular application's service. Instead, make sure to specify the explicit intent with the particular component or class. See the Intent docs for details.
I'm sure this is it but I'm having difficulty with the details.
Here's the existing code:
Mainfest for the main Application:
<application android:icon="#drawable/biosound_icon" android:label="#string/app_name" android:debuggable="true">
<service
android:name="com.t2.biofeedback.BioFeedbackService">
<intent-filter>
<action android:name="com.t2.biofeedback.IBioFeedbackService"/>
</intent-filter>
</service>
</application>
The call to bind the service was in the library AndroidSpineServerLib
Intent intent2 = new Intent("com.t2.biofeedback.IBioFeedbackService");
bindService(intent2, mConnection, Context.BIND_AUTO_CREATE);
So I can see how the service was bound to a specific application
To fix this I tried:
Intent intent2 = new Intent(this, BioFeedbackService.class);
bindService(intent2, mConnection, Context.BIND_AUTO_CREATE);
The problem is that the service was not created.
I also tried the following
In the manifest of the service:
<service
android:class=".service.BioFeedbackService">
<intent-filter>
<action android:name="com.t2.biofeedback.IBioFeedbackService"/>
</intent-filter>
</service>
And in the library where I bind the service:
Intent intent2 = new Intent();
intent2.setAction("com.t2.biofeedback.IBioFeedbackService");
bindService(intent2, mConnection, Context.BIND_AUTO_CREATE);
Still no luck.
Maybe I'm putting the service definition in the wrong manifest.
Remember I have the following hierarchy
Main Application references:
AndroidBTService (Library), which references
AndroidSpineServerLib (Library)
So I have 3 manifests and not sure which to update.