2015-01-08 14 views
40

Şimdi bir yayın alıcısı (MyStartupIntentReceiver) aracılığıyla bir hizmet çağıran bir uygulama var. servisini çağırmak için yayın alıcısı içinde kodudur:Hizmet Amacı açık olmalıdır: Intent

public void onReceive(Context context, Intent intent) { 
    Intent serviceIntent = new Intent(); 
    serviceIntent.setAction("com.duk3r.eortologio2.MyService"); 
    context.startService(serviceIntent); 
} 

sorun Android 5.0 Lollipop içinde aşağıdaki hatayı alıyorum olmasıdır (Android'in önceki sürümlerinde, herşey yolunda çalışır):

Unable to start receiver com.duk3r.eortologio2.MyStartupIntentReceiver: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.duk3r.eortologio2.MyService } 

Hizmetin açık olarak bildirilmesi ve normal şekilde başlatılması için neyi değiştirmek zorundayım? Diğer benzer konulardaki bazı cevapları denedim, ancak mesajdan kurtulmuş olmama rağmen servis başlamazdı.

+0

bu uygulamada bir hizmettir? – tyczj

+0

evet paket com.duk3r.eortologio2 benim app. – duk3r

+3

Başka şirketlerce sağlanan uygulamaların bu bileşenle iletişim kurmasını istediğinizde, bir bileşene yalnızca 'özelliği vardır. Her şey için bir ' '' ye ihtiyacınız olduğunu varsaymak için tuzağa düşmüş görünüyorsunuz - gerçekte, nadiren bir 'ye ihtiyacınız var. Açıkça bir 'Intent', 'Intent' in kendisi için konuşacak bileşeni, genellikle Java 'Class' nesnesini ikinci parametre olarak alan yapıcıyı kullanarak belirlediğiniz zamandır. Implicit 'Intent's ve' 'lerden ziyade, uygulamanızın yerel bileşenleri için kullanmanız gerekenler. – CommonsWare

cevap

72

daima (şu anda kodunda ne)

Intent serviceIntent = new Intent(context,MyService.class); 
context.startService(serviceIntent); 

veya

Intent bi = new Intent("com.android.vending.billing.InAppBillingService.BIND"); 
bi.setPackage("com.android.vending"); 

örtülü niyetler vardır şu biçime uygun olmalıdır uygulamanızda vb bir hizmet, aktivite yaptığınız herhangi niyet Güvenlik riski var

+0

thanx tyczj, bu hataya neden oldu :) – duk3r

+0

bu doğru değil, @ kai-chen'in cevabı mükemmel çalışır –

+0

BindService' gerekiyorsa ne olur? –

18

packageName öğelerinizi ayarlayın.

intent.setPackage(this.getPackageName()); 
1

Sebebi açık amaca dönüştür, sonra da başlatma hizmetini başlat. Benim gibi tembel insanlar için

 Intent implicitIntent = new Intent(); 
     implicitIntent.setAction("com.duk3r.eortologio2.MyService"); 
     Context context = getApplicationContext(); 
     Intent explicitIntent = convertImplicitIntentToExplicitIntent(implicitIntent, context); 
     if(explicitIntent != null){ 
      context.startActivity(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; 
     } 
5

sadece bu yöntemde

public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) { 
    // Retrieve all services that can match the given intent 
    PackageManager pm = context.getPackageManager(); 
    List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0); 

    // Make sure only one match was found 
    if (resolveInfo == null || resolveInfo.size() != 1) { 
     return null; 
    } 

    // Get component info and create ComponentName 
    ResolveInfo serviceInfo = resolveInfo.get(0); 
    String packageName = serviceInfo.serviceInfo.packageName; 
    String className = serviceInfo.serviceInfo.name; 
    ComponentName component = new ComponentName(packageName, className); 

    // Create a new intent. Use the old one for extras and such reuse 
    Intent explicitIntent = new Intent(implicitIntent); 

    // Set the component to be explicit 
    explicitIntent.setComponent(component); 

    return explicitIntent; 
} 

Gönder bağlamı ve niyetinizi kullanmak ve kullanmak için niyet sonucu olsun.

0

Bunu deneyin. benim için çalışıyor. Burada MonitoringService hizmet sınıfımdır. Hizmetin durması veya başlatılması için iki eylemim var. Bu değeri yayın alıcım'dan AIRPLANE_MODE_CHANGED'a göndermekteyim.

@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); 
    } 
} 

NOT: ManageLocationListenerReceiver: Ben adında benim yayın alıcısı tetiklemek için kod aşağıdaki ekleyin.

<receiver 
    android:name=".ManageLocationListenerReceiver" 
    android:enabled="true" 
    android:exported="true"> 
    <intent-filter> 
     <action android:name="android.intent.action.AIRPLANE_MODE" /> 
    </intent-filter> 
</receiver>