I tried https://github.com/pubnub/java/tree/master/android#connection-durability-reconnecting--resuming-when-a-connection-is-lost-or-changed but still I'm not able to figure out how to use setResumeOnReconnect() .
I'm running android-service and added following code snippet inside onCreate() of the service.
pubnubBroadcastReceiver =new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
int networkType = intent.getExtras().getInt(ConnectivityManager.EXTRA_NETWORK_TYPE);
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(networkType);
boolean isConnected = networkInfo.isConnected();
if(isConnected) {
ApplicationLoader.getPubnub().disconnectAndResubscribe();
// ApplicationLoader.getPubnub().setResumeOnReconnect(true);
}
}
};
registerReceiver(pubnubBroadcastReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
Don't know what I'm missing here.
As per PubNub sample chat, you need to implement code to get the last n messages(n: number of messages preferred).
/**
* Get last 100 messages sent on current channel from history.
*/
public void history() {
this.mPubNub.history(this.channel, 100, false, new Callback() {
#Override
public void successCallback(String channel, final Object message) {
try {
JSONArray json = (JSONArray) message;
Log.d("History", json.toString());
final JSONArray messages = json.getJSONArray(0);
final List<ChatMessage> chatMsgs = new ArrayList<ChatMessage>();
for (int i = 0; i < messages.length(); i++) {
try {
if (!messages.getJSONObject(i).has("data"))
continue;
JSONObject jsonMsg = messages.getJSONObject(i)
.getJSONObject("data");
String name = jsonMsg
.getString(Constants.JSON_USER);
String msg = jsonMsg.getString(Constants.JSON_MSG);
long time = jsonMsg.getLong(Constants.JSON_TIME);
ChatMessage chatMsg = new ChatMessage(name, msg,
time);
chatMsgs.add(chatMsg);
} catch (JSONException e) { // Handle errors silently
e.printStackTrace();
}
}
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "RUNNIN",
Toast.LENGTH_SHORT).show();
mChatAdapter.setMessages(chatMsgs);
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void errorCallback(String channel, PubnubError error) {
Log.d("History", error.toString());
}
});
}
Related
i have created an Application for Nougat device where my application is detecting all the images taking by camera and i am sending this images in the server. My application is successfully sending the first photo taken by the camera but the receiver neither detecting the second image i am taking nor sending it to the server. I have a ConfigurationBuilder class which will trigger each and every 30 minutes to detect the new pictures by the camera and a cameraReceiver and a service class where i have registered the receiver.
ConfigurationBuilder.java
public class ConfigurationBuilder extends JobService {
JobParameters mRunningParams;
static final int PROJECTION_ID = 0;
static final int PROJECTION_DATA = 1;
static final String DCIM_DIR = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM).getPath();
static final String[] PROJECTION = new String[] {
MediaStore.Images.ImageColumns._ID, MediaStore.Images.ImageColumns.DATA
};
static final List<String> EXTERNAL_PATH_SEGMENTS
= MediaStore.Images.Media.EXTERNAL_CONTENT_URI.getPathSegments();
String TAG = "JobService";
private Context mContext;
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public boolean onStartJob(JobParameters jobParameters) {
mContext = getApplicationContext();
getSettingResponse(true);
jobFinished(jobParameters, false);
Log.d(TAG, "onStartJob: ");
return true;
}
private void getSettingResponse(boolean fromJobScheduler) {
try {
if (fromJobScheduler)
new DataClear();
OkHttpClient client = new SSLManager().getClientKeyNonDeprecated(mContext);
// code request code here
HttpUrl.Builder urlBuilder =
HttpUrl.parse(mContext.getSharedPreferences(NetworkAPI.PREFNAME,Context.MODE_PRIVATE ).getString("configuration_url", "")).newBuilder();
//urlBuilder.addQueryParameter("device", CommonMethods.getBluetoothName());
urlBuilder.addQueryParameter("device", "FranksS7");
urlBuilder.addQueryParameter("membership", "Phone Network");
urlBuilder.addQueryParameter("membershipType", "Domain");
Request request = new Request.Builder().addHeader("Accept", "application/json")
.url(urlBuilder.build()).get()
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.d(TAG, "onFailure: " + e.getMessage());
getConfigure(null);
}
#Override
public void onResponse(Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
Log.d(TAG, "onResponse:Unexpected code" + response.body().string());
} else {
getConfigure(response.body().string());
}
}
});
} catch (Exception e) {
Log.d(TAG, "getSettingResponse: " + e.getMessage());
}
}
#Override
public boolean onStopJob(JobParameters jobParameters) {
return false;
}
private void getConfigure(String response) {
try {
if (response != null) {
JSONArray policies = new JSONObject(response).getJSONArray("Policies");
for (int i = 0; i < policies.length(); i++) {
JSONObject obj = policies.getJSONObject(i);
Iterator iterator = obj.keys();
String key = (String) iterator.next();
JSONObject issue = obj.getJSONObject(key);
String value = issue.optString("Value");
RecorderPolicies policiesField = new Select()
.from(RecorderPolicies.class)
.where("Policy = ?", key).executeSingle();
if (policiesField != null) {
policiesField.Value = value;
long res = policiesField.save();
// new Update(RecorderPolicies.class).set("Value = ?",value).where("Policy = ?", key).execute();
} else {
RecorderPolicies recorderPolicies = new RecorderPolicies();
recorderPolicies.Policy = key;
recorderPolicies.Value = value;
long res = recorderPolicies.save();
}
}
}
if (isMyServiceRunning(ApplicationService.class)) {
// stopService(new Intent(mContext, ApplicationService.class));
Log.d(TAG, "Service Terminated");
}
if (new RecorderPolicies().getActivateCode("CanRecordDetailedData"))
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
mContext.startService(new Intent(mContext, ApplicationService.class));
Log.d(TAG, "Service Restarted");
}
}, 10000);
else
Log.d(TAG, "----------------------problem starting service---------------------");
} catch (Exception e) {
Log.d(TAG, "getConfigure: " + e.getMessage());
}
}
#RequiresApi(api = Build.VERSION_CODES.N)
public void startConfigurationScheduler(int JobID, Context activityContext) {
mContext = activityContext;
ComponentName jobService =
new ComponentName(activityContext, ConfigurationBuilder.class.getName());
JobInfo jobInfo =
new JobInfo.Builder(JobID, jobService)
.setPersisted(true).setRequiresDeviceIdle(true)
//updated code for nougat...............................................................on 12/11/2017
//.setPeriodic(32*60000, (long) (1.6*60000)).build();
.setPeriodic(32 * 60000).build();
JobScheduler jobScheduler = (JobScheduler) activityContext.getSystemService(JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(jobInfo);
getSettingResponse(false);
}
public void stopConfigurationScheduler(int JobID, Context activityContext) {
JobScheduler jobScheduler = (JobScheduler) activityContext.getSystemService(JOB_SCHEDULER_SERVICE);
jobScheduler.cancel(JobID);
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) mContext.getSystemService(ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
Process.killProcess(service.pid); // kill service
return true;
}
}
return false;
}
}
CameraReceiver .java
public class CameraReceiver extends BroadcastReceiver {
private String pathSplit;
private String type;
Context mContext;
#Override
public void onReceive(Context context, Intent intent) {
mContext=context;
Cursor cursor = context.getContentResolver().query(intent.getData(),
null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
String image_path = cursor.getString(cursor.getColumnIndex("_data"));
String MediaType = intent.getAction().equals("android.hardware.action.NEW_VIDEO") ? "VIDEO" : "IMAGE";
FilesObservers.postDataCreateEvent("CREATE", image_path, true,MediaType);
cursor.close();
}
}
public IntentFilter getVideoFilters() {
IntentFilter lsIntentFilter = new IntentFilter();
try {
lsIntentFilter.addDataType("video/*");
} catch (IntentFilter.MalformedMimeTypeException e) {
e.printStackTrace();
}
lsIntentFilter.addAction("android.hardware.action.NEW_VIDEO");
lsIntentFilter.addCategory("android.intent.category.DEFAULT");
return lsIntentFilter;
}
public IntentFilter getCameraFilters() {
IntentFilter lsIntentFilter = new IntentFilter();
try {
lsIntentFilter.addDataType("image/*");
} catch (IntentFilter.MalformedMimeTypeException e) {
e.printStackTrace();
} //lsIntentFilter.addAction("JobInfo.Builder.addTriggerContentUri(JobInfo.TriggerContentUri)");
lsIntentFilter.addAction("android.provider.MediaStore.ACTION_IMAGE_CAPTURE)");
lsIntentFilter.addCategory("android.intent.category.DEFAULT");
return lsIntentFilter;
}
}
In Nougat ACTION_NEW_VIDEO and ACTION_NEW_PICTURE broadcasts were removed.
Instead this they recommend to use JobInfo.Builder.JobInfo.Builder.addTriggerContentUri(JobInfo.TriggerContentUri)
It is funny because In Android O this broadcast has been brought back - for registered receivers only.
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 have the following Service that is meant to check a web API.
The Implementation is meant to retry the HTTP request 5 times before issuing a notification.
Anyway it seems that the service simply stops after the first attempt.
Please what is going on???
public class CreditcheckService extends IntentService {
public CreditcheckService() {
super("CreditcheckService");
}
#Override
protected void onHandleIntent(Intent intent) {
String phone = "";
phone = intent.getStringExtra("phone");
checkcreditonline(phone);
Log.e("inizio il service","inizio il service");
}
private void checkcreditonline(final String phone) {
final Handler h = new Handler();
final JsonHttpResponseHandler jsonHttpResponseHandler = new JsonHttpResponseHandler() {
private int counter = 0;
#Override
public void onSuccess(JSONObject arg0) {
int cazzo=0;
cazzo++;
try {
String status = arg0.getString("credit");
} catch (JSONException e) {
e.printStackTrace();
}
try {
String status = arg0.getString("error");
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Throwable arg0) {
//IF FAILED SHOULD RETRY, BUT IT DOESN'T
if (counter < 5) {
//HERE THE SUCCESSIVE ATTEMPTS
h.postDelayed(new WebserviceRunnable(this, phone), 5000);
} else {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(CreditcheckService.this)
.setSmallIcon(R.drawable.icon)
.setContentTitle(getResources().getString(R.string.unable_to))
.setContentText(getResources().getString(R.string.please_connect));
mBuilder.setContentIntent(PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), 0));
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(999, mBuilder.build());
}
counter++;
}
};
h.post(new WebserviceRunnable(jsonHttpResponseHandler, phone));
}
private class WebserviceRunnable implements Runnable {
private JsonHttpResponseHandler jsonHttpResponseHandler;
private String email;
public WebserviceRunnable(
JsonHttpResponseHandler jsonHttpResponseHandler, String aEmail) {
this.jsonHttpResponseHandler = jsonHttpResponseHandler;
this.email = aEmail;
}
public void run() {
try {
WebServiceApi.get(
"rest/credit/get/" + URLEncoder.encode(email, "utf-8"),
null, jsonHttpResponseHandler);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}
onHandleIntent in IntentService is asynchronous.
When onHandleIntent exits, the Service is stopped.
So don't post a message to a Handler, instead do it directly in checkcreditonline().
I am trying to find out if my app is connected to the internet or not. I have a timeout set to 3 seconds. Sometimes the Internet Check will come back as "Not Connected" (even if I do have an internet connection) and sometimes it doesn't. Why does it take longer sometimes to check than others? Would I be able to have a dialogbox or something to popup while this is being checked?
public void isNetworkAvailable(final Handler handler)
{
new Thread()
{
private boolean responded = false;
#Override
public void run()
{
new Thread()
{
#Override
public void run()
{
HttpGet requestForTest = new HttpGet("http://m.google.com");
try
{
new DefaultHttpClient().execute(requestForTest);
responded = true;
}
catch (Exception e)
{
}
}
}.start();
try
{
int waited = 0;
while (!responded && (waited < 3000))
{
sleep(100);
if (!responded)
{
waited += 1000;
}
}
}
catch (InterruptedException e)
{
} // do nothing
finally
{
if (!responded)
{
handler.sendEmptyMessage(0);
}
else
{
handler.sendEmptyMessage(1);
}
}
}
}.start();
}
Handler h = new Handler()
{
#Override
public void handleMessage(Message msg)
{
if (msg.what != 1)
{ // code if not connected
Log.i("Internet check", "Not connected");
}
else
{ // code if connected
Log.i("Internet check", "Connected");
}
}
};
Use the following code
if(!haveInternet()){
<Your Alert Dialog Here>
}
private boolean haveInternet() {
NetworkInfo info = ((ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE))
.getActiveNetworkInfo();
if (info == null || !info.isConnected()) {
return false;
}
if (info.isRoaming()) {
return true;
}
return true;
}
are you consider use this http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html and/or register a BroadcastReceiver to notify it when connection is down/up, then you can handle it in any place of your application?
public class CustomApplication extends Application {
public static final String INTERNET_ACTION = "internet_action";
public static final String EXTRA_STATUS = "status";
#Override
public void onCreate() {
super.onCreate();
monitorNetworkAvailability();
}
private void monitorNetworkAvailability() {
//
// Improve the way to handle Thread
//
new Thread() {
private boolean responded = false;
#Override
public void run() {
while (true) {
new Thread() {
#Override
public void run() {
HttpGet requestForTest = new HttpGet("http://m.google.com");
try {
new DefaultHttpClient().execute(requestForTest);
responded = true;
} catch (Exception e) {
}
}
}.start();
try {
int waited = 0;
while (!responded && (waited < 3000)) {
sleep(100);
if (!responded) {
waited += 1000;
}
}
} catch (InterruptedException e) {
} // do nothing
finally {
Intent i = new Intent(INTERNET_ACTION);
i.putExtra(EXTRA_STATUS, responded);
sendBroadcast(i);
}
try {
Thread.sleep(1 * 60 * 1000);
} catch (InterruptedException e) {
}
}
}
}.start();
};
}
class MyActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(receiver, i);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
IntentFilter i = new IntentFilter(CustomApplication.INTERNET_ACTION);
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
boolean responded = intent.getBooleanExtra(CustomApplication.EXTRA_STATUS, false);
if (!responded) {
Toast.makeText(MyActivity.this, "No connection", Toast.LENGTH_SHORT).show();
}
}
};
}
public static Boolean isOnline(Context context) {
ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if(ni != null && ni.isConnected())
return true;
//Toast.makeText(context, context.getString(R.string.no_internet_connection), Toast.LENGTH_SHORT).show();
return false;
}
Requires permission:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
Edit:
As you correctly point out this is not a solid solution. In my case (which I indeed failed to mention) this is sufficient as a first check paired with LocationClient.isConnected().
Looking at your code I would think that it is worth taking a look at LocationClient, even if you are not planning to use location awareness of you app.
My reasoning for this is that you get rid of the need to repeatedly use resources to check if you have a valid connection. LocationClient uses the already in place communication with Google Play to tell you whether you are connected or not.
This solution of course only works if you assume that your users have a Google Account added to their device.
Here is a link to the official guidelines: http://developer.android.com/training/location/retrieve-current.html the onConnected and onDisconnected parts are found in the Define Location Services Callbacks section.
You are right. Your problem is that, the device checks for internet connection, and sometimes get a response from the router which says it cannot connect to internet, but that itself is a response, so your code might think that there is a response. Below is a sample method to test if you really can connect to the internet.
public static boolean hasActiveInternetConnection()
{
try
{
new Socket().connect(new InetSocketAddress("google.com", 80), 4000);
return true;
} catch (Exception e)
{
return false;
}
}
Then inside your activity you can call. (Make sure not to run this inside the MAIN/UI thread. Use an async or thread/handler/runnable strategy)
if(hasActiveInternetConnection())
{
//yey I have internet
}
else
{
//no internet connection
}
I was able to complete this by putting it inside an AsyncTask.
class online extends AsyncTask<String, String, String>
{
boolean responded = false;
#Override
protected void onPreExecute()
{
super.onPreExecute();
pDialog2 = new ProgressDialog(Main.this);
pDialog2.setMessage("Checking internet, please wait...");
pDialog2.setIndeterminate(false);
pDialog2.setCancelable(false);
pDialog2.show();
}
protected String doInBackground(String... args)
{
HttpGet requestForTest = new HttpGet("http://m.google.com");
try
{
new DefaultHttpClient().execute(requestForTest); // can
responded = true;
}
catch (Exception e)
{
}
try
{
int waited = 0;
while (!responded && (waited < 5000))
{
mHandler.postDelayed(new Runnable()
{
public void run()
{
}
}, 100);
waited += 100;
}
}
finally
{
if (!responded)
{
h.sendEmptyMessage(0);
}
else
{
h.sendEmptyMessage(1);
}
}
return null;
}
protected void onPostExecute(String file_url)
{
pDialog2.dismiss();
}
}
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.