2013-04-09 13 views
9

Piszę aplikację opartą na usługach z usługą związaną, a usługa onBind() nigdy nie wydaje się być wywoływana (testowanie jej za pomocą toastów i dzienników).Funkcja onBind() nigdy nie jest wywoływana w usłudze

Usługa:

import android.app.Notification; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.app.Service; 
import android.content.Context; 
import android.content.Intent; 
import android.location.Criteria; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Binder; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.util.Log; 
import android.widget.Toast; 
import com.gmail.zack.yovel.FlickAround.MyActivity; 
import com.gmail.zack.yovel.FlickAround.R; 
import org.json.JSONArray; 
import org.json.JSONObject; 

import java.util.ArrayList; 

/** 
* Created with IntelliJ IDEA. 
* User: Ziky 
* Date: 09/04/13 
* Time: 19:06 
* To change this template use File | Settings | File Templates. 
*/ 
public class UpdateService extends Service implements LocationListener, UpdatePhotosTask.OnHttpResponseListener { 
    private final static String API_KEY = "5255c7b02750c0fa4b15bd8ad4ec1fb7"; 
    private final static String GET_PHOTOS_FOR_LOCATION_SCHEMA = "http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=" + API_KEY + "&lat=%d&lon=%d&format=json&nojsoncallback=1"; 
    private static final String KEY_PHOTOS = "photos"; 
    private static final String KEY_PHOTO = "photo"; 
    private int NOTIFICATION = R.string.update_service_started; 
    private NotificationManager mNManager; 
    private LocationManager mLManager; 
    private String mProvider; 
    private Location mLocation; 
    private IBinder mBinder = new LocalBinder(); 
    private UpdatePhotosTask task; 

    @Override 
    public IBinder onBind(Intent intent) { 
     Toast.makeText(this, "UpdateService.onBind()", Toast.LENGTH_LONG).show(); 
     Log.i("test", "UpdateService.onBind()"); 
     mLManager.requestLocationUpdates(mProvider, 0, 1000, this); 
     return mBinder; 
    } 

    @Override 
    public void onCreate() { 
     mNManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
     showNotification(); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Log.i("LocalService", "Received start id " + startId + ": " + intent); 
     mLManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
     Criteria criteria = new Criteria(); 
     mProvider = mLManager.getBestProvider(criteria, false); 
     mLocation = mLManager.getLastKnownLocation(mProvider); 
     return START_STICKY; 
    } 

    @Override 
    public void onDestroy() { 
     mNManager.cancel(NOTIFICATION); 
     Toast.makeText(this, R.string.update_service_stoped, Toast.LENGTH_SHORT).show(); 
    } 

    private void showNotification() { 
     CharSequence text = getText(R.string.update_service_active); 
     Notification notification = new Notification(R.drawable.refresh, text, System.currentTimeMillis()); 
     PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MyActivity.class), 0); 
     notification.setLatestEventInfo(this, getText(R.string.update_service_label), text, contentIntent); 
     mNManager.notify(NOTIFICATION, notification); 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     beginUpdate(location); 
    } 

    private void beginUpdate(Location location) { 
     Toast.makeText(this, "beginning update", Toast.LENGTH_LONG).show(); 
     String url = buildUrl(location); 
     task = new UpdatePhotosTask(this); 
     task.execute(url); 
    } 

    private String buildUrl(Location location) { 
     return String.format(GET_PHOTOS_FOR_LOCATION_SCHEMA, location.getLatitude(), location.getLongitude()); 
    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 
    } 

    @Override 
    public void onProviderEnabled(String provider) { 
    } 

    @Override 
    public void onProviderDisabled(String provider) { 
    } 

    @Override 
    public void onHttpResponse(ArrayList<String> responses) { 
     if (responses.size() > 0) { 
      String response = responses.get(0); 
      try { 
       JSONObject jsonObject = new JSONObject(response); 
       jsonObject = jsonObject.getJSONObject(KEY_PHOTOS); 
       JSONArray jsonArray = jsonObject.getJSONArray(KEY_PHOTO); 
       ArrayList<String> photos = new ArrayList<String>(); 
       for (int i = 0, length = jsonArray.length(); i < length; i++) { 
        jsonObject = jsonArray.getJSONObject(i); 
        Log.i("photo info", jsonObject.toString()); 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public class LocalBinder extends Binder { 
     public UpdateService getService() { 
      return UpdateService.this; 
     } 
    } 
} 

AsyncTask:

import android.os.AsyncTask; 
import android.util.Log; 
import org.apache.http.HttpResponse; 
import org.apache.http.StatusLine; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.impl.client.DefaultHttpClient; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.util.ArrayList; 

/** 
* Created with IntelliJ IDEA. 
* User: Ziky 
* Date: 09/04/13 
* Time: 07:38 
* To change this template use File | Settings | File Templates. 
*/ 
public class UpdatePhotosTask extends AsyncTask<String, Void, ArrayList<String>> { 

    private OnHttpResponseListener listener; 

    public UpdatePhotosTask(OnHttpResponseListener listener) { 
     this.listener = listener; 
    } 

    @Override 
    protected ArrayList<String> doInBackground(String... urls) { 
     ArrayList<String> responses = new ArrayList<String>(); 
     for (String url : urls) { 
      StringBuilder response = new StringBuilder(); 
      DefaultHttpClient client = new DefaultHttpClient(); 
      HttpGet httpGet = new HttpGet(url); 
      try { 
       HttpResponse execute = client.execute(httpGet); 
       StatusLine statusLine = execute.getStatusLine(); 
       int statusCode = statusLine.getStatusCode(); 
       if (statusCode == 200) { 
        InputStream content = execute.getEntity().getContent(); 
        BufferedReader buffer = new BufferedReader(new InputStreamReader(content)); 
        String s = ""; 
        while ((s = buffer.readLine()) != null) { 
         response.append(s); 
        } 
        responses.add(response.toString()); 
       } else { 
        Log.e(this.getClass().toString(), "Failed to download photo list"); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
     return responses; 
    } 

    @Override 
    protected void onPostExecute(ArrayList<String> responses) { 
     listener.onHttpResponse(responses); 
    } 

    public interface OnHttpResponseListener { 
     public void onHttpResponse(ArrayList<String> responses); 
    } 
} 

Aktywność:

import android.app.Activity; 
import android.content.ComponentName; 
import android.content.Intent; 
import android.content.ServiceConnection; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.os.StrictMode; 
import android.widget.Toast; 
import com.gmail.zack.yovel.FlickAround.background.UpdateService; 

public class MyActivity extends Activity { 
    private UpdateService mUpdateService; 
    private ServiceConnection mConnection = new ServiceConnection() { 
     @Override 
     public void onServiceConnected(ComponentName name, IBinder service) { 
      mUpdateService = ((UpdateService.LocalBinder) service).getService(); 
      Toast.makeText(MyActivity.this, R.string.update_service_connected, Toast.LENGTH_SHORT).show(); 
     } 

     @Override 
     public void onServiceDisconnected(ComponentName name) { 
      mUpdateService = null; 
      Toast.makeText(MyActivity.this, R.string.local_service_disconnected, Toast.LENGTH_SHORT).show(); 
     } 
    }; 
    private boolean mIsBound; 

    void doBindService() { 
     Toast.makeText(this, "MyActivity.doBindService()", Toast.LENGTH_LONG).show(); 
     bindService(new Intent(this, UpdateService.class), mConnection, BIND_AUTO_CREATE); 
     mIsBound = true; 
    } 

    void doUnbindService() { 
     if (mIsBound) { 
      unbindService(mConnection); 
      mIsBound = false; 
     } 
    } 

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

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

     // Activate StrictMode 
     StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 
       .detectAll().penaltyLog().penaltyDeath().build()); 
     StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll() 
       .penaltyLog().penaltyDeath().build()); 
    } 

    @Override 
    protected void onStart() { 
     super.onStart(); 
     doBindService(); 
    } 
} 

Dlaczego nie jest to działa?

+2

Sprawdź, czy LogCat zawiera komunikaty, na przykład o tym, że nie ma swojej usługi wymienionej w manifeście. – CommonsWare

Odpowiedz

10

Prawdopodobnie najczęstszym źródłem niewydolności wiążącej jest brak usługi wymienionej w manifeście. Nie powoduje to wyjątku, więc Twoja aplikacja się nie zawiesza, ale w LogCat powinien pojawić się komunikat (ostrzeżenie, IIRC) wskazujący Twój problem.

+0

Dzięki, tak było - inna klasa usługi została wymieniona w manifeście zamiast tego. –

Powiązane problemy