2013-04-09 3 views
9

Ich schreibe eine dienstbasierte App mit einem gebundenen Dienst, und die onBind() - Methode des Dienstes scheint nie aufgerufen zu werden (testet sie mit Toast und Logs).onBind() wird niemals in einem Dienst aufgerufen

Der Service:

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

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

Die Aktivität:

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

Warum funktioniert es nicht?

+2

Überprüfen Sie LogCat auf Nachrichten, z. B. dass Ihr Dienst nicht in Ihrem Manifest aufgeführt ist. – CommonsWare

Antwort

10

Wahrscheinlich ist die häufigste Quelle der Bindung, die im Hintergrund fehlschlägt, nicht der im Manifest aufgelistete Dienst. Dies führt nicht zu einer Ausnahme, daher stürzt Ihre App nicht ab, aber in LogCat sollte eine Meldung (Warnung, IIRC) erscheinen, die auf Ihr Problem hinweist.

+0

Danke, das war der Fall - Eine andere Dienstklasse wurde im Manifest statt dieser aufgelistet. –

Verwandte Themen