Question

this is the class that calls my Service:

public class TicketList extends ListActivity
{
private ArrayList<Tickets> alTickets = new ArrayList<Tickets>();
private boolean listCreated = false;
private static Drawable background = null;
private Resources res;
private Tickets ticket = null;
private TicketConnector localService;

/** 
 * Called when the activity is first created. 
 * 
 */
@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.ticketlist);

    if(!listCreated)
    {
        connectService();
        //populateList();

        res = getResources();
        background = res.getDrawable(R.drawable.background);
        listCreated = true;
    }

    TicketAdapter StatisticsAdapter = new TicketAdapter(this, alTickets);
    setListAdapter(StatisticsAdapter);
}

/**
 * Populates the ListView.
 * This needs to be done once the Activity is created and if the menu entry refresh is hit.
 */
private void populateList()
{
    try
    {           
        String jsonString = localService.queryData(new String[] {"getTicketList"}, new String[] {"Offen"});
        //String jsonString = new TicketConnector().queryData(new String[] {"getTicketList"}, new String[] {"Offen"});

        JSONObject jsonObj = new JSONObject(jsonString);
        JSONArray ticketArray = jsonObj.getJSONArray("tickets");

        Tickets[] tickets = new Tickets[ticketArray.length()];
        for (int i=0;i<ticketArray.length();i++)
        {
            JSONObject object = ticketArray.getJSONObject(i).getJSONObject("ticket");   

            ticket = new Tickets(object.getString("id"), object.getString("color"), object.getString("priority"));
            alTickets.add(ticket);
        }
    }
    catch (Exception e)
    {
        Log.e("DayTrader", "Exception getting JSON data", e);
    }
}

private void connectService() 
{
     Intent intent = new Intent(getApplicationContext(), TicketConnector.class);
     bindService(intent, connection, Context.BIND_AUTO_CREATE);
}

public void getData() 
{
     String s = localService.queryData(new String[] {"getTicketList"}, new String[] {"Offen"});
}

ServiceConnection connection = new ServiceConnection() 
{
     @Override
     public void onServiceConnected(ComponentName name, IBinder binder) 
     {
         Toast.makeText(TicketList.this, "Service connected",Toast.LENGTH_SHORT).show();

         localService = ((TicketConnector.LocalBinder)binder).getService();
         Log.i("INFO", "Service bound: TicketConnector");
     }

     @Override
     public void onServiceDisconnected(ComponentName name) 
     {
         Toast.makeText(TicketList.this, "Service disconnected",Toast.LENGTH_SHORT).show();
         localService = null;
         Log.i("INFO", "Service unbound: TicketConnector");
     }
 };
}

And this is the service:

public class TicketConnector extends Service
{   
private SharedPreferences settings = null;

// This is the object that receives interactions from clients.  See
// RemoteService for a more complete example.
private final IBinder binder = new LocalBinder();

private String username = null;
private String password = null;
private String server = null;
private String port = null;
private String urlStr = null;

private String result = null;

@Override
public void onCreate()
{
    settings = CMDBSettings.getSettings(this);
    username = settings.getString("username", "");
    password = settings.getString("password", "");
    server = settings.getString("server", "");
    port = settings.getString("serverport", "");
}

@Override
public IBinder onBind(Intent intent)
{
    return binder;
}

@Override
public void onDestroy()
{

}

public String queryData(String[] actions, String[] category)
{
    //http://localhost:8080/MobileCMDB/TicketListener?format=json&actions=getTicketList&ticketcategory=Open
    urlStr = "http://"+server+":"+port+"/MobileCMDB/TicketListener?format=";
    new jsonParser().execute(actions);

    return result;
}

abstract class BaseParser extends AsyncTask<String, Integer, String>
{   
    protected BaseParser(String format)
    {
        urlStr += format;
    }

    private String makeUrlString(String[] actions, String[] category)
    {
        StringBuilder sb = new StringBuilder(urlStr);
        for (int i=0;i<actions.length;i++)
        {
            sb.append("&actions=");
            sb.append(actions[i]);

            sb.append("&ticketcategory=");
            sb.append(category[i]);
        }

        return sb.toString();
    }

    protected InputStream getData(String[] actions, String[] category) throws Exception
    {
        URI uri = new URI(makeUrlString(actions, category));

        HttpClient client = new DefaultHttpClient();
        HttpGet request = new HttpGet(uri);
        request.addHeader("Accept-Encoding","gzip");
        HttpResponse response = client.execute(request);
        InputStream content = response.getEntity().getContent();
        Header contentEncoding = response.getFirstHeader("Content-Encoding");

        if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip"))
        {
            content = new GZIPInputStream(content);
        }

        return content;
    }

    @Override
    protected void onPostExecute(String jsonString)
    {
        result = jsonString;
    }   
}

private class jsonParser extends BaseParser
{
    public jsonParser()
    {
        super("json");
    }

    @Override
    protected String doInBackground(String... actions) 
    {
        String[] category = new String[] {"Open"};

        StringBuilder json = null;
        try
        {
            json = new StringBuilder();
            BufferedReader reader = new BufferedReader(new InputStreamReader(getData(actions, category)));
            String line = reader.readLine();

            while (line != null)
            {
                json.append(line);
                line = reader.readLine();
            }
        } 
        catch (Exception e)
        {
            Log.e("PrimeCMDB - Network", "Exception getting JSON data", e);
        }

        return json.toString();
    }
}

/**
 * Class for clients to access.  Because we know this service always
 * runs in the same process as its clients, we don't need to deal with
 * IPC.
 */
public class LocalBinder extends Binder 
{
    public TicketConnector getService() 
    {
        return TicketConnector.this;
    }
}
}

This are the two activities in the AndroidManifest.xml:

<activity
    android:name=".ticket.TicketList"
    android:label="@string/ticket"
/>
<service 
    android:name=".network.TicketConnector" 
    android:enabled="true"
/>

onServiceConnected is never executed. Did I miss something?

Here is the output of LogCat at verbose mode while activating the TicketList Activity:

09-28 23:22:11.420: INFO/ActivityManager(795): Starting activity: Intent { cmp=org.mw88.cmdb/.gui.TicketListActivity }
09-28 23:22:12.340: WARN/ActivityManager(795): Binding with unknown activity: android.os.BinderProxy@4410bf30
09-28 23:22:16.090: INFO/ActivityManager(795): Displayed activity org.mw88.cmdb/.gui.TicketListActivity: 4606 ms (total 4606 ms)
Was it helpful?

Solution

Thank you all for your Answers.

I found the question after searching Google for this log message:

Binding with unknown activity: android.os.BinderProxy

It seems that Android has a bug when using bindService to fill a TabSpec Activity!

The solution was pretty simple: just replace bindService with getApplicationContext().bindService

Now it works perfectly ;-)

OTHER TIPS

I don't think that it is a bug.

In my opinion, that's because when you use the TabActivity, the child activities will be embedded in the parent (TabActivity) as more like a view with activity behavior, hence its context cannot serve as an actual context.

So for the workaround, you need to get and use the parent (using getParent()) or the application context (using getApplicationContext()) which can act as an "actual" context.

But again, this is just my opinion because I cannot provide any link to any documentation related to this one. :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top