2016-05-05 19 views
6

Tôi đang cố gắng phát triển thiết lập 2 ứng dụng (ứng dụng dịch vụ + ứng dụng khách) bằng AIDL. Tôi hiện đang có một thiết lập của 3 module:Dịch vụ AIDL không kết nối sau khi bindService()

  • android-agent-framework (android Module thư viện tổ chức chỉ file AIDL)
  • android-agent (dịch vụ)
  • android-dụ-client (các khách hàng)

đại lý android và android-agent-framework có quyền phụ thuộc vào người đầu tiên truy cập vào giao diện.

Bất cứ khi nào khách hàng gọi bindService() nó bị sai khi trả về và trong ServiceConnection, onServiceConnected() không được gọi. Cũng trong việc thực hiện dịch vụ, onBind() không được gọi. Không có lỗi trong nhật ký.

Đây là mã:

hoạt động 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()); 
    } 

} 

dịch vụ 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 manifest:

<?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 hoạt động -example-client:

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() gọi trước khi cố kết nối dịch vụ thực sự liệt kê dịch vụ để dịch vụ đang chạy.

Nhật ký không chứa bất kỳ lỗi nào và máy khách đang ở cuối chạy trong vòng lặp nhưng dịch vụ vẫn không có giá trị.

Có thể ai đó đã gặp sự cố tương tự trước đây.

+0

Trên Android 5.0+, bạn cần sử dụng 'Intent' rõ ràng để liên kết với dịch vụ. Tôi hoài nghi rằng 'setPackage()' là đủ. – CommonsWare

+0

@CommonsWare Tôi thực sự đã thêm setPackage() sau khi tôi gặp sự cố về Android phàn nàn rằng Intent không rõ ràng. Tôi đã thử nghiệm một dự án ví dụ AIDL cũng sử dụng setPackage() trên cùng một điện thoại và nó hoạt động. Với setPackage(), lỗi cũng biến mất trong dự án của tôi – TyrManuZ

Trả lời

2

Sau khi thực hiện một vòng khác thông qua tất cả các tệp, tôi đã tìm thấy lỗi của mình.

tôi cần phải thay đổi:

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

tới:

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

Gói tiếp cận mục đích cần phải phù hợp với gói ứng dụng và không phải là gói dịch vụ.

Các vấn đề liên quan