This is my Service which does network operation. But it is throwing NetworkonMainThreadException which i understand android upper version doesn't allows network operation under main thread. Now i want to use Async Task for this purpose. I am not sure which are all code i need to add under Async Task from Service Class to actually make the code complete. Below is my Service Code :
public class NewsTickerDataService extends Service {
#Override
public void onStart(Intent aIntent, int aStartId) {
super.onStart(aIntent, aStartId);
RemoteViews _views = buildUpdatedViews(this);
ComponentName _widget =
new ComponentName(this, NewsTicker.class);
AppWidgetManager _manager =
AppWidgetManager.getInstance(this);
_manager.updateAppWidget(_widget, _views);
}
#Override
public IBinder onBind(Intent aParamIntent) {
// not supporting binding
return null;
}
private RemoteViews buildUpdatedViews(Context aContext) {
List<Story> _stories = getStories();
RemoteViews _result = new RemoteViews(
aContext.getPackageName(),
R.layout.activity_main
);
if (_stories.isEmpty()) {
_result.setTextViewText(R.id.title,
"Sadly there's nothing to read today.");
} else {
_result.setTextViewText(
R.id.title, _stories.get(0).getTitle());
}
return _result;
}
private List<Story> getStories() {
try {
URL _url = new URL("http://search.twitter.com" +
"/search.atom?q=%23uml&" +
"result_type=mixed&count=5"
);
InputStream _in = _url.openStream();
return parse(new InputSource(_in));
} catch (Exception anExc) {
Log.e("NewsTicker", anExc.getMessage(), anExc);
return new ArrayList<Story>();
}
}
private List<Story> parse(InputSource aSource)
throws Exception {
SAXParserFactory _f = SAXParserFactory.newInstance();
SAXParser _p = _f.newSAXParser();
XMLReader _r = _p.getXMLReader();
AbstractParser _h = AbstractParser.newAtomParser();
_r.setContentHandler(_h);
_r.parse(aSource);
return _h.getStories();
}
}
Async Task Code :
public class YourAsyncTask extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
// your load work
//return myString;
}
#Override
protected void onPostExecute(String result) {
}
}
Can someone please help me to integrate Async Task into same code. Thanks
Yes, I'd suggest IntentService too!
IntentService example
public class MyService extends IntentService {
private int STOP_DOWNLOAD = false;
public static int UPDATE_PROGRESS = 0;
public MyService() {
super("myservice");
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
protected void onHandleIntent(Intent intent) {
// Network Task : download ?
// Send some data to the receiver
Bundle resultData = new Bundle();
resultData.putInt("progress", progress);
receiver.send("update", resultData);
}
private void stopDownload() {
this.STOP_DOWNLOAD = true;
// Stop the download : use this boolean into onHandleIntent
}
}
The receiver
public class MyReceiver extends ResultReceiver {
Context context;
public MyReceiver(Context mContext) {
super(handler);
context = mContext;
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
if (resultCode == "update") {
String something = resultData.getString(MyService.SOMETHING);
}
}
}
Start the service in an Activity : startService(...)
From the onStart() of your service class make network operation
YourAsyncTask.execute(url);
Async task code
public class YourAsyncTask extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
// your load work
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
return response;
//return myString;
}
#Override
protected void onPostExecute(String result) {
//HERE CALL YOUR PARSE METHOD
//AFTER PARSING CALL buildUpdatedViews(Context aContext , stories)
}
}
Related
I am trying to make app where I am making server req and getting response, while I am getting response I showed it with notification even if apps killed. So this is why I made all this in service and after getting response I broadcast info got from server response to broadcastreceiver in activity to show info in a recyclerview.info showing while in apps on(no click on notification but continuous network req and response) as i made direct broadcast but while I click on notification nothing showing in recyclerview. how to solve this ..
NotificationActivity:
public class NotificationActivity extends AppCompatActivity {
GetPostAsyncTask backgroundTask;
ArrayList<NotificationDataClass> list;
NotificationListShowAdapter notificationListShowAdapter;
RecyclerView recyclerView;
Context contextNotificationActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification);
Intent intent=new Intent(NotificationActivity.this,ServiceClass.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startService(intent);
contextNotificationActivity=NotificationActivity.this;
recyclerView=(RecyclerView)findViewById(R.id.recyclerViewId);
/*notificationListShowAdapter=new NotificationListShowAdapter(contextNotificationActivity,list);
LinearLayoutManager layoutManager=new LinearLayoutManager(contextNotificationActivity);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(notificationListShowAdapter);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(contextNotificationActivity,
layoutManager.getOrientation());
recyclerView.addItemDecoration(dividerItemDecoration);
notificationListShowAdapter.notifyDataSetChanged();*/
}
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(broadcastReceiver,new IntentFilter("Notification"));
}
private BroadcastReceiver broadcastReceiver=new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Receiver",Toast.LENGTH_LONG).show();
String result=intent.getStringExtra("Result");
Log.v("Brd",intent.getStringExtra("Result"));
JSONObject jsonObject= null;
list=new ArrayList<>();
try {
jsonObject = new JSONObject(result);
// JSONObject codeObj=jsonObject.optJSONObject("code");
JSONArray jsonArray=jsonObject.getJSONArray("payload");
for(int i=0;i<jsonArray.length();i++){
JSONObject jsonObject1=new JSONObject(jsonArray.optString(i));
NotificationDataClass notificationDataClass=new NotificationDataClass();
notificationDataClass.setName(jsonObject1.getString("Name"));
notificationDataClass.setRemarks(jsonObject1.getString("Remarks"));
Log.v("hsdgfjgsdh", String.valueOf(jsonObject1.getInt("Type")));
if(jsonObject1.getInt("Type")==1){
notificationDataClass.setInout("In");
}else {
notificationDataClass.setInout("Out");
}
notificationDataClass.setTime(jsonObject1.getString("DateTime"));
list.add(i,notificationDataClass);
}
notificationListShowAdapter=new NotificationListShowAdapter(context,list);
LinearLayoutManager layoutManager=new LinearLayoutManager(context);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(notificationListShowAdapter);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context,
layoutManager.getOrientation());
recyclerView.addItemDecoration(dividerItemDecoration);
notificationListShowAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
};
#Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(broadcastReceiver);
}
}
serviceClass:
public class ServiceClass extends Service {
GetPostAsyncTask_ServiceClass backgroundTask;
Context context;
Handler handler;
Runnable runnable;
LocalBroadcastManager localBroadcastManager;
int iny=1;
#Override
public void onCreate() {
super.onCreate();
localBroadcastManager=LocalBroadcastManager.getInstance(this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
context=getApplicationContext();
handler=new Handler();
runnable=new Runnable() {
#Override
public void run() {
String queryForNotification=null;
try {
queryForNotification = URLEncoder.encode("dateTime", "UTF-8") + "=" + URLEncoder.encode("03/13/2017", "UTF-8");
Log.v("INRTR","out"+iny++);
backgroundTask=new GetPostAsyncTask_ServiceClass(context);
backgroundTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,"GET","GetHrOnDutyActivityByDate?"+queryForNotification,"");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// ((Vibrator) getSystemService(VIBRATOR_SERVICE)).vibrate(1000);
handler.postDelayed(runnable,10000);
}
};
handler.postDelayed(runnable,10000);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
//Asynctask
private class GetPostAsyncTask_ServiceClass extends AsyncTask<String, Void, String> {
// public AsyncResult asyncResult;
ProgressDialog progressDialog;
private final String baseUrl = "http://192.168.0.6:880/MobileAPI/";
Context context;
GetPostAsyncTask_ServiceClass(Context context) {
this.context = context;
// this.asyncResult = asyncResult;
}
#Override
protected void onPreExecute() {
//Toast.makeText(context,"Loading..",Toast.LENGTH_SHORT).show();
progressDialog = new ProgressDialog(context);
// progressDialog.show();
}
#Override
protected String doInBackground(String... args) {
try {
// setting the URL
URL url = new URL(baseUrl + args[1]);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.addRequestProperty("Apiuser", "SDLPayrollAPI");
httpURLConnection.addRequestProperty("Apikey", "DFGHJ*UH45445^TY");
// setting the method type
httpURLConnection.setRequestMethod(args[0]);
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
// setting the identification key name with query params
bufferedWriter.write(args[2]);
bufferedWriter.flush();
bufferedWriter.close();
httpURLConnection.connect();
String line = "";
String res = "";
// prepare the output buffer
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
while ((line = bufferedReader.readLine()) != null) {
res += line;
}
inputStream.close();
httpURLConnection.disconnect();
return res.toString();
} catch (IOException e) {
Log.v("PesDSS","doBCa"+e.toString());
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.v("PesDSS","out"+result);
Intent intent1;
// progressDialog.dismiss();
if (result != null) {
// asyncResult.asyncResult(result);
Log.v("PesDSS","in"+result);
//notification
NotificationCompat.Builder notification=new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.systech_logo)
.setContentTitle("Notification")
.setContentText("Delivered")
.setAutoCancel(true)
;
intent1 = new Intent(context, NotificationActivity.class);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent1.setAction("Notification");
intent1.putExtra("Result",result);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent1);
TaskStackBuilder taskStackBuilder=TaskStackBuilder.create(context);
taskStackBuilder.addParentStack(NotificationActivity.class);
taskStackBuilder.addNextIntent(intent1);
PendingIntent pendingIntent=taskStackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
// PendingIntent pendingIntent=PendingIntent.getBroadcast(context,0,intent1,PendingIntent.FLAG_CANCEL_CURRENT);
notification.setContentIntent(pendingIntent);
NotificationManager notificationManager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0,notification.build());
}
}
}
}
Notification data class:
public class NotificationDataClass {
String name;
String remarks;
String inout;
String time;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemarks() {
return remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
public String getInout() {
return inout;
}
public void setInout(String inout) {
this.inout = inout;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
}
I tried to follow solutions from Stack Overflow but I could not solve it. Any help would be appreciated!
FYI onReceive() is called only when your current activity is in foreground or visible. For doing task on click of notification, when your activity/app is in background you should also do the same thing in onCreate() which you have done in onReceive() like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification);
Intent notificationIntent = getIntent.getStringExtra("Result");
if(notificationIntent != null){
//do whatever you have done in onReceive().
}
}
I have a regular class (SOAP.java) which I added a function to call a webservice, I have the URL and other informations in res/values/strings.xml.
My Intent Service (which is called every 2 minutes) and a Fragment of my App are using the function in SOAP.java, but I can't get access to the strings, error:
08-19 03:47:19.730 16543-17323/fr.solutis.solutis E/AndroidRuntime﹕
FATAL EXCEPTION: IntentService[EnvoieService]
Process: fr.solutis.solutis, PID: 16543
java.lang.NullPointerException
at fr.solutis.solutis.SOAP.(SOAP.java:22)
at fr.solutis.solutis.notifications.EnvoieService.onHandleIntent(EnvoieService.java:96)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.os.HandlerThread.run(HandlerThread.java:61)
SOAP.java:
public class SOAP {
private Context context;
public SOAP(Context current){
this.context = current;
}
String NAMESPACE = context.getResources().getString(R.string.NAMESPACE);
String URL = context.getResources().getString(R.string.URL);
String SOAP_ACTION = context.getResources().getString(R.string.SOAP_ACTION);
private static String TAG = SOAP.class.getSimpleName();
public Reponse envoieDemande(String method, String xml) {
code
}
}
IntenService:
public class EnvoieService extends IntentService {
DatabaseHandler db = new DatabaseHandler(this);
public EnvoieService() {
super("EnvoieService");
}
#Override
protected void onHandleIntent(Intent intent) {
List<Demande> demandes = db.getAllDemandesRenvoie();
String TAG = EnvoieService.class.getSimpleName();
if (!(demandes.isEmpty())) {
for (Demande cn : demandes) {
...
SOAP soap = new SOAP(this);
Reponse ret = soap.envoieDemande("SendLead", xml);
}
} else {
cancelAlarm();
}
}
public void cancelAlarm() {
Intent intent = new Intent(getApplicationContext(), EnvoieReceiver.class);
final PendingIntent pIntent = PendingIntent.getBroadcast(this, EnvoieReceiver.REQUEST_CODE,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pIntent);
}
}
Fragment:
public class DemandeGratuite extends android.support.v4.app.Fragment {
...
{
{
{
{
{
{
{
{
AsyncSoapCall task = new AsyncSoapCall();
task.execute();
getChildFragmentManager().popBackStack();
mListener.onInteraction(6);
} catch (FileNotFoundException e) {
System.err.println("FileNotFoundException: " + e.getMessage());
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
}
}
}
}
);
}
private class AsyncSoapCall extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
SOAP soap = new SOAP(getContext());
Reponse ret = soap.envoieDemande("SendLead", xml);
return null;
}
#Override
protected void onPostExecute(Void result) {
Log.i(TAG, "onPostExecute");
}
#Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}
#Override
protected void onProgressUpdate(Void... values) {
Log.i(TAG, "onProgressUpdate");
}
}
}
Resources cannot be accesed from the context of a service. You must use the context of an activity or u can try to use this class
public class App extends Application {
private static Context mContext;
public static Resources getResources() {
return mContext.getResources();
}
public void onCreate() {
super.onCreate();
mContext = getApplicationContext();
}
}
and then use the function App.getResources().getString(your_string_id) from wherever you want
I have an Activity which constructs a RESTManager class (used to make an asynchronous call to the server and return data to the Activity).
However, after I construct my RESTManager and call the server using
//Retrieve data from server
RESTManager m = new RESTManager(this,getApplicationContext());
//Set the data list
m.delegate=this;
m.retrieveRoomData();
the server call does not go through until I turn off bluetooth scanning.
However, I start my bluetooth scan immediately after the RESTManager as such:
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.setBackgroundScanPeriod(1100l);
beaconManager.setBackgroundBetweenScanPeriod(100l);
beaconManager.setForegroundScanPeriod(1100l);
beaconManager.setForegroundBetweenScanPeriod(100l);
//Set the custom BeaconLayout for iBeacons
if (myPref.getBoolean("layoutSet", true)) {
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24"));
backgroundPowerSaver = new BackgroundPowerSaver(this);
Log.v("Beacon Layout", "Beacon Layout Set");
myPref.edit().putBoolean("layoutSet", false).apply();
myPref.edit().commit();
}
beaconManager.bind(this);
I am not getting any error.
Is there any reason why my AsyncTask from RESTManager would hang from the bluetooth scans?
Relevant code:
RESTManager class
public class RESTManager {
private DateTime lastUpdate = DateTime.now();
public AsyncResponse delegate=null;
private SharedPreferences mPrefs;
private SharedPreferences.Editor preferenceEditor;
private ArrayList<RoomData> roomDataList = new ArrayList<RoomData>();
private ArrayList<MeetingData> meetingDataList = new ArrayList<MeetingData>();
private Activity currentActivity;
private Context context;
public RESTManager(Activity currentActivity, Context context) {
this.currentActivity = currentActivity;
this.context = context;
mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
}
//Todo update meeting data logic
public ArrayList<MeetingData> retrieveMeetingDataFromServer() {
return null;
}
public void retrieveRoomData() {
new CallServerForRoomData().execute();
}
//TODO add timestamping logic.
private class CallServerForRoomData extends AsyncTask<String, Void, String> {
String myJsonData = "";
#Override
protected String doInBackground(String... params) {
//If the data isn't cached, call the server.
if (!mPrefs.contains("RoomData")) {
try {
setupHttpClient();
HttpClient myClient = new HttpClient(RequestMethod.GET, "http://10.184.46.217:9012/v1/rooms", new HttpHeaders(), null, null);
myClient.connect();
HttpResponse mR = myClient.processResponse();
myJsonData = mR.getServerResponseAsString();
System.out.println(myJsonData);
preferenceEditor = mPrefs.edit();
preferenceEditor.putString("RoomData", myJsonData);
preferenceEditor.commit();
setRoomDataList(convertRoomDataJson(myJsonData));
return "server";
} catch (HttpClientException e) {
e.printStackTrace();
}
}
//If it is cached, retrieve the data locally.
else {
setRoomDataList(convertRoomDataJson(mPrefs.getString("RoomData", "NULL")));
return "local";
}
return "Done";
}
protected void onPostExecute(final String result) {
delegate.dataFinishedRetrieving(getRoomDataList());
// setRoomDataList(convertRoomDataJson(myJsonData));
currentActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(context, "Data retrieved on " + result + " storage", Toast.LENGTH_SHORT).show();
}
});
}
}
/**
* AsyncTask for retrieving a room's meeting data.
* Pass in the room's unique identifier as a parameter of the execute method.
*/
//TODO add timestamping logic
private class CallServerForMeetingData extends AsyncTask<String, Void, String> {
String myJsonData = "";
#Override
protected String doInBackground(String... params) {
try {
setupHttpClient();
HttpClient myClient = new HttpClient(RequestMethod.GET, "http://10.184.146.217:9012/v1/room/" + params[0] + "/schedule", new HttpHeaders(), null, null);
myClient.connect();
HttpResponse mR = myClient.processResponse();
myJsonData = mR.getServerResponseAsString();
} catch (HttpClientException e) {
e.printStackTrace();
}
//Set the converted MeetingData to the RoomData object
for (RoomData e : roomDataList) {
if (e.getObjectId() == params[0]) {
e.setMeetingData(convertMeetingDataJson(myJsonData));
}
}
return "Done";
}
}
//Initializes the HTTPClient and attaches it to the application lifecycle.
public void setupHttpClient() {
HttpCacheManager.init(Application.getAppContext());
}
public ArrayList<MeetingData> convertMeetingDataJson(String JsonData) {
final Gson gson = initCustomGSON();
Type MeetingDataListType = null;
if (JsonData != "") {
MeetingDataListType = new TypeToken<ArrayList<MeetingData>>() {
}.getType();
}
return (gson.fromJson(JsonData, MeetingDataListType));
}
public ArrayList<RoomData> convertRoomDataJson(String JsonData) {
final Gson gson = initCustomGSON();
Type RoomDataListType = null;
if (!JsonData.equals("")) {
RoomDataListType = new TypeToken<ArrayList<RoomData>>() {
}.getType();
roomDataList = (gson.fromJson(JsonData, RoomDataListType));
}
roomDataList = (gson.fromJson(JsonData, RoomDataListType));
for (RoomData e : roomDataList) {
Log.v("RoomData name", e.getName());
Log.v("RoomData roomId", e.getObjectId());
//Log.v("RoomData imageUrl", e.getImageUrl());
if (e.getBeacons() != null) {
Log.v("Number of beacons", e.getBeacons().toString());
}
}
return roomDataList;
}
/**
* Initializes the GSON Json Decoder with the custom JodaTime serializers.
*
* #return
*/
public Gson initCustomGSON() {
final GsonBuilder builder = new GsonBuilder();
JodaTimeConverters converter = new JodaTimeConverters();
converter.registerAll(builder);
return builder.create();
}
public ArrayList<RoomData> getRoomDataList() {
return roomDataList;
}
public void setRoomDataList(ArrayList<RoomData> roomDataList) {
this.roomDataList = roomDataList;
}
public void setMeetingDataListForRoom(RoomData whichRoom) {
new CallServerForMeetingData().execute(whichRoom.getObjectId());
}
}
i want to send a list from Background service to activity in android
public class MyService extends Service{
private String receiverUserInfoId;
private String loginUserInfoId;
private String orgMsgThreadId;
private String userName = "Vipin";
DatabaseHelper db;
MessageListActivity ms;
private String userAvatarURL;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
db = new DatabaseHelper(getApplicationContext());
Bundle extra = intent.getExtras();
loginUserInfoId = extra.getString("LoginUserInfoId");
receiverUserInfoId=extra.getString("UserInfoId");
orgMsgThreadId = extra.getString("OrgMessageThreadId");
userName=extra.getString("UserName");
userAvatarURL=extra.getString("UserAvatarURL");
new syncMessageFromServer().execute();
new SyncPendingMessageToServer();
return super.onStartCommand(intent, flags, startId);
}
private class syncMessageFromServer extends AsyncTask<Void, Integer, String> {
#Override
protected void onPreExecute() {
// setting progress bar to zero
//progressBar.setProgress(0);
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Integer... progress) {
}
#Override
protected String doInBackground(Void... params) {
return uploadFile();
}
#SuppressWarnings("deprecation")
private String uploadFile() {
String str = "";
HttpResponse response;
HttpClient myClient = new DefaultHttpClient();
HttpPost myConnection = new HttpPost("http://192.168.1.2/AndroidApp/GetMessage?loginUserInfoId=" + loginUserInfoId + "&recieverUserInfoId=" + receiverUserInfoId + "&isPendingToSynce=" + true);
try {
response = myClient.execute(myConnection);
str = EntityUtils.toString(response.getEntity(), "UTF-8");
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
JSONArray jArray = new JSONArray(str);
for (int i = 0; i <= jArray.length() - 1; i++) {
JSONObject row = jArray.getJSONObject(i);
ChatMessage cm = new ChatMessage();
cm.setOriginalMsgThreadId(row.getString("MessageThreadId"));
cm.setSenderUserInfoId(row.getString("SenderUserId"));
cm.setReceiverUserInfoId(row.getString("MultipleReceiversId"));
cm.setMessageStatus("SENT");
cm.setIsPending(0);
cm.setMessageText(row.getString("MessageText"));
cm.setMediaURL(offlineFileURL);
cm.setThumbImage(offlineFileURL);
cm.setMediaMIMEType("");
cm.setMediaSize(0);
cm.setMediaName("");
cm.setLatitude("");
cm.setLongitude("");
cm.setSendTimeStamp(row.getString("SendTime"));
cm.setReceiveTimeStamp(row.getString("ReadTime"));
long messageThreadId = db.SendMessage(cm);
MessageListActivity mLA = new MessageListActivity();
mLA.SetListData(cm);
}
} catch (JSONException e) {
e.printStackTrace();
}
return str;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
new syncMessageFromServer().execute();
}
}
}
i want to send ChatMessage to the SetListData() function in MessageListActivity class how can i do this. just i want to refresh my list adapter to new message fetched by the server
You need to use a messenger if you want to communicate with the activity. Change your service like this:
public class MyService extends Service{
public static int MESSENGER = 1;
public static int JSONARRAY = 2;
private String receiverUserInfoId;
private String loginUserInfoId;
private String orgMsgThreadId;
private String userName = "Vipin";
DatabaseHelper db;
MessageListActivity ms;
private String userAvatarURL;
Messenger messageActivity;
final Messenger mMessenger = new Messenger(new IncomingHandler());
class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch(msg.what){
case MESSENGER:
messageActivity = msg.replyTo;
break;
}
}
#Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
db = new DatabaseHelper(getApplicationContext());
Bundle extra = intent.getExtras();
loginUserInfoId = extra.getString("LoginUserInfoId");
receiverUserInfoId=extra.getString("UserInfoId");
orgMsgThreadId = extra.getString("OrgMessageThreadId");
userName=extra.getString("UserName");
userAvatarURL=extra.getString("UserAvatarURL");
new syncMessageFromServer().execute();
new SyncPendingMessageToServer();
return super.onStartCommand(intent, flags, startId);
}
private class syncMessageFromServer extends AsyncTask<Void, Integer, String> {
#Override
protected void onPreExecute() {
// setting progress bar to zero
//progressBar.setProgress(0);
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Integer... progress) {
}
#Override
protected String doInBackground(Void... params) {
return uploadFile();
}
#SuppressWarnings("deprecation")
private String uploadFile() {
String str = "";
HttpResponse response;
HttpClient myClient = new DefaultHttpClient();
HttpPost myConnection = new HttpPost("http://192.168.1.2/AndroidApp/GetMessage?loginUserInfoId=" + loginUserInfoId + "&recieverUserInfoId=" + receiverUserInfoId + "&isPendingToSynce=" + true);
try {
response = myClient.execute(myConnection);
str = EntityUtils.toString(response.getEntity(), "UTF-8");
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
JSONArray jArray = new JSONArray(str);
messageActivity.send(Message.obtain(null, JSONARRAY, jArray.toString()));
} catch (JSONException e) {
e.printStackTrace();
}
return str;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
new syncMessageFromServer().execute();
}
}
}
And in your activity add the following methods:
public class MyListActivity extends Activity{
public static Messenger mService = null;
public final Messenger mMessenger = new Messenger(new IncomingHandler());
public boolean mIsBound = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_participant);
doBindService();
}
public void doBindService() {
if (!mIsBound) {
context.bindService(new Intent(context,
MyService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
mService = new Messenger(service);
try {
Message msg = Message.obtain(null, MyService.MESSENGER);
msg.replyTo = mMessenger;
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void onServiceDisconnected(ComponentName className) {
mService = null;
}
};
class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MyService.JSONARRAY:
buildTheChatMessage((JsonArray)msg.obj);
break;
default:
super.handleMessage(msg);
}
}
}
public void buildTheChatMessage(JsonArray arr){
ChatMessage cm = new ChatMessage();
cm.setOriginalMsgThreadId(row.getString("MessageThreadId"));
cm.setSenderUserInfoId(row.getString("SenderUserId"));
cm.setReceiverUserInfoId(row.getString("MultipleReceiversId"));
cm.setMessageStatus("SENT");
cm.setIsPending(0);
cm.setMessageText(row.getString("MessageText"));
cm.setMediaURL(offlineFileURL);
cm.setThumbImage(offlineFileURL);
cm.setMediaMIMEType("");
cm.setMediaSize(0);
cm.setMediaName("");
cm.setLatitude("");
cm.setLongitude("");
cm.setSendTimeStamp(row.getString("SendTime"));
cm.setReceiveTimeStamp(row.getString("ReadTime"));
setListData(cm);
}
}
This way your activity is bound to the service and you can communicate between them. I wish you get the idea from this code and implement what you need.
Here's a source to read more about this methods.
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)
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 ;-)
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. :)