2016-05-05 7 views
6

Я пытаюсь разработать настройку 2 приложений (приложение-приложение-приложение + клиентское приложение) с использованием AIDL. У меня в настоящее время на установке 3-х модулей:Служба AIDL не подключается после bindService()

  • андроида-агент-структура (Android модуль библиотеки может содержать только файл AIDL)
  • андроида-агента (службу)
  • Android-пример-клиента (клиент)

Андроид-агент и андроид-агент-каркас имеют зависимость от первого, чтобы получить доступ к интерфейсу.

Всякий раз, когда клиент вызывает bindService(), он получает false как возврат, а в ServiceConnection onServiceConnected() не вызывается. Также в реализации сервиса onBind() не вызывается. В журналах ошибок нет.

Вот код:

андроид-агентская деятельность:

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

} 

сервис андроид-агента:

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

} 

андроида-агент манифест:

<?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> 

андроида -example-client activity:

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


    } 

} 

Вызов printServices(), прежде чем пытаться связать службу, фактически перечисляет службу так, что она запущена.

Журнал не содержит ошибок, и клиент в конце работает в цикле, но служба по-прежнему равна нулю.

Возможно, кто-то столкнулся с аналогичной проблемой раньше.

+0

В Android 5.0+ вам нужно использовать явное «намерение» для привязки к службе. Я скептически отношусь к тому, что 'setPackage()' достаточно. – CommonsWare

+0

@CommonsWare Я фактически добавил setPackage() после того, как столкнулся с проблемой Android, жалующейся на то, что намерение не было явным. Я протестировал один пример проекта AIDL, который также использовал setPackage() на том же телефоне, и он сработал. С setPackage() ошибка исчезла и в моем проекте – TyrManuZ

ответ

2

После очередного раунда всех файлов я обнаружил свою ошибку.

мне нужно изменить:

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

к:

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

Пакет Намерению должен соответствовать пакет приложения, а не пакет сервиса.

 Смежные вопросы

  • Нет связанных вопросов^_^