Am fetching JSON data from a remote server and before triggering the asynctask am checking for the availability of internet connection with the help of below code
if (isOnline()==true){
new DownloadJSON().execute();
}
//do whatever you want to do
else
{
try {
Toast.makeText(context, "Slow or No Internet Connection", Toast.LENGTH_SHORT).show();
}
catch(Exception e)
{
}
}
public boolean isOnline() {
try {
Process p1 = Runtime.getRuntime().exec("ping -c 1 www.google.com");
int returnVal = p1.waitFor();
boolean reachable = (returnVal == 0);
if (reachable) {
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
p1.destroy();
}
return false;
}
This works fine for no internet connection. Even it works in cases like, there is wifi but no internet access. But the problem is it blacks out my activity if the internet connectivity is slow and gets force closed.
Please guide me how can I add a timeout value to isOnline() or is there any better way to handle such error in catch block
Why don't you use the AsyncTask class ? It won't block the UI thread.
Related
Im making an apps that mock location and executing set ALLOW_MOCK_LOCATION turned on and off on runtime, so i hopes the other apps which detecting the ALLOW_MOCK_LOCATION flag will never get the ALLOW_MOCK_LOCATION as 1(true).
I read from here that it was possible and said to be fast enough, so other apps can hardly detect the change of ALLOW_MOCK_LOCATION. But what i am get is the other apps still sometimes reed ALLOW_MOCK_LOCATION as 1(true).
Please note that my devices already rooted and i can confirm it does mocked the location well. I also tried move it into /system/app, but still also encounter this problem.
This is the periodical loop which dispatch a asyntask with timeout(I even set the timeout 3 millis !!).
while(RUNNING){
fakeLocation.setAltitude(65.0);
fakeLocation.setAccuracy(Criteria.ACCURACY_FINE);
fakeLocation.setSpeed(0.0f);
fakeLocation.setTime(System.currentTimeMillis());
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
fakeLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
if(locationJellyBeanFixMethod!=null){
try {
locationJellyBeanFixMethod.invoke(fakeLocation);
}catch(Exception ex){}
}
}
new Thread(new Runnable() {
#Override
public void run() {
try {
new MockTask().execute().get(3, TimeUnit.MILLISECONDS);
}catch(TimeoutException e){
changeMockLocationSettings(0);
//Log.d(GLOBAL_VAR.TAG_DEBUG,"Mock location timeout:");
}catch(Exception e){}
}
}).start();
try {Thread.sleep(1500);} catch (InterruptedException e) {}
}
Below is the Asyntask
private class MockTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... param) {
try {
changeMockLocationSettings(1);
locationManager.setTestProviderLocation(GLOBAL_VAR.PROVIDER_NAME, fakeLocation);
changeMockLocationSettings(0);
//Log.d(GLOBAL_VAR.TAG_DEBUG,"location mocked -> "+fakeLocation);
} catch (Exception ex) {
//Log.d(GLOBAL_VAR.TAG_DEBUG,"Failed to mock location:"+ex.toString());
}
return null;
}
#Override
protected void onPostExecute(Void loc) {}
}
And lastly, the method to change ALLOW_MOCK_LOCATION
private boolean changeMockLocationSettings(int value) {
try {
return Settings.Secure.putInt(getApplicationContext().getContentResolver(),Settings.Secure.ALLOW_MOCK_LOCATION, value);
} catch (Exception e) {
Log.d(GLOBAL_VAR.TAG_DEBUG,"Setting allow mock location to "+value+" failed :"+e.toString());
e.printStackTrace();
return false;
}
}
Please help and correct me, and even suggest a better solution if any, and thanks in Advance
I made a simple android appication for connect with bluetooth serial device and I want to add closeBT if android not connected maybe the device is out of range because crash.
How do I do this? This code is correct?
protected void onStart() {
super.onStart();
findBT(); //Check if bluettoth enable and paired devices
try {
openBT(); //open sockets,streams
} catch (IOException e) {
e.printStackTrace();
closeBT();
}
}
Try-catch is not for the application logic! It is for doing stuff when something went wrong! You want to use an if-else here, like
if (findBT() != null) { // I don't know what findBT does, but maybe it returns BT-devices
try {
openBT(); //open sockets,streams
} catch (IOException e) {
e.printStackTrace();
// inform the user that a connection could not be established or something similar
}
} else {
// inform the user, that no BT-device was found.
}
you want to use closeBT() for instance when the user or your application decides to disconnect the BT-devices.
I have an application which needs to communicate with the server at some random interval through GPRS or EDGE.. But there are few possibilities at which internet cannot be accessed by the application when the user is in call or deactivated etc. At these time i have two scenario's recoverable and non recoverable.
Recoverable scenarios
On phone call ( User will hang up and data connection will be active
again)
No Signal (Sometimes signal may drop and the phone will get
signal again)
Non Recoverable Scenarios
Flight mode
Deactivating Data Connection
When its recoverable i can try again for the connection after some defined interval. And during non recoverable i have to alert user. For instance if the user deactivates data connection or enables flight mode i have to alert the user.
EDIT:I can able to detect flight mode through one of the intents. I couldn't able to find for others.
The below code return if valid connections are available
public boolean isConnectionsAvailable() {
boolean lRet = false;
try{
ConnectivityManager conMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info= conMgr.getActiveNetworkInfo();
if(info != null && info.isConnected()) {
lRet = true ;
}else{
lRet = false ;
}
}catch (Exception e) {
Log.d("Connection Error", e.toString());
lRet = false ;
}
return lRet;
}
After this, if you have low signal strength then you make a HTTP request by setting relevant time out to it. If timeout happened give relevant alert msg to user as below
public void serverCall(String pURL){
if (isConnectionsAvailable()){
// Call server by setting proper timeout
}
}
Edit:
To check the Airplane mode status:
private static boolean isAirplaneModeOn(Context context) {
return Settings.System.getInt(context.getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, 0) != 0;
}
You could try surrounding your method with try and catch. If the method fails because it cannot connect to your server for whatever reason you could call postDelayed from a Handler and re-run your method again in a pre-determined length of time.
Handler mHandler = new Handler();
Runnable yourMethodRunnable = new Runnable(){
#Override
public void run(){
yourMethod();
}
};
private void yourMethod(){
try{
// talk to server
} catch (InCallException e) {
mHandler.postDelayed(yourMethodRunnable, delay)
} catch (NoSignalException e) {
// etc...
} catch (OtherException e) {
// etc...
}
}
The exceptions are just examples, and likely don't exist, get the exceptions that you want to catch either from the Android Developer Docs, or by looking at the output from LogCat when you re-enact each time that the connection to the server would fail.
I'm using org.apache.commons.net.ftp.FTPClient to communicate with an ftp server via an android app I'm making that records video and then uploads it to the ftp server. Everything is fine until I call storeFile at which point the app prevents any interaction until the uploading is completed. Is there any way around this? I'm currently developing for API lvl 12.
My set up is as follows I have a class that calls a service in the background to handle recording of the video as well as the ftp setup. In the FTP class I have any of my fptclient interaction within asynctasks. Here is my method for uploading the file:
public boolean upload(String srcFilePath, String desFileName, String desDirectory)
{
if(!isLoggedIn())
{
return false;
}
boolean status = false;
try
{
status = new AsyncTask<String, Void, Boolean>(){
#Override
protected Boolean doInBackground(String... args) {
boolean status = false;
try {
String srcFilePath = args[0];
String desFileName = args[1];
String desDirectory = args[2];
FileInputStream srcFileStream = new FileInputStream(srcFilePath);
// change working directory to the destination directory
if (changeDirectory(desDirectory,true)) {
status = mFTPClient.storeFile(desFileName, srcFileStream);
}
srcFileStream.close();
return status;
} catch (Exception e) {
Log.d(TAG, "upload failed");
e.printStackTrace();
return false;
}
}
}.execute(srcFilePath, desFileName, desDirectory).get();
} catch (InterruptedException e)
{
e.printStackTrace();
return status;
} catch (ExecutionException e)
{
e.printStackTrace();
return status;
}
return status;
}
Any help would be immensely appreciated!
Devunwired's post worked! Hoorah!
You've started down the right path by placing this long-running task into a background thread using AsyncTask so that it doesn't block the UI. However, by immediately calling get() on the task after executing it, you effectively block the UI thread anyway because get() is a blocking method. From the SDK docs:
AsyncTask.get()
Waits if necessary for the computation to complete, and then retrieves its result.
What you should do is refactor your AsyncTask to make use of the onPostExecute() method. This method will be called when the background task is complete, with your result value as a parameter, and will be called on the UI thread so you can safely update anything you like with it.
HTH
There is any way I can enable Android NFC reader using API?
So apparently there is no way to enable the NFC from the API, even though Google does so within their source code (see below).
If you look at a line from the API for NfcAdapter.isEnabled():
Return true if this NFC Adapter has
any features enabled.
Application may use this as a helper
to suggest that the user should turn
on NFC in Settings.
If this method returns false, the NFC
hardware is guaranteed not to generate
or respond to any NFC transactions.
It looks like there is no way to do it within the API. Bummer. Your best bet is a dialog to inform the user they need to enable it in the settings, and perhaps launch a settings intent.
EDIT: The following is from the source, but it looks like they didn't allow the user to implement the methods in the API (I'm confused about this).
I found this from the android source code to help enable and disable the adapter.
Relevant source:
public boolean onPreferenceChange(Preference preference,
Object value) {
// Turn NFC on/off
final boolean desiredState = (Boolean) value;
mCheckbox.setEnabled(false);
// Start async update of the NFC adapter state, as the API is
// unfortunately blocking...
new Thread("toggleNFC") {
public void run() {
Log.d(TAG, "Setting NFC enabled state to: "
+ desiredState);
boolean success = false;
if (desiredState) {
success = mNfcAdapter.enable();
} else {
success = mNfcAdapter.disable();
}
if (success) {
Log.d(TAG,
"Successfully changed NFC enabled state to "
+ desiredState);
mHandler.post(new Runnable() {
public void run() {
handleNfcStateChanged(desiredState);
}
});
} else {
Log.w(TAG, "Error setting NFC enabled state to "
+ desiredState);
mHandler.post(new Runnable() {
public void run() {
mCheckbox.setEnabled(true);
mCheckbox
.setSummary(R.string.nfc_toggle_error);
}
});
}
}
}.start();
return false;
}
I got it working through reflection
This code works on API 15, haven't checked it against other verions yet
public boolean changeNfcEnabled(Context context, boolean enabled) {
// Turn NFC on/off
final boolean desiredState = enabled;
mNfcAdapter = NfcAdapter.getDefaultAdapter(context);
if (mNfcAdapter == null) {
// NFC is not supported
return false;
}
new Thread("toggleNFC") {
public void run() {
Log.d(TAG, "Setting NFC enabled state to: " + desiredState);
boolean success = false;
Class<?> NfcManagerClass;
Method setNfcEnabled, setNfcDisabled;
boolean Nfc;
if (desiredState) {
try {
NfcManagerClass = Class.forName(mNfcAdapter.getClass().getName());
setNfcEnabled = NfcManagerClass.getDeclaredMethod("enable");
setNfcEnabled.setAccessible(true);
Nfc = (Boolean) setNfcEnabled.invoke(mNfcAdapter);
success = Nfc;
} catch (ClassNotFoundException e) {
} catch (NoSuchMethodException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
} else {
try {
NfcManagerClass = Class.forName(mNfcAdapter.getClass().getName());
setNfcDisabled = NfcManagerClass.getDeclaredMethod("disable");
setNfcDisabled.setAccessible(true);
Nfc = (Boolean) setNfcDisabled.invoke(mNfcAdapter);
success = Nfc;
} catch (ClassNotFoundException e) {
} catch (NoSuchMethodException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
}
if (success) {
Log.d(TAG, "Successfully changed NFC enabled state to "+ desiredState);
} else {
Log.w(TAG, "Error setting NFC enabled state to "+ desiredState);
}
}
}.start();
return false;
}//end method
This requires 2 permissions though, put them in the manifest:
<!-- change NFC status toggle -->
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
The NFC button's state switches accordingly when the code is used, so there are no issues when doing it manually in the seetings menu.
If you can see the NfcService Application Source Code, there is a Interface file INfcAdapter.aidl. In the file two API's are there namely "boolean enable()" and "boolean disable()". You can directly use this API's to enable and disable NfcService through an android application. But the trick over here is that you can not compile the code using SDK provided by the Android. You have to compile the application using the a makefile. I have successfully build a application.
I hope this forum would be help you to resolve this issue as well to get the clear understanding on the NFC power on/off API barries.
http://ranjithdroid.blogspot.com/2015/11/turn-onoff-android-nfc-by.html