I have an app some time now in which I call a service through a broadcast receiver (MyStartupIntentReceiver). The code in the broadcast receiver in order to call the service
Convert implicit intent to explicit intent then fire start service.
Intent implicitIntent = new Intent();
implicitIntent.setAction("com.duk3r.eortologio2.MyService");
Context context = getApplicationContext();
Intent explicitIntent = convertImplicitIntentToExplicitIntent(implicitIntent, context);
if(explicitIntent != null){
context.startService(explicitIntent);
}
public static Intent convertImplicitIntentToExplicitIntent(Intent implicitIntent, Context context) {
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfoList = pm.queryIntentServices(implicitIntent, 0);
if (resolveInfoList == null || resolveInfoList.size() != 1) {
return null;
}
ResolveInfo serviceInfo = resolveInfoList.get(0);
ComponentName component = new ComponentName(serviceInfo.serviceInfo.packageName, serviceInfo.serviceInfo.name);
Intent explicitIntent = new Intent(implicitIntent);
explicitIntent.setComponent(component);
return explicitIntent;
}
any intent you make to a service, activity etc. in your app should always follow this format
Intent serviceIntent = new Intent(context,MyService.class);
context.startService(serviceIntent);
or
Intent bi = new Intent("com.android.vending.billing.InAppBillingService.BIND");
bi.setPackage("com.android.vending");
implicit intents (what you have in your code currently) are considered a security risk
Set your packageName
works.
intent.setPackage(this.getPackageName());
Try this. it works for me. Here MonitoringService is my service class. I have two action, which indicate service to stop or start. I send that value from my broadcast receiver depend on AIRPLANE_MODE_CHANGED.
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(Intent.ACTION_AIRPLANE_MODE_CHANGED.equalsIgnoreCase(action)){
boolean isOn = intent.getBooleanExtra("state", false);
String serviceAction = isOn? MonitoringService.StopAction : MonitoringService.StartAction;
Intent serviceIntent = new Intent(context, MonitoringService.class);
serviceIntent.setAction(serviceAction);
context.startService(serviceIntent);
}
}
NOTE: I add following code to trigger my broadcast receiver named: ManageLocationListenerReceiver.
<receiver
android:name=".ManageLocationListenerReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.AIRPLANE_MODE" />
</intent-filter>
</receiver>
I improved the answer of Shahidul to remove the context dependency:
public class ServiceUtils {
public static void startService(String intentUri) {
Intent implicitIntent = new Intent();
implicitIntent.setAction(intentUri);
Context context = SuperApplication.getContext();
Intent explicitIntent = convertImplicitIntentToExplicitIntent(implicitIntent, context);
if(explicitIntent != null){
context.startService(explicitIntent);
}
}
private static Intent convertImplicitIntentToExplicitIntent(Intent implicitIntent, Context context) {
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfoList = pm.queryIntentServices(implicitIntent, 0);
if (resolveInfoList == null || resolveInfoList.size() != 1) {
return null;
}
ResolveInfo serviceInfo = resolveInfoList.get(0);
ComponentName component = new ComponentName(serviceInfo.serviceInfo.packageName, serviceInfo.serviceInfo.name);
Intent explicitIntent = new Intent(implicitIntent);
explicitIntent.setComponent(component);
return explicitIntent;
}
}
Inside the SuperApplication class:
public class SuperApplication extends Application {
private static MyApp instance;
public static SuperApplication getInstance() {
return instance;
}
public static Context getContext(){
return instance;
// or return instance.getApplicationContext();
}
@Override
public void onCreate() {
instance = this;
super.onCreate();
}
}
In your manifest:
<application
android:name="com.example.app.SuperApplication "
android:icon="@drawable/icon"
android:label="@string/app_name"
.......
<activity
......
And then, just call:
ServiceUtils.startService("com.myservice");