I have a service that pass String of Json to MainActivity:
GetSubjects.class :
public class GetSubjects extends Service {
String URL = "http://webservice.jim.com/YYY/XXXX.asmx";
String Webresponse = "IS NULL ?";
int scode = 1597536485;
String result;
public final static String MY_ACTION = "MY_ACTION";
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(final Intent intent, int flags, final int startId) {
Runnable r = new Runnable() {
#Override
public void run() {
handleStart(intent, startId);
}
};
Thread t = new Thread(r);
t.start();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
void handleStart(Intent intent, int startId) {
try {
Params_GetSubjects param = new Params_GetSubjects(scode);
result = new mGetSubjects().execute(param).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
public class mGetSubjects extends AsyncTask<Params_GetSubjects, String, String> {
String NAMESPACE = "http://tempuri.org/";
String METHOD_NAME = "Get";
String SOAP_ACTION = "http://tempuri.org/Get";
#Override
protected String doInBackground(Params_GetSubjects... params) {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("scode", params[0].Scode);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE conn = new HttpTransportSE(URL);
Object object;
try {
conn.call(SOAP_ACTION, envelope);
//SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
object = envelope.getResponse();
Webresponse = object.toString();
} catch (Exception e) {
e.printStackTrace();
return "NULL";
}finally {
ThreadFinish threadfinish = new ThreadFinish();
threadfinish.start();
return Webresponse;
}
}
}
public class ThreadFinish extends Thread{
#Override
public void run() {
try {
Intent intent = new Intent();
intent.setAction(MY_ACTION);
intent.putExtra("DATAPASSED", result);
sendBroadcast(intent);
}catch (Exception e){
e.printStackTrace();
}finally {
stopSelf();
}
}
}
}
Here is my MainActivity :
public class MainActivity extends AppCompatActivity {
MyReceiver myReceiver;
private RecyclerView.LayoutManager layoutManager;
private DrawerAdapter mDrawerAdapter;
private RecyclerView mRecyclerView;
List<DrawerItem> draweritemList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(MainActivity.this, GetSubjects.class));
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch (id) {
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START);
return true;
case R.id.action_settings:
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onStart() {
myReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(GetSubjects.MY_ACTION);
registerReceiver(myReceiver, intentFilter);
super.onStart();
}
#Override
protected void onStop() {
this.unregisterReceiver(myReceiver);
super.onStop();
}
private class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
String datapassed = arg1.getExtras().getString("DATAPASSED");
Log.i("ASDQWRRYGH",datapassed);
draweritemList = JsonParser.parseFeed(datapassed);
for (int i=0;i < draweritemList.size();i++)
{
Log.i("ASDQWRRYGH",draweritemList.get(i).getTitle());
}
}
}
}
And here is my JsonParer :
public class JsonParser {
public static List<DrawerItem> parseFeed(String content) {
try {
JSONObject jsonRootObject = new JSONObject(content);
JSONArray jsonArray = jsonRootObject.optJSONArray("Rows");
List<DrawerItem> draweritemList = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
DrawerItem draweritem = new DrawerItem();
draweritem.setId(obj.getString("Id"));
draweritem.setTitle(obj.getString("Title"));
draweritemList.add(draweritem);
}
return draweritemList;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
}
often get me result from service but often get me bellow error ,what can i do?:
You've got three additional threads executing in your Service; the AsyncTask and two Threads. The first Thread is executing your AsyncTask, but it's blocking because you're calling get() on it to assign the return value to the return String. When the network transaction finishes in the AsyncTask, it starts another Thread to send the broadcast, and this happens before doInBackground() can return to set the value of the return String, which ends up getting broadcasted while it's still null.
The simplest fix is to move the broadcast to after the result = ... line, and get rid of the ThreadFinish class.
It might be preferable, though, to execute everything sequentially in a single thread; either in the AsyncTask, or the Thread executing your Runnable.
Related
Ok, I got a Togglebutton that starts a service. The service starts a new Thread in onStartCommand. In this Thread an Asynctask is executed.
Now I want this Asynctask to be executed for example every 5 seconds. The Asynctask checks if the website is available.
-> if no, after 5 secs check again
-> if yes, show message and stop
Whats the best method with my already present code:
public class NotifiyService extends Service {
String savedsa;
Thread Th1;
boolean value;
final class TheThread implements Runnable{
int serviceID;
String savedsa1;
TheThread(int serviceID,String savedsa){
this.serviceID = serviceID;
this.savedsa1 = savedsa;
}
#Override
public void run() {
HttpTaskParams httpparams = new HttpTaskParams(value,savedsa1);
new HttpTask().execute(httpparams);
}
}
public NotifiyService() {
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
SharedPreferences sharedPreferences7 = getSharedPreferences("Prefsa",MODE_WORLD_READABLE);
savedsa = sharedPreferences7.getString("keysa","");
Toast.makeText(NotifiyService.this,getResources().getString(R.string.MonStarted)+ "\n" + savedsa,Toast.LENGTH_LONG).show();
Th1 = new Thread(new TheThread(startId,savedsa));
Th1.start();
return START_STICKY;
}
#Override
public void onDestroy() {
//super.onDestroy();
Toast.makeText(NotifiyService.this,getResources().getString(R.string.MonStopped), Toast.LENGTH_LONG).show();
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
private static class HttpTaskParams{
boolean value;
String address;
HttpTaskParams(boolean value, String address){
this.value = value;
this.address = address;
}
}
private class HttpTask extends AsyncTask<HttpTaskParams,Void,Boolean>{
#Override
protected Boolean doInBackground(HttpTaskParams... params) {
boolean value = params[0].value;
String address = params[0].address;
try {
URL url = new URL(address);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("HEAD");
httpURLConnection.setConnectTimeout(3000);
httpURLConnection.setReadTimeout(3000);
httpURLConnection.connect();
value = true;
return value;
} catch (MalformedURLException e) {
e.printStackTrace();
value = false;
return value;
} catch (IOException e) {
e.printStackTrace();
value = false;
return value;
}
}
#Override
protected void onPostExecute(Boolean result) {
if(result){
Toast.makeText(NotifiyService.this,"true",Toast.LENGTH_SHORT).show();
//Notification in Status Bar
NotificationCompat.Builder builder = new NotificationCompat.Builder(NotifiyService.this);
builder.setSmallIcon(R.drawable.dummy);
Intent intent = new Intent(NotifiyService.this, Main2Activity.class);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(NotifiyService.this,0,intent,0);
builder.setContentIntent(pendingIntent);
builder.setLights(Color.YELLOW,600,600);
builder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.dummy));
builder.setContentTitle(getResources().getString(R.string.newNotify));
builder.setContentText(getResources().getString(R.string.newNotify2));
builder.setAutoCancel(true);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(1,builder.build());
}
else{
Toast.makeText(NotifiyService.this,"false",Toast.LENGTH_SHORT).show();
}
}
}
}
EDIT:
#Override
public void run() {
ScheduledExecutorService checkreg = Executors.newScheduledThreadPool(1);
scheduledFuture = checkreg.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
HttpTaskParams httpparams = new HttpTaskParams(value, savedsa1);
new HttpTask().execute(httpparams);
}
}, 0, 20, TimeUnit.SECONDS);}
#Override
public void onDestroy() {
//super.onDestroy();
Th1.interrupt();
scheduledFuture.cancel(false);
Toast.makeText(NotifiyService.this,getResources().getString(R.string.MonStopped), Toast.LENGTH_LONG).show();
stopSelf();
}
I think a ScheduledExecutorService could help you.
Please check this answer.
Please let me know if this helps you.
try this /**
* Loads exchange rates form network periodically
* Returns results in broadcast message.
* Created by koss on 19.02.16.
* */
public class EcbEuropeService extends Service {
public static final String ECB_URL = "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml";
public static final int UPDATE_PERIOD = 30000;
public static final int UPDATE_TICK = 1000;
public static final String NOTIFICATION = "koss.ru.oneclickrate.receiver";
public static final String EXTRA_CURRENCIES_MAP = "extra_currencies_map";
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
getUrlData();
return Service.START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public Cubes getUrlData() {
(new AsyncTask<Object, Object, Cubes>() {
Map<CurrencyType, BigDecimal> result = new EnumMap<CurrencyType, BigDecimal>(CurrencyType.class);
#Override
protected Cubes doInBackground(Object... params) {
Cubes cubes = new Cubes();
InputStream is = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(ECB_URL);
urlConnection = (HttpURLConnection) url.openConnection();
is = urlConnection.getInputStream();
cubes = EcbEuropeResponseParser.parse(is);
} catch (Exception e) {
e.printStackTrace();
} finally {
if(urlConnection!=null) IOUtils.close(urlConnection);
if(is!=null) IOUtils.closeQuietly(is);
return cubes;
}
}
#Override
protected void onPostExecute(Cubes map) {
super.onPostExecute(map);
sendBroadcastMessage(map);
startTimer();
}
}).execute();
return null;
}
/**
* Restarts timer
* */
public void startTimer() {
cdt.cancel();
cdt.start();
}
CountDownTimer cdt = new CountDownTimer(UPDATE_PERIOD, UPDATE_TICK) {
#Override
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
getUrlData();
}
};
private void sendBroadcastMessage(Cubes currenciesMap) {
Intent intent = new Intent(NOTIFICATION);
intent.putExtra(EXTRA_CURRENCIES_MAP, currenciesMap);
sendBroadcast(intent);
}
}
I created a sample app and using Pushwoosh I am able to receive the notification, and on click, it opens app, however when I want to send additional data then it does not display that.
I have added the code below.
I have searched for relevant questions but nothing elates. This is the data i'm trying to pass to app.
{"employees":[{"firstName":"John", "lastName":"Doe"},{"firstName":"Anna", "lastName":"Smith"},{"firstName":"Peter", "lastName":"Jones"}]}
Here is the MainActivity
public class MainActivity extends AppCompatActivity
{
private static final String bTAG = "example";
boolean broadcastPush = true;
JSONAdapter jsonAdapter;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<String> listB = new ArrayList<String>();
String userNameText = "";
JSONObject json = null;
try
{
json = new JSONObject(userNameText);
} catch (JSONException e)
{
e.printStackTrace();
}
JSONArray array = null;
try
{
JSONObject userdataObject = json.getJSONObject("userdata");
array = userdataObject.getJSONArray("employees");
}
catch (JSONException e)
{
e.printStackTrace();
}
//Set the adapter as the adapter of choice for our list
jsonAdapter = new JSONAdapter(this, array);
//here we register receivers for push notifications
registerReceivers();
final PushManager pushManager = PushManager.getInstance(this);
//Now we start the push manager, this will count app open for Pushwoosh stats as well
try
{
pushManager.onStartup(this);
}
catch (Exception e)
{
e.printStackTrace();
}
//now we register for push notification
pushManager.registerForPushNotifications();
//then check launch notification
String launchNotification = pushManager.getLaunchNotification();
if(launchNotification != null)
{
Log.d(bTAG, "Launch notification received" + launchNotification);
}
else
{
Log.d(bTAG, "No notification received");
}
//Clear application icon badge number
pushManager.setBadgeNumber(0);
}
/**
* Called when the activity receives a new intent.
*/
public void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
//have to check if we've got new intent as a part of push notification
try {
checkMessage(intent);
} catch (JSONException e)
{
e.printStackTrace();
}
}
//Registration receiver
BroadcastReceiver mBroadcastReceiver = new BaseRegistrationReceiver()
{
#Override
public void onRegisterActionReceive(Context context, Intent intent)
{
try {
checkMessage(intent);
} catch (JSONException e) {
e.printStackTrace();
}
}
};
//Push message receiver
private BroadcastReceiver mReceiver = new BasePushMessageReceiver()
{
#Override
protected void onMessageReceive(Intent intent)
{
//JSON_DATA_KEY contains JSON payload of push notification.
try
{
doOnMessageReceive(intent.getExtras().getString(JSON_DATA_KEY));
} catch (JSONException e)
{
e.printStackTrace();
}
}
};
//Registration of the receivers
public void registerReceivers()
{
IntentFilter intentFilter = new IntentFilter(getPackageName() + ".action.PUSH_MESSAGE_RECEIVE");
if (broadcastPush)
registerReceiver(mReceiver, intentFilter, getPackageName() +".permission.C2D_MESSAGE", null);
registerReceiver(mBroadcastReceiver, new IntentFilter(getPackageName() + "." + PushManager.REGISTER_BROAD_CAST_ACTION));
}
public void unregisterReceivers()
{
//Unregister receivers on pause
try
{
unregisterReceiver(mReceiver);
}
catch (Exception e)
{
// pass.
}
try
{
unregisterReceiver(mBroadcastReceiver);
}
catch (Exception e)
{
//pass through
}
}
#Override
public void onResume()
{
super.onResume();
//Re-register receivers on resume
registerReceivers();
}
#Override
public void onPause()
{
super.onPause();
//Unregister receivers on pause
unregisterReceivers();
}
/**
* Will check PushWoosh extras in this intent, and fire actual method
*
* #param intent activity intent
*/
private void checkMessage(Intent intent) throws JSONException {
if (null != intent)
{
if (intent.hasExtra(PushManager.PUSH_RECEIVE_EVENT))
{
doOnMessageReceive(intent.getExtras().getString(PushManager.PUSH_RECEIVE_EVENT));
}
else if (intent.hasExtra(PushManager.REGISTER_EVENT))
{
doOnRegistered(intent.getExtras().getString(PushManager.REGISTER_EVENT));
}
else if (intent.hasExtra(PushManager.UNREGISTER_EVENT))
{
doOnUnregistered(intent.getExtras().getString(PushManager.UNREGISTER_EVENT));
}
else if (intent.hasExtra(PushManager.REGISTER_ERROR_EVENT))
{
doOnRegisteredError(intent.getExtras().getString(PushManager.REGISTER_ERROR_EVENT));
}
else if (intent.hasExtra(PushManager.UNREGISTER_ERROR_EVENT))
{
doOnUnregisteredError(intent.getExtras().getString(PushManager.UNREGISTER_ERROR_EVENT));
}
resetIntentValues();
}
}
public void doOnRegistered(String registrationId)
{
Log.d(bTAG, "registered: " + registrationId);
}
public void doOnRegisteredError(String errorId)
{
Log.d(bTAG, "registration error: " + errorId);
}
public void doOnUnregistered(String registrationId)
{
Log.d(bTAG, "unregistered: " + registrationId);
}
public void doOnUnregisteredError(String errorId)
{
Log.d(bTAG, "deregistration error: " + errorId);
}
public void doOnMessageReceive(String message) throws JSONException
{
Log.d(bTAG, "received push: " + message);
JSONObject json = new JSONObject(message);
JSONArray array = json.getJSONArray("employees");
for (int i=0; i<array.length(); i++)
{
JSONObject o = array.getJSONObject(i);
System.out.println(o);
}
}
/**
* Will check main Activity intent and if it contains any PushWoosh data, will clear it
*/
private void resetIntentValues()
{
Intent mainAppIntent = getIntent();
if (mainAppIntent.hasExtra(PushManager.PUSH_RECEIVE_EVENT))
{
mainAppIntent.removeExtra(PushManager.PUSH_RECEIVE_EVENT);
}
else if (mainAppIntent.hasExtra(PushManager.REGISTER_EVENT))
{
mainAppIntent.removeExtra(PushManager.REGISTER_EVENT);
}
else if (mainAppIntent.hasExtra(PushManager.UNREGISTER_EVENT))
{
mainAppIntent.removeExtra(PushManager.UNREGISTER_EVENT);
}
else if (mainAppIntent.hasExtra(PushManager.REGISTER_ERROR_EVENT))
{
mainAppIntent.removeExtra(PushManager.REGISTER_ERROR_EVENT);
}
else if (mainAppIntent.hasExtra(PushManager.UNREGISTER_ERROR_EVENT))
{
mainAppIntent.removeExtra(PushManager.UNREGISTER_ERROR_EVENT);
}
setIntent(mainAppIntent);
}
}
And here is the Adapter
class JSONAdapter extends BaseAdapter
{
private final Activity activity;
private final JSONArray jsonArray;
public JSONAdapter (Activity activity, JSONArray jsonArray)
{
assert activity != null;
assert jsonArray != null;
this.jsonArray = jsonArray;
this.activity = activity;
}
#Override public int getCount() {
if(null==jsonArray)
return 0;
else
return jsonArray.length();
}
#Override public JSONObject getItem(int position) {
if(null==jsonArray) return null;
else
return jsonArray.optJSONObject(position);
}
#Override public long getItemId(int position) {
JSONObject jsonObject = getItem(position);
return jsonObject.optLong("id");
}
#Override public View getView(int position, View convertView, ViewGroup parent)
{
if (convertView == null)
convertView = activity.getLayoutInflater().inflate(R.layout.user_name_list, null);
TextView text = (TextView)convertView.findViewById(R.id.text);
JSONObject json_data = getItem(position);
if(null!=json_data )
{
try {
text.setText(json_data.getString("firstName"));
} catch (JSONException e) {
e.printStackTrace();
}
}
return convertView;
}
}
Please assist as I'm not too sure how to get the additional data I added on Pushwoosh to display in the app without hard coding it.
I am developing a news app which performs Async task, but during the running of the Async task if the internet connection is lost the app crashes. I tried solving the issue by Using a broadcast receiver and cancel the async task when connection is lost but the problem still persist. Below is my full activity source code.
public class News extends AppCompatActivity{
// Declare Variables
JSONObject jsonobject;
JSONArray jsonarray;
GridView gridview;
GridViewAdapter adapter;
ProgressDialog mProgressDialog;
ArrayList<HashMap<String, String>> arraylist;
Toolbar mToolbar;
static String NEWS = "news";
static String ID = "id";
static String PROFILE_PIC = "news_pic";
DownloadNews downloader;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news);
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(networkStateReceiver, filter);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
gridview = (GridView) findViewById(R.id.discoverGrid);
downloader = new DownloadNews();
ConnectionDetector cd = new ConnectionDetector(getApplicationContext());
if (!cd.isConnectingToInternet()) {
Toast.makeText(getApplicationContext(),"Couldn't refresh",Toast.LENGTH_SHORT).show();
}
else
{
downloader.execute();
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run() {
if ( downloader.getStatus() == AsyncTask.Status.RUNNING ){
downloader.cancel(true);
linlaHeaderProgress.setVisibility(View.GONE);
Toast.makeText(getApplicationContext(),"Internet Connection is Down",Toast.LENGTH_SHORT).show();
}
else if(downloader.getStatus() == AsyncTask.Status.FINISHED){
linlaHeaderProgress.setVisibility(View.GONE);
}
}
}, 15000 );
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.news, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
int id = item.getItemId();
if (id == R.id.action_search) {
return true;
}
else if (id == android.R.id.home) {
onBackPressed();
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
private class DownloadNews extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
while(true){
if (isCancelled())
break;
}
arraylist = new ArrayList<HashMap<String, String>>();
// Retrieve JSON Objects from the given URL address
try {
try {
jsonobject = JSONfunctions
.getJSONfromURL("http://www.example.com/app/news.php");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (ConnectTimeoutException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (SocketTimeoutException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
// Locate the array name in JSON
jsonarray = jsonobject.getJSONArray("news");
for (int i = 0; i < jsonarray.length(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
jsonobject = jsonarray.getJSONObject(i);
// Retrieve JSON Objects
map.put("id", jsonobject.getString("id"));
map.put("profile_pic", jsonobject.getString("news_pic"));
// Set the JSON Objects into the array
arraylist.add(map);
}
} catch (JSONException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void args) {
adapter = new GridViewAdapter(News.this, arraylist);
gridview.setAdapter(adapter);
mProgressDialog.dismiss();
}
#Override
protected void onCancelled(){
downloader.cancel(true);
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
BroadcastReceiver networkStateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
if(!noConnectivity) {
onConnectionFound();
} else {
onConnectionLost();
}
}
};
public void onConnectionLost() {
Toast.makeText(this, "Connection lost", Toast.LENGTH_LONG).show();
downloader.cancel(true);
}
public void onConnectionFound() {
Toast.makeText(this, "Connection found", Toast.LENGTH_LONG).show();
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkStateReceiver);
}
}
Your code is broken. Your while(true) loop is miswritten, its looping until you're canceled then trying to do a network request. That's probably not what you want. What you want to do is just remove that loop entirely (which may need further debugging after that). If you really want to continually download the data over and over, you want a Thread and not an AsyncTask, and the body of your function should all be inside that while loop.
I want to update my ChatMessageAdapter by received new data from background service so that I want to call UpdateAdapter method from background to update adapter.
here is my ServiceClass:
public class MyService extends Service{
private String loginUserInfoId;
SessionManager session;
DatabaseHelper db;
MessageListActivity mLA;
long totalSize = 0;
#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());
mLA = new MessageListActivity();
session = new SessionManager(getApplicationContext());
session.checkLogin();
HashMap<String, String> user = session.getUserDetails();
loginUserInfoId = user.get(SessionManager.KEY_USER_INFO_ID);
if(isInternetOn()) {
new syncMessageFromServer().execute();
new SyncPendingMessageToServer();
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
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/GetAllMessage/" + loginUserInfoId);
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();
String offlineFileURL = "";
/******* Firstly take data in model object ******/
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"));
mLA.UpdateAdapter(ChatMessage cm);
long messageThreadId = db.SendMessage(cm);
}
} catch (JSONException e) {
e.printStackTrace();
}
return str;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(isInternetOn()) {
new syncMessageFromServer().execute();
}
}
}
}
and this is my MessageActivityList Class:
public class MessageListActivity extends ActionBarActivity {
private String receiverUserInfoId;
private String loginUserInfoId;
private String orgMsgThreadId;
private String userName;
private String uploadedFileURL = "";
DatabaseHelper db;
SessionManager session;
private ChatMessageAdapter chatMessageAdapter;
private EditText chatText;
private ImageButton buttonSend;
private ListView listView;
private static final String TAG = MessageListActivity.class.getSimpleName();
// Camera activity request codes
private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
private static final int CAMERA_CAPTURE_VIDEO_REQUEST_CODE = 200;
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
private Uri fileUri; // file url to store image/video
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message_list);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
.penaltyLog()
.build());
db = new DatabaseHelper(getApplicationContext());
session = new SessionManager(getApplicationContext());
session.checkLogin();
HashMap<String, String> user = session.getUserDetails();
loginUserInfoId = user.get(SessionManager.KEY_USER_INFO_ID);
Intent intent=getIntent();
Bundle extra = intent.getExtras();
receiverUserInfoId=extra.getString("UserInfoId");
orgMsgThreadId = extra.getString("OrgMessageThreadId");
userName=extra.getString("UserName");
setTitle(userName);
listView = (ListView) findViewById(R.id.messageList);
chatMessageAdapter = new ChatMessageAdapter(getApplicationContext(), R.layout.activity_single_message);
listView.setAdapter(chatMessageAdapter);
buttonSend = (ImageButton) findViewById(R.id.buttonSend);
chatText = (EditText) findViewById(R.id.chatText);
chatText.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
if(chatText.getText().toString().trim().length() > 0){
sendChatMessage();
}
}
return false;
}
});
buttonSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
sendChatMessage();
}
});
listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
// listView.setAdapter(chatMessageAdapter);
//to scroll the list view to bottom on data change
chatMessageAdapter.registerDataSetObserver(new DataSetObserver() {
#Override
public void onChanged() {
super.onChanged();
listView.setSelection(chatMessageAdapter.getCount() - 1);
}
});
setListData();
}
public void UpdateAdapter(ChatMessage cm) {
chatMessageAdapter.add(cm);
}
}
What to do for calling this UpdateAdapter method to update my ChatMessage received by the server?
You should be using a LocalBroadcastReceiver.
Register for receiving the updates in onResume and unregister in onPause.
U can use Broadcast receiver for updating the UI from service.
Register the broadcast receiver in onCreate() of ur Activity:
private UpdateReceiver updateReceiver;
if (UpdateReceiver == null)
{
updateReceiver = new UpdateReceiver();
IntentFilter intentFilter = new
IntentFilter("REFRESH_DATA");
registerReceiver(updateReceiver, intentFilter);
}
Unregister in onDestroy() of ur Activity
if (updateReceiver != null) unregisterReceiver(updateReceiver);
Define the Broadcast receiver in ur Activity :
private class UpdateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("REFRESH_DATA")) {
//update adapter from here
}
}
}
In ur service in which situation u want to update the adapter, there call sendBroadcast. Like:
Intent intent=new Intent("REFRESH_DATA");
//u can pass the data through putExtras
sendBroadcast(intent);
use Broadcast receiver for updating the UI from service and register the broadcast receiver in onCreate() of ur MainActivity where you want to recieve
code will like below
private UpdateReceiver updateReceiver;
if (UpdateReceiver == null)
{
updateReceiver = new UpdateReceiver();
IntentFilter intentFilter = new
IntentFilter("REFRESH_DATA");
registerReceiver(updateReceiver, intentFilter);
}
and create class to check update is recieved or not
private class UpdateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("REFRESH_DATA")) {
//update adapter from here
}
}
}
register a BroadcastReceiver inside your activity. call that method in onReceive method of this receiver. and from your Service sendBroadcast to this receiver, remember to add the required data to your intent and fetch data from onReceive method intent.
I'm making an app that sends a notification to the status bar, it sends the notification when stepping through the code in the debugger, however it never sends the notification when run in realtime.
Here is my runnable that generates the notification, again when stepping through this code in the debugger the notification runs however in realtime nothing happens.
public class NewsEvents_Service extends Service {
private static final String NEWSEVENTS = "newsevents";
private static final String KEYWORDS = "keywords";
private NotificationManager mNM;
private ArrayList<NewsEvent> neList;
private int count;
#Override
public void onCreate() {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
neList = new ArrayList<NewsEvent>();
getKeywords();
//getNewsEvents();
Thread thr = new Thread(null, mTask, "NewsEvents_Service");
thr.start();
Log.d("Thread", "IT STARTED!!!!!!????!!!!!!!!!!!!!!!?!!?");
}
#Override
public void onDestroy() {
// Cancel the notification -- we use the same ID that we had used to start it
mNM.cancel(R.string.ECS);
// Tell the user we stopped.
Toast.makeText(this, "Service Done", Toast.LENGTH_SHORT).show();
}
/**
* The function that runs in our worker thread
*/
Runnable mTask = new Runnable() {
public void run() {
getNewsEventsFromWeb();
for(NewsEvent ne : neList){
Log.d("Thread Running", "Service Code running!!!!!!!!!!!!!!!");
String body = ne.getBody().replaceAll("\\<.*?>", "");
String title = ne.getTitle();
for(String s : keyWordList){
if(body.contains(s) || body.contains(s.toLowerCase()) ||
title.contains(s) || title.contains(s.toLowerCase())){
ne.setInterested(true);
}
}
if(ne.isInterested() == true ){
Notification note = new Notification(R.drawable.icon,
"New ECS News Event", System.currentTimeMillis());
Intent i = new Intent(NewsEvents_Service.this, FullNewsEvent.class);
i.putExtra("ne", ne);
PendingIntent pi = PendingIntent.getActivity(NewsEvents_Service.this, 0,
i, 0);
note.setLatestEventInfo(NewsEvents_Service.this, "New Event", ne.getTitle(), pi);
note.flags = Notification.FLAG_AUTO_CANCEL;
mNM.notify(R.string.ECS, note);
}
}
}
};
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/**
* Show a notification while this service is running.
*/
private void getNewsEventsFromWeb() {
HttpClient client = new DefaultHttpClient();
HttpGet get;
try {
get = new HttpGet(getString(R.string.jsonnewsevents));
ResponseHandler<String> response = new BasicResponseHandler();
String responseBody = client.execute(get, response);
String page = responseBody;
Bundle data = new Bundle();
data.putString("page",page);
Message msg = new Message();
msg.setData(data);
handler.sendMessage(msg);
}
catch (Throwable t) {
Log.d("UpdateNews", "PROBLEMS");
}
}
private Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
String page = msg.getData().getString("page");
try {
JSONArray parseArray = new JSONArray(page);
for (int i = 0; i < parseArray.length(); i++) {
JSONObject jo = parseArray.getJSONObject(i);
String title = jo.getString("title");
String body =jo.getString("body");
String pd = jo.getString("postDate");
String id = jo.getString("id");
NewsEvent ne = new NewsEvent(title, pd , body, id);
boolean unique = true;
for(NewsEvent ne0 : neList){
if(ne.getId().equals(ne0.getId())){
unique = false;
}else{
unique = true;
}
}
if(unique == true){
neList.add(ne);
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
private ArrayList<String> keyWordList;
public void getNewsEvents(){
try {
InputStream fi = openFileInput(NEWSEVENTS);
if (fi!=null) {
ObjectInputStream in = new ObjectInputStream(fi);
neList = (ArrayList<NewsEvent>) in.readObject();
in.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
if(neList == null){
neList = new ArrayList<NewsEvent>();
}
}
public ArrayList<String> getKeywords(){
try {
InputStream fi = openFileInput(KEYWORDS);
if (fi!=null) {
ObjectInputStream in = new ObjectInputStream(fi);
keyWordList = (ArrayList<String>) in.readObject();
in.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
if(keyWordList == null){
keyWordList = new ArrayList<String>();
return keyWordList;
}
return keyWordList;
}
/**
* This is the object that receives interactions from clients. See RemoteService
* for a more complete example.
*/
private final IBinder mBinder = new Binder() {
#Override
protected boolean onTransact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
return super.onTransact(code, data, reply, flags);
}
};
}
Here is my activity that schedules the service to run
public class NewsEvents extends ListActivity{
private URL JSONNewsEvents;
private ArrayList<NewsEvent> neList;
private ArrayList<String> keyWordList;
private Worker worker;
private NewsEvents ne;
public static final String KEYWORDS = "keywords";
private static final String NEWSEVENTS = "newsevents";
public static final int ONE_ID = Menu.FIRST+1;
private PendingIntent newsAlarm;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.newsevents);
ne = this;
neList = new ArrayList<NewsEvent>();
try {
JSONNewsEvents = new URL(getString(R.string.jsonnewsevents));
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
worker = new Worker(handler, this);
setListAdapter(new IconicAdapter());
getKeywords();
worker.execute(JSONNewsEvents);
}
#Override
protected void onStop() {
super.onStop();
writeNewsEvents() ;
}
#Override
protected void onPause(){
super.onPause();
writeNewsEvents();
}
private void writeNewsEvents() {
try {
OutputStream fi = openFileOutput(NEWSEVENTS, 0);
if (fi!=null) {
ObjectOutputStream out = new ObjectOutputStream(fi);
out.writeObject(neList);
out.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
}
/**
* #return
*/
public ArrayList<String> getKeywords(){
try {
InputStream fi = openFileInput(KEYWORDS);
if (fi!=null) {
ObjectInputStream in = new ObjectInputStream(fi);
keyWordList = (ArrayList<String>) in.readObject();
in.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
if(keyWordList == null){
keyWordList = new ArrayList<String>();
return keyWordList;
}
return keyWordList;
}
public void onListItemClick(ListView parent, View v,
int position, long id) {
startFullNewsEvent(neList.get(position));
}
/**
* #param newsEvent
*/
public void startFullNewsEvent(NewsEvent ne) {
Intent intent = new Intent(this, FullNewsEvent.class);
intent.putExtra("ne", ne);
this.startActivity(intent);
finish();
}
private Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
String page = msg.getData().getString("page");
try {
JSONArray parseArray = new JSONArray(page);
for (int i = 0; i < parseArray.length(); i++) {
JSONObject jo = parseArray.getJSONObject(i);
String title = jo.getString("title");
String body =jo.getString("body");
String pd = jo.getString("postDate");
String id = jo.getString("id");
NewsEvent ne = new NewsEvent(title, pd , body, id);
boolean unique = true;
for(NewsEvent ne0 : neList){
if(ne.getId().equals(ne0.getId())){
unique = false;
}else{
unique = true;
}
}
if(unique == true){
neList.add(ne);
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ne.setListAdapter(new IconicAdapter());
}
};
public class IconicAdapter extends ArrayAdapter<NewsEvent> {
IconicAdapter() {
super(NewsEvents.this, R.layout.rownews, neList);
}
public View getView(int position, View convertView,ViewGroup parent) {
LayoutInflater inflater=getLayoutInflater();
View row=inflater.inflate(R.layout.rownews, parent, false);
TextView label=(TextView)row.findViewById(R.id.label);
ImageView image= (ImageView)row.findViewById(R.id.icon);
String body = neList.get(position).getBody();
body.replaceAll("\\<.*?>", "");
String title = neList.get(position).getTitle();
for(String s : keyWordList){
if(body.contains(s) || body.contains(s.toLowerCase()) ||
title.contains(s) || title.contains(s.toLowerCase())){
neList.get(position).setInterested(true);
}
}
if(neList.get(position).isInterested() == true){
image.setImageResource(R.drawable.star);
}
label.setText(neList.get(position).getTitle());
return(row);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
populateMenu(menu);
return(super.onCreateOptionsMenu(menu));
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return(applyMenuChoice(item) || super.onOptionsItemSelected(item));
}
//Creates our activity to menus
private void populateMenu(Menu menu) {
menu.add(Menu.NONE, ONE_ID, Menu.NONE, "Home");
}
private boolean applyMenuChoice(MenuItem item) {
switch (item.getItemId()) {
case ONE_ID: startHome(); return(true);
}
return(false);
}
public void startHome() {
Intent intent = new Intent(this, ECS.class);
this.startActivity(intent);
finish();
}
}
Race conditions, I'm making an HTTP Request and then handing it off to a handler, immediately following that I iterator through the array list, which at full speed is empty because the HTTP hasn't completed. In debugging it all slows down so the HTTP is complete and all works well.
Threads and Network Connections, a deadly combination.