I am trying to write an Android app that uses com.loopj.android.http.AsyncHttpClient. Although I wrote an Android app some years ago, I am very rusty, so please be gentle with me!
In my app, I do a get, and none of the callback virtual methods are called. To simplify, and make sure it wasn't something about my app, I made a new project based on the SupportAppNavigation project that comes with the SDK. I modified the onCreate code as follows:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("com.trumphurst", "Creating AsyncHttpClient");
AsyncHttpClient client = new AsyncHttpClient();
client.setTimeout(5000);
Log.i("com.trumphurst", "Getting www.google.com");
client.get("http://www.google.com", new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
Log.i("com.trumphurst", "Success");
}
#Override
public void onFailure(Throwable error, String content) {
Log.i("com.trumphurst", "Failure");
}
});
setListAdapter(new SampleAdapter(querySampleActivities()));
}
(Note that this is the only code change I have made to the example application that comes with the SDK.)
I started the app under the debugger, and monitored the logcat output. I saw "Creating AsyncHttpClient" and "Getting www.google.com", then nothing.
I have added some permissions to the manifest - it now starts:
<manifest android:versionCode="1"
android:versionName="1"
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.support.appnavigation">
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application android:label="#string/app_name">
<activity android:name=".app.AppNavHomeActivity"
android:label="#string/app_nav_home_label">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Clearly I must be doing something wrong - can anyone put me right?
I think you forget add permission in your AndroidManifest file:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Read more about Manifest file here.
UPDATED:
Here is an example of manifes file from loopj github
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.loopj.android.http"
android:versionName="1.4.3"
android:versionCode="1">
<application
android:name="android_async_http">
</application>
<uses-sdk android:minSdkVersion="3" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
You can see INTERNET permission here.
Change AsyncHttpResponseHandler()
to TextHttpResponseHandler()
then your Overrides should be:
myClient.get(url, new TextHttpResponseHandler() {
#Override
public void onFailure(int i, Header[] headers, String s, Throwable throwable) {
}
#Override
public void onSuccess(int ii, Header[] headers, String s) {
}
}
Try to also add the onStart and onComplete methods to the callback.
The problem with the AsyncHttpClient is that it wont throw an error if your JSON returned is correctly encoded or not
e.g. I had the same problem as you but noticed that both the onSuccess and onComplete methods were being called but not success or failure. Found it to be the way my server was returning JSON. I was trying to return an associated string array that I created my self and missed the [] infont of the arrayname
Problem: $result = array('result'=>'OK');
Solution: $result[] = array('result'=>'OK');
Not saying yours would be the same syntax problem but it wouldn't hurt to look over what is being returned
Related
I'm writing an acessibility service in Android which relies on getting the view id of the currently selected view, however on some devices (Nexus 6P 6.0.1, Samsung Galaxy S6 edge+ 5 + 6.0.1) I get no view id through and on others (HTC One M8 5.0.1) it comes through fine. Because it works fine on some devices, I'm sure there's not a problem with my code, however I've posted a minimal test case below.
Can anyone can help me get my service reporting ids across all devices?
The A11y service
public class ViewIdLoggingAccessibilityService extends AccessibilityService {
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
AccessibilityNodeInfo source = event.getSource();
if (source == null) {
Log.d("onAccessibilityEvent", "source was null for: " + event);
} else {
String viewIdResourceName = source.getViewIdResourceName();
Log.d("onAccessibilityEvent", "viewid: " + viewIdResourceName);
}
}
#Override
public void onInterrupt() {
Log.d("!# onInterrupt", "called");
}
}
The AndroidManifest.xml
<manifest package="com.example.a11yservice"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
>
<service
android:name=".ViewIdLoggingAccessibilityService"
android:label="#string/view_id_logging_service_label"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
>
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/serviceconfig"
/>
</service>
</application>
</manifest>
serviceconfig.xml
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagReportViewIds"
android:canRetrieveWindowContent="true"
android:notificationTimeout="100" />
It's known issue and was posted to AOSP issue tracker some time ago. You can check status of issue here: "Accessibility Issue: flagReportViewIds has no effect on real devices in Android M".
Unfortunately issue exists even on latest Android 7.0 but I found simple workaround. You can call refresh() method on AccessibilityNodeInfo object to refresh it and collect all missed data including id.
Something like that:
public void onAccessibilityEvent(AccessibilityEvent event) {
AccessibilityNodeInfo ani = event.getSource();
if (ani != null) {
ani.refresh(); // to fix issue with viewIdResName = null on Android 6+
}
}
I found that if the viewId isn't available, querying the focused element seems to work:
AccessibilityNodeInfo source = findFocus(AccessibilityNodeInfo.FOCUS_INPUT);
viewIdResourceName = source.getViewIdResourceName();
returns the correct view id
I'm developing Android application, where tries to obtain remote JSON file using aquery. Target Version is Android 4.3 (api ver. 18). Before I was trying to get JSON using tumblr API, but I thought that maybe I'm constructing url wrong way, so I decided to try with easier JSON url, which you can see in code below. What I'm getting all over is Network Error with code -101.
I will be grateful for any tip.
public class WeHaveTheMunchiesActivity extends Activity {
private AQuery mAQ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_viewer);
mAQ=new AQuery(this);
String url="http://www.google.com/uds/GnewsSearch?q=Obama&v=1.0";
mAQ.ajax(url, JSONObject.class, new AjaxCallback<JSONObject>(){
#Override
public void callback(String url, JSONObject json, AjaxStatus status){
Toast.makeText(getApplicationContext(), status.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
I know its too late, but if someone have same problem (status -101) and internet permission are present, but you still got -101 try this
add line in your application tag of your manifest.xml
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
Add this permission in AndroidManifest.xml :
<uses-permission android:name="android.permission.INTERNET"/>
I have a little app that I made that have worked for months, but suddenly I get a
android.os.NetworkOnMainThreadException
I havent changed any code, this is the line that crashes
try {
endPoint = InetAddress.getByName(target.getToIp());
port = target.getPort();
socket = new DatagramSocket();
}
catch(Exception e) {
}
Note that I'm not sending anything I'm just creating the instances, it breaks already on the InetAddress row.
It wored as late as last night, all I have done on the phone is run update on Google play, it updated to latest version of Google Maps, but that cant have anything todo with it?
It works in the emulator, only my HTC One X that breaks
Full code here
https://github.com/AndersMalmgren/FreePIE/tree/master/Lib/Android/FreePIE%20Android%20IMU
edit:
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.freepie.android.imu"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Tried to move the problem code to the thread instead, now it wont break, but the socket is set to null.
running = true;
worker = new Thread(new Runnable() {
public void run(){
try {
endPoint = InetAddress.getByName(target.getToIp());
port = target.getPort();
socket = new DatagramSocket();
}
catch(Exception e) {
Exception err = e;
}
while(running) {
try {
sync.await();
} catch(Exception e) {}
Send();
}
try {
socket.disconnect();
}
catch(Exception e) {}
}
});
worker.start();
update:
Solution was to add some failback if user types a DNS instead of a IP
https://github.com/AndersMalmgren/FreePIE/commit/e8017e02a7893d9df41e4ed67a037f016b6a7d39
You will get NetworkOnMainThreadException on Android 4.0+ by default if you attempt to do network I/O on the main application thread. getByName() does a DNS lookup if you provide a domain name (instead of dotted-IP notation), and that will trigger NetworkOnMainThreadException.
You must put your code in AsyncTask like this:
new AsyncTask<Void,Void,Void>(){
doInBackground(){
endPoint = InetAddress.getByName(target.getToIp());
port = target.getPort();
socket = new DatagramSocket();
}
}.execute();
Note this code is not a working one, please read more about AsyncTasks here
Use Network on main thread is not allowed from the Android 4.0. If you run the code at Android 2.3 or other, it will not throw any exception.
Ok, I have been working on a Android application for a while. It's basicaly a RSS reciever. I use RSS to check the news, weather forecast, TV schedule and Horoscope.
Everything was fine while I was testing it on Android 2.3.3, 2.3.6 and even on 2.1; but when I sent it to my friend who has Android 4.0 it did not work. I was suspicious so I tested it on emulator. Nor 4.0, nor 4.1 Emulators can run it. Here I provide Manifest and one class. If anybody knows how to fix this, that will be great.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="XXX.XXXXX.XXX"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="14" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".Vodic"
android:label="#string/title_activity_pocetna" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Pomoc"
android:label="#string/m_tel_vodi_za_odlu_ne"
></activity>
<activity
android:name=".Pomocna"
android:label="#string/m_tel_vodi_za_odlu_ne"
></activity>
.
.
.
<activity
android:name=".TvRasporedTreca"
android:label="#string/m_tel_vodi_za_odlu_ne"
></activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<!-- Needed to check when the network connection changes -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
</manifest>
And here's one class:
public class Vodic extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pocetna);
Button tv = (Button)findViewById(R.id.tv);
Button vijesti = (Button)findViewById(R.id.vijesti);
Button horoskop = (Button)findViewById(R.id.horoskop);
Button vremenska_prognoza = (Button)findViewById(R.id.vremenska_prognoza);
Button o_aplikaciji = (Button)findViewById(R.id.o_aplikaciji);
Button pomoc = (Button)findViewById(R.id.pomoc);
tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Intent fy=new Intent(getApplicationContext(), TV_Raspored.class);
startActivity(fy);
}
});
.
.
.
pomoc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Intent fy=new Intent(getApplicationContext(), Pomoc.class);
startActivity(fy);
}
});
}
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if(netInfo != null && netInfo.isConnected()) {
return true;
}
return false;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_pocetna, menu);
return true;
}
}
So, to sum up. It works on 2.1 and 2.3.3 but doesn't on 4.0 and 4.1 . I have no Idea what's wrong.. so if anybody knows, please help..
From Android 3.x and onward Google has added some checks that generate errors if your application employs very bad practices.
Without a log it is hard to confirm, but the most likely scenario is that you are making network operations in the core of your activities, generating a NetworkOnUIThread exception.
It is NOT a bug in the Android framework. The problem is that your activities run in the main thread, ie the UI thread.
So when you make a network call in an Activity, the whole UI freezes until you get an answer (or a timeout); which is something that you absolutely want to avoid.
An easy solution to this issue is to use AsyncTask : it is an easy to implement built-in solutions to make operations in a secondary thread.
Using the guide on JSoup's website I wrote the following code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
Document doc = Jsoup.connect("http://google.com").get();
Elements links = doc.getElementsByTag("a");
for(Element ele : links){
Log.i("Menu", ele.text());
}
} catch (IOException e) {
}
setContentView(R.layout.main);
}
I added the internet permission in my manifest file but it keeps throwing an IOException!
I tested your code and it should work fine... I would imagine your permission was put in the wrong spot. It goes BEFORE your application definition in your manifest:
here are the first few lines of my manifest that runs your code:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application android:icon="#drawable/icon" android:label="#string/app_name">