Java tutorial
/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package my.home.lehome.service; import android.app.IntentService; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.Message; import android.os.Messenger; import android.os.PowerManager; import android.os.RemoteException; import android.text.TextUtils; import android.util.Log; import com.android.volley.NoConnectionError; import com.android.volley.ParseError; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.ServerError; import com.android.volley.TimeoutError; import com.android.volley.toolbox.RequestFuture; import com.android.volley.toolbox.Volley; import org.json.JSONException; import org.json.JSONObject; import java.util.Date; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import my.home.lehome.R; import my.home.lehome.service.net.CommandRequest; import my.home.lehome.util.Constants; import my.home.model.entities.ChatItem; import my.home.model.entities.ChatItemConstants; import my.home.model.manager.DBStaticManager; /** * Created by legendmohe on 15/3/30. */ public class SendMsgIntentService extends IntentService { public static final int MSG_END_SENDING = 0; public static final int MSG_BEGIN_SENDING = 1; public final static String ACTION_SEND_MSG_BEGIN = "my.home.lehome.receiver.SendMsgIntentService:start"; public final static String ACTION_SEND_MSG_END = "my.home.lehome.receiver.SendMsgIntentService:end"; public final static String TAG = "SendMsgIntentService"; private PowerManager.WakeLock mWakeLock; private RequestQueue mRequestQueue; /** * Creates an IntentService. Invoked by your subclass's constructor. */ public SendMsgIntentService() { super("SendMsgIntentService"); } @Override public void onCreate() { super.onCreate(); if (mWakeLock == null) { PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mWakeLock.acquire(); Log.d(TAG, "acquire wakelock"); } mRequestQueue = Volley.newRequestQueue(getApplicationContext()); } @Override public void onDestroy() { super.onDestroy(); if (mWakeLock != null) { mWakeLock.release(); mWakeLock = null; Log.d(TAG, "release wakelock"); } } @Override public int onStartCommand(Intent intent, int flags, int startId) { preparePengindCommand(intent); return super.onStartCommand(intent, flags, startId); } @Override protected void onHandleIntent(Intent intent) { dispatchCommand(intent); } private void preparePengindCommand(Intent intent) { Messenger messenger; if (intent.hasExtra("messenger")) messenger = (Messenger) intent.getExtras().get("messenger"); else messenger = null; Message repMsg = Message.obtain(); repMsg.what = MSG_BEGIN_SENDING; boolean isSysCmd = intent.getBooleanExtra("isSysCmd", false); if (isSysCmd) { Log.d(TAG, "sys cmd item"); return; } ChatItem item = intent.getParcelableExtra("update"); if (item == null) { item = new ChatItem(); item.setContent(intent.getStringExtra("cmd")); item.setType(ChatItemConstants.TYPE_CLIENT); item.setState(Constants.CHATITEM_STATE_ERROR); // set ERROR item.setDate(new Date()); DBStaticManager.addChatItem(getApplicationContext(), item); } item.setState(Constants.CHATITEM_STATE_PENDING); Log.d(TAG, "enqueue item: \n" + item); Bundle bundle = new Bundle(); bundle.putBoolean("update", intent.hasExtra("update")); bundle.putParcelable("item", item); if (messenger != null) { repMsg.setData(bundle); try { messenger.send(repMsg); } catch (RemoteException e) { e.printStackTrace(); } } else { Log.d(TAG, "messager is null, send broadcast instead:" + ACTION_SEND_MSG_BEGIN); Intent newIntent = new Intent(ACTION_SEND_MSG_BEGIN); newIntent.putExtras(bundle); sendBroadcast(newIntent); } intent.putExtra("pass_item", item); } private void dispatchCommand(final Intent intent) { String cmd = intent.getStringExtra("cmdString"); String servelURL = intent.getStringExtra("serverUrl"); String deviceID = intent.getStringExtra("deviceID"); boolean local = intent.getBooleanExtra("local", false); Log.d(TAG, "dispatch cmd:" + cmd + " | servelURL:" + servelURL + " | deviceID:" + deviceID + " | local:" + local); final Context context = getApplicationContext(); if (local) { if (TextUtils.isEmpty(servelURL)) { saveAndNotify(intent, CommandRequest.getJsonStringResponse(400, context.getString(R.string.msg_local_saddress_not_set))); } } else { if (TextUtils.isEmpty(deviceID)) { saveAndNotify(intent, CommandRequest.getJsonStringResponse(400, context.getString(R.string.msg_no_deviceid))); } if (TextUtils.isEmpty(servelURL)) { saveAndNotify(intent, CommandRequest.getJsonStringResponse(400, context.getString(R.string.msg_saddress_not_set))); } } RequestFuture<String> future = RequestFuture.newFuture(); CommandRequest request = new CommandRequest(local ? Request.Method.POST : Request.Method.GET, // diff servelURL, cmd, future, future); mRequestQueue.add(request); try { String response = future.get(request.getTimeoutMs() + 10000, TimeUnit.MILLISECONDS); Log.d(TAG, "get cmd response:" + response); saveAndNotify(intent, CommandRequest.getJsonStringResponse(200, response)); } catch (ExecutionException e) { Throwable error = e.getCause(); Log.d(TAG, "get cmd error:" + error.toString()); String errorString = context.getString(R.string.error_unknown); int errorCode = 400; if (error instanceof ServerError) { errorString = context.getString(R.string.chat_error_conn); errorCode = 400; } else if (error instanceof TimeoutError) { errorString = context.getString(R.string.chat_error_http_error); errorCode = 400; } else if (error instanceof ParseError) { errorString = context.getString(R.string.chat_error_http_error); errorCode = 400; } else if (error instanceof NoConnectionError) { errorString = context.getString(R.string.chat_error_no_connection_error); errorCode = 400; } saveAndNotify(intent, CommandRequest.getJsonStringResponse(errorCode, errorString)); } catch (TimeoutException e) { saveAndNotify(intent, CommandRequest.getJsonStringResponse(400, context.getString(R.string.chat_error_http_error))); } catch (Exception e) { future.cancel(true); e.printStackTrace(); // saveAndNotify(intent, // CommandRequest.getJsonStringResponse( // 400, // context.getString(R.string.error_internal) // )); } } private void saveAndNotify(Intent intent, String result) { Context context = getApplicationContext(); int rep_code = -1; String desc; try { JSONObject jsonObject = new JSONObject(result); rep_code = jsonObject.getInt("code"); desc = jsonObject.getString("desc"); } catch (JSONException e) { e.printStackTrace(); desc = context.getString(R.string.chat_error_json); } Messenger messenger; if (intent.hasExtra("messenger")) messenger = (Messenger) intent.getExtras().get("messenger"); else messenger = null; Message repMsg = Message.obtain(); repMsg.what = MSG_END_SENDING; ChatItem item = intent.getParcelableExtra("pass_item"); ChatItem newItem = null; if (item != null) { if (rep_code == 200) { item.setState(Constants.CHATITEM_STATE_SUCCESS); DBStaticManager.updateChatItem(context, item); } else { if (rep_code == 415) { item.setState(Constants.CHATITEM_STATE_SUCCESS); } else { item.setState(Constants.CHATITEM_STATE_ERROR); } DBStaticManager.updateChatItem(context, item); newItem = new ChatItem(); newItem.setContent(desc); newItem.setType(ChatItemConstants.TYPE_SERVER); newItem.setState(Constants.CHATITEM_STATE_ERROR); // always set true newItem.setDate(new Date()); DBStaticManager.addChatItem(context, newItem); } } else { if (rep_code != 200) { Log.d(TAG, result); newItem = new ChatItem(); newItem.setContent(getString(R.string.loc_send_error) + ":" + desc); // TODO - not only loc report newItem.setType(ChatItemConstants.TYPE_SERVER); newItem.setState(Constants.CHATITEM_STATE_SUCCESS); // always set true newItem.setDate(new Date()); DBStaticManager.addChatItem(context, newItem); } } Log.d(TAG, "dequeue item: " + item); if (item == null) return; Bundle bundle = new Bundle(); bundle.putParcelable("item", item); if (newItem != null) bundle.putParcelable("new_item", newItem); bundle.putInt("rep_code", rep_code); if (messenger != null) { repMsg.setData(bundle); try { messenger.send(repMsg); } catch (RemoteException e) { e.printStackTrace(); } } else { Log.d(TAG, "messager is null, send broadcast instead:" + ACTION_SEND_MSG_END); Intent newIntent = new Intent(ACTION_SEND_MSG_END); newIntent.putExtras(bundle); sendBroadcast(newIntent); } } }