2016-05-05 18 views
6

Sto cercando di sviluppare una configurazione di 2 applicazioni (app di servizio + app client) utilizzando AIDL. Ho attualmente una configurazione di 3 moduli:Servizio AIDL non connesso dopo bindService()

  • android-agent-quadro (modulo di libreria Android in possesso solo il file AIDL)
  • Android-agent (il servizio)
  • android-esempio-client (il client)

android-agent e android-agent-framework hanno una dipendenza dal primo per accedere all'interfaccia.

Ogni volta che il client chiama bindService() diventa falso come ritorno e in ServiceConnection non viene chiamato onServiceConnected(). Anche nell'implementazione del servizio onBind() non viene chiamato. Non ci sono errori nei log.

Ecco il codice:

attività Android-agent:

public class MyCompanyStartActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     Log.i(MyCompanyStartActivity.class.toString(), "Create MyCompanyStartActivity"); 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     ComponentName service = startService(new Intent(this, MyCompanyRequestService.class)); 
     Log.i("tag", service.getClassName() + "::" + service.getPackageName()); 
    } 

} 

servizio Android-agent:

public class MyCompanyRequestService extends Service { 

@Override 
public IBinder onBind(Intent intent) { 
    Log.i(MyCompanyRequestService.class.toString(), "Starting SmartRest Service"); 
    return mBinder; 
} 

private final IMyCompanyRequestService.Stub mBinder = new IMyCompanyRequestService.Stub() { 

    @Override 
    public void sendData(String xid, String authentication, String data) throws RemoteException{ 
     Log.i(MyCompanyRequestService.class.toString(), "sending data: " + data); 
    } 
}; 

} 

android-agent manifestare:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.mycompany.android.agent" > 

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name=".MyCompanyStartActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

     <!-- Services --> 
     <service 
      android:name="com.mycompany.android.agent.framework.MyCompanyRequestService" 
      android:process=":remote" 
      android:exported="true" 
      android:enabled="true"> 
      <intent-filter> 
       <action android:name="MyCompanyRequestService"/> 
       <category android:name="android.intent.category.DEFAULT"/> 
      </intent-filter> 
     </service> 

     <!-- Permissions --> 

    </application> 

</manifest> 

Android -esempio-attività del cliente:

public class ClientStarter extends Activity { 

    protected IMyCompanyRequestService mycompanyRequestService = null; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     Log.i("tag","create client"); 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

    } 
    @Override 
    protected void onStart() { 
     super.onStart(); 
     if (mycompanyRequestService == null) { 
      printServices(); 
      Intent it = new Intent("MyCompanyRequestService"); 
      it.setPackage("com.mycompany.android.agent.framework"); 
      Log.i("tag","before binding service: " + it.getAction() + "::" + it.getPackage()); 
      boolean serviceBinding = getApplicationContext().bindService(it, connection, Context.BIND_AUTO_CREATE); 
      Log.i("tag", "service is bound: " + serviceBinding); 
     } 
     Handler handler = new Handler(); 
     handler.postDelayed(new Runner(), 10000); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     unbindService(connection); 
    } 

    private ServiceConnection connection = new ServiceConnection() { 
     @Override 
     public void onServiceConnected(ComponentName name, IBinder service) { 
      Log.i("service", "Service connected"); 
      mycompanyRequestService = IMyCompanyRequestService.Stub.asInterface(service); 
      Toast.makeText(getApplicationContext(), "Service Connected", Toast.LENGTH_SHORT).show(); 
      Log.i("service", "Service connected"); 
     } 
     @Override 
     public void onServiceDisconnected(ComponentName name) { 
      Log.i("service", "Service disconnected"); 
      mycompanyRequestService = null; 
      Toast.makeText(getApplicationContext(), "Service Disconnected", Toast.LENGTH_SHORT).show(); 
      Log.i("service", "Service disconnected"); 
     } 
    }; 

    private void printServices() { 
     ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 
     for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { 
      Log.d("service", service.service.getClassName()); 
     } 
    } 

    private class Runner implements Runnable { 

     @Override 
     public void run() { 
      Log.i("tag","starting"); 
      LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
      Location loc; 
      try { 
       Thread.sleep(10000); 
      } catch (InterruptedException e) { 
       Log.e(ClientStarter.class.toString(), "Error", e); 
      }   while(true) { 
       try { 
        if (mycompanyRequestService != null) { 
         loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
         Log.i(ClientStarter.class.toString(), loc.getLatitude() + " - " + loc.getLongitude() + " - " + loc.getAltitude()); 
         mycompanyRequestService.sendData("test", "auth", String.valueOf(loc.getLatitude()) + "," + String.valueOf(loc.getLongitude()) + "," + String.valueOf(loc.getAltitude())); 
        } else { 
         Log.i(ClientStarter.class.toString(), "service not yet available"); 
        } 
        Thread.sleep(5000); 
       } catch (InterruptedException e) { 
        Log.e(ClientStarter.class.toString(), "Error", e); 
       } catch (RemoteException e) { 
        Log.e(ClientStarter.class.toString(), "Error", e); 
       } 
      } 
     } 


    } 

} 

La chiamata printServices() prima di tentare di associare il servizio elenca effettivamente il servizio in modo che sia in esecuzione.

Il registro non contiene errori e il client sta alla fine eseguendo il ciclo ma il servizio è ancora nullo.

Forse qualcuno ha riscontrato un problema simile prima.

+0

Su Android 5.0+, è necessario utilizzare un esplicito 'Intento' per collegarsi a un servizio. Sono scettico sul fatto che 'setPackage()' sia sufficiente. – CommonsWare

+0

@CommonsWare Ho effettivamente aggiunto il setPackage() dopo che mi sono imbattuto nel problema relativo a Android lamentando che l'intento non era esplicito. Ho testato un progetto di esempio AIDL che utilizzava anche setPackage() sullo stesso telefono e funzionava. Con il setPackage() l'errore è sparito anche nel mio progetto – TyrManuZ

risposta

2

Dopo aver passato un altro giro attraverso tutti i file ho trovato il mio errore.

avevo bisogno di cambiare:

Intent it = new Intent("MyCompanyRequestService"); 
it.setPackage("com.mycompany.android.agent.framework"); 

a:

Intent it = new Intent("MyCompanyRequestService"); 
it.setPackage("com.mycompany.android.agent"); 

Il pacchetto del intenti deve corrispondere il pacchetto delle app e non il pacchetto del servizio.

Problemi correlati