Android Studio Retrofit Call Failure - java

I'm trying to use Retrofit in my app via Java. I'm using this worldtime API. You can call this URL in your browser to see the response : http://worldtimeapi.org/api/timezone/Europe/Istanbul (response comes too late, just refresh your browser)
I added this line to my AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
I added these to gradle
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
I only want to see few keys of response, so I created a class TimeForIstanbul.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class TimeForIstanbul {
#SerializedName("day_of_week")
#Expose
public Integer dayOfWeek;
#SerializedName("utc_datetime")
#Expose
public String utcDatetime;
#SerializedName("week_number")
#Expose
public Integer weekNumber;
public Integer getDayOfWeek() {
return dayOfWeek;
}
public void setDayOfWeek(Integer dayOfWeek) {
this.dayOfWeek = dayOfWeek;
}
public String getUtcDatetime() {
return utcDatetime;
}
public void setUtcDatetime(String utcDatetime) {
this.utcDatetime = utcDatetime;
}
public Integer getWeekNumber() {
return weekNumber;
}
public void setWeekNumber(Integer weekNumber) {
this.weekNumber = weekNumber;
}
}
I created my interface ApiService.java
import retrofit2.Call;
import retrofit2.http.GET;
public interface ApiService {
#GET("Europe/Istanbul")
Call<TimeForIstanbul> getTime();
}
And simply I edited my MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MainActivity extends AppCompatActivity {
private Retrofit retrofit;
private ApiService apiService;
private String BASE_URL = "http://worldtimeapi.org/api/timezone/";
private Call<TimeForIstanbul> timeForIstanbulCall;
private TimeForIstanbul timeForIstanbul;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRetrofitSettings();
}
private void setRetrofitSettings(){
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
apiService = retrofit.create(ApiService.class);
timeForIstanbulCall = apiService.getTime();
timeForIstanbulCall.enqueue(new Callback<TimeForIstanbul>() {
#Override
public void onResponse(Call<TimeForIstanbul> call, Response<TimeForIstanbul> response) {
if(response.isSuccessful()){
timeForIstanbul = response.body();
System.out.println(timeForIstanbul.getDayOfWeek());
}
}
#Override
public void onFailure(Call<TimeForIstanbul> call, Throwable t) {
System.out.println("Error is ");
System.out.println(t.toString());
}
});
}
}
And when I run this app, I see
I/System.out: Error is
java.net.UnknownServiceException: CLEARTEXT communication to worldtimeapi.org not permitted by network security policy
on logcat so it goes to onFailure. What am I missing? What is wrong here? My resource for this example is this video

What you have to do to solve the problem is add this on my manifest.xml
android:usesCleartextTraffic="true"
But you may have to use other approaches you can take a look on android-8-cleartext-http-traffic-not-permitted.

android:usesCleartextTraffic="true"
Add This line in your manifest application
It will allow to connect with without SSL certified URL

You have to use https with that api. Change:
private String BASE_URL = "http://worldtimeapi.org/api/timezone/";
to
private String BASE_URL = "https://worldtimeapi.org/api/timezone/";
If you want to have a cleartext communication with the api you have to follow the steps from the Android documentation

Related

400 error code while using twitter search API

I am trying to query Twitter on my android app and retrieve all the tweets related to the keyword "AgilebizKE" using retrofit.
I am currently getting a 400 error code. After doing some research i have found that either my query parameters are wrong or my request isn't 'authorized'. However, i see no issues with my query parameters.
Main Activity relevant code:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.twitter.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
tweetAPI tweetapi = retrofit.create(tweetAPI.class);
Call<List<tweet>> call = tweetapi.getTweets();
call.enqueue(new Callback<List<tweet>>() {
#Override
public void onResponse(Call<List<tweet>> call, Response<List<tweet>> response) {
if (!response.isSuccessful()) {
tweets_results.setText("code: " + response.code());
return;
}
List<tweet> tweets = response.body();
for (tweet tweet : tweets){
String content = "";
content+="Created at: "+tweet.getCreated_at()+"\n";
content+="Text: "+tweet.getText()+"\n";
content+="Retweets: "+tweet.getRetweet_count()+"\n";
content+="Favs: "+tweet.getFavorite_count()+"\n\n";
tweets_results.append(content);
}
}
#Override
public void onFailure(Call<List<tweet>> call, Throwable t) {
tweets_results.setText(t.getMessage());
}
});
Interface
public interface tweetAPI {
#GET("1.1/search/tweets.json?q=AgilebizKE")
Call<List<tweet>> getTweets();
}
Tweet pojo
ublic class tweet {
private String created_at;
private String text;
private String retweet_count;
private String favorite_count;
public String getCreated_at() {
return created_at;
}
public String getText() {
return text;
}
public String getRetweet_count() {
return retweet_count;
}
public String getFavorite_count() {
return favorite_count;
}
}
Ok so i decided to switch to using twitter4j instead of retrofit since it is much easier and quicker. For more details on this go to this site: http://twitter4j.org/
I will now explain how i implemented twitter search functionality for my use case.
Android Manifest
Add these permissions
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
build.gradle(Module: app)
Add this
implementation files('libs/twitter4j-core-4.0.7.jar')
Next, you have to create a JobIntentService so as to run the network functions, that twitter4j requires, off the main thread. This is the video I used to better understand this concept: https://www.youtube.com/watch?v=B4gFbWnNpac&t=567s
TweetJobIntentService.java
Before proceeding any further, register your app and get its personal OAuth twitter credentials from the twitter for devs portal. Fill these credentials where I have indicated in the code sample below.
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.core.app.JobIntentService;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import java.util.ArrayList;
import java.util.List;
import twitter4j.Query;
import twitter4j.QueryResult;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
public class TweetJobIntentService extends JobIntentService {
private static final String TAG = "TweetJobIntentService";
static void enqueueWork(Context context, Intent work) {
enqueueWork(context, TweetJobIntentService.class, 123, work);
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate: ");
}
#Override
protected void onHandleWork(#NonNull Intent intent) {
Log.d(TAG, "onHandleWork: ");
List tweets = new ArrayList();
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer("Your_OAuthConsumerKey", "Your_AuthConsumerSecret");
AccessToken accessToken = new AccessToken("Your_OAuthAccessToken", "Your_OAuthAccessTokenSecret");
twitter.setOAuthAccessToken(accessToken);
Query query = new Query(Your_search_Keyword);
try {
QueryResult result = twitter.search(query);
for (Status status : result.getTweets()) {
Log.d(TAG, status.getText());
}
if (isStopped()) return;
} catch (TwitterException e) {
e.printStackTrace();
}
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDeastroy");
}
#Override
public boolean onStopCurrentWork() {
Log.d(TAG, "onStopCurrentWork");
return super.onStopCurrentWork();
}
}
Your retrieved tweets should be printed in logcat.
Your Main activity/fragment
Here, you will initiate/call your JobIntentService. For me, my service is initiated in a fragment in the onViewCreated method. Yours can be initiated following a button click or whatever you wish.
Intent jobserviceIntent = new Intent(getActivity(), TweetJobIntentService.class);
TweetJobIntentService.enqueueWork(getActivity(), jobserviceIntent);

Android MVVM architecture and observing changes on data from an API

I'm new to the Android MVVM architecture. I have an API running locally with data ("deals") in it. I'd like to simply make a request to the API and display that data in a text field. Currently the data does not show up when the fragment is first loaded, but if I go to another activity and then back to the fragment it loads.
There are 3 classes of importance here.
DashboardViewModel.java:
package com.example.android_client.ui.dashboard;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.example.android_client.models.Deal;
import com.example.android_client.repository.Repository;
import java.util.List;
public class DashboardViewModel extends ViewModel {
private MutableLiveData<String> mText;
private Repository repository;
private MutableLiveData<List<Deal>> deals = null;
public void init() {
if(this.deals == null) {
this.repository = Repository.getInstance();
this.deals = this.repository.getDeals();
}
}
public DashboardViewModel() {
this.mText = new MutableLiveData<>();
}
public LiveData<List<Deal>> getDeals() {
return this.deals;
}
}
DashboardFragment.java:
package com.example.android_client.ui.dashboard;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import com.example.android_client.R;
import com.example.android_client.models.Deal;
import java.util.List;
public class DashboardFragment extends Fragment {
private DashboardViewModel dashboardViewModel;
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_dashboard, container, false);
final TextView textView = root.findViewById(R.id.text_dashboard);
dashboardViewModel = ViewModelProviders.of(this).get(DashboardViewModel.class);
dashboardViewModel.init();
dashboardViewModel.getDeals().observe(this, new Observer<List<Deal>>() {
#Override
public void onChanged(List<Deal> deals) {
if (deals != null && !deals.isEmpty()) {
System.out.println(deals.get(0).toString());
textView.setText(deals.get(0).toString());
}
}
});
return root;
}
}
and Repository.java:
package com.example.android_client.repository;
import androidx.lifecycle.MutableLiveData;
import com.example.android_client.models.Deal;
import com.google.gson.Gson;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
public class Repository {
private static Repository instance;
private ArrayList<Deal> dealsList = new ArrayList<>();
private final OkHttpClient client = new OkHttpClient();
public static Repository getInstance() {
if(instance == null) {
instance = new Repository();
}
return instance;
}
private Repository() {}
public MutableLiveData<List<Deal>> getDeals() {
setDeals();
MutableLiveData<List<Deal>> deals = new MutableLiveData<>();
deals.setValue(dealsList);
return deals;
}
private void setDeals() {
Request request = new Request.Builder()
.url("http://10.0.2.2:8000/api/deals?<params here>")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(#NotNull Call call, #NotNull IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(#NotNull Call call, #NotNull Response response) throws IOException {
try (ResponseBody responseBody = response.body()) {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
String jsonDeals = responseBody.string(); // can only call string() once or you'll get an IllegalStateException
Deal[] deals = new Gson().fromJson(jsonDeals, Deal[].class);
dealsList = new ArrayList<>(Arrays.asList(deals));
}
}
});
}
}
When stepping through the code in the Repository class I can see that setDeals() is called when I load the fragment, and the request in the callback is queued. The first time getDeals() returns, it returns a list of 0 deals (within the MutableLiveData object).
onResponse in the callback doesn't run until the fragment is already loaded. When debugging I can see that the data is in the objects (all the Gson stuff works fine), but onChanged doesn't get called again (which sets the text view).
Am I not observing changes on the deals properly?
Your code is not working due to a new live data instance be created whenever getDeals() is called and the api response value be informed to other live data instance. You must set api response value to same instance of MutableLiveData returned by getDeals()
I'm not saying that it is the best architectural solution, but if you create a mutable live data as a class attribute and return it whenever getDeals() is called. Probably, it's going to work.
Also, a good practice is return a LiveData and not a MutableLiveData to not allowing a external component modify the internal value.
Please, take a look at the piece of code below.
OBS: Maybe, there is some syntax error, because I have not compiled it
import com.example.android_client.models.Deal;
import com.google.gson.Gson;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
public class Repository {
private static Repository instance;
private ArrayList<Deal> dealsList = new ArrayList<>();
private final OkHttpClient client = new OkHttpClient();
private MutableLiveData<List<Deal>> _deals = new MutableLiveData<>();
private LiveData<List<Deal>> deals = _deals
public static Repository getInstance() {
if(instance == null) {
instance = new Repository();
}
return instance;
}
private Repository() {}
public LiveData<List<Deal>> getDeals() {
setDeals();
return deals;
}
private void setDeals() {
Request request = new Request.Builder()
.url("http://10.0.2.2:8000/api/deals?<params here>")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(#NotNull Call call, #NotNull IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(#NotNull Call call, #NotNull Response response) throws IOException {
try (ResponseBody responseBody = response.body()) {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
String jsonDeals = responseBody.string(); // can only call string() once or you'll get an IllegalStateException
Deal[] deals = new Gson().fromJson(jsonDeals, Deal[].class);
dealsList = new ArrayList<>(Arrays.asList(deals));
_deals.setValue(dealsList);
}
}
});
}
}
When
I think this would help. Try postValue on MutableLiveData in onResponse of network call. Please change your repository class like below:
package com.example.android_client.repository;
import androidx.lifecycle.MutableLiveData;
import com.example.android_client.models.Deal;
import com.google.gson.Gson;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
public class Repository {
private static Repository instance;
private ArrayList<Deal> dealsList = new ArrayList<>();
private final OkHttpClient client = new OkHttpClient();
MutableLiveData<List<Deal>> deals = new MutableLiveData<>();
public static Repository getInstance() {
if(instance == null) {
instance = new Repository();
}
return instance;
}
private Repository() {}
private MutableLiveData<List<Deal>> getDeals() {
Request request = new Request.Builder()
.url("http://10.0.2.2:8000/api/deals?<params here>")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(#NotNull Call call, #NotNull IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(#NotNull Call call, #NotNull Response response) throws IOException {
try (ResponseBody responseBody = response.body()) {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
String jsonDeals = responseBody.string(); // can only call string() once or you'll get an IllegalStateException
Deal[] deals = new Gson().fromJson(jsonDeals, Deal[].class);
dealsList = new ArrayList<>(Arrays.asList(deals));
deals.postValue(dealsList);
}
}
});
return deals;
}
}
in your repository class in function get deals. you are initializing live data. requesting url in background thread and posting value on live data which is not received from server yet.
to solve this create livedata instance in constructor of repository and postvalue on livedata in onResponse callback.
//sorry for bad writting, posted from mobile.

NoSuchMethodError error with Retrofit GET request

I am supposed to simply send a get-request to an endpoint and retrieve the data, and had success with post-request version of this code. However, it doesn't seem to work for GET. I have a simple model which is like this
public class Brand {
private String id;
private String name;
public Brand(String id, String name) {
this.id = id;
this.name = name;
}}
And my repository
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.http.*;
import java.util.List;
public interface Service {
#Headers({ "Accept: application/json" })
#GET("/brands")
Call<List<Brand>> getBrandList();
#Headers("Content-Type:application/json")
#POST("/login/email")
Call<ResponseBody> login(#Body LoginInfo loginInfo);
}
And finally this is where I try to run
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import java.io.IOException;
import java.util.List;
public class BrandRepoImp {
private static final String apiUrl = "http://example.com/grc/main/";
public static void main(String... args) throws IOException {
BrandRepoImp app=new BrandRepoImp();
app.getBrandList();
}
public void getBrandList() throws IOException {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(apiUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
Service resource = retrofit.create(Service.class);
Call<List<Brand>> brands = resource.getBrandList();
System.out.println(brands.execute().body());
}
}
It returns this error
Exception in thread "main" java.lang.NoSuchMethodError: okio.BufferedSource.rangeEquals(JLokio/ByteString;)Z
at okhttp3.internal.Util.bomAwareCharset(Util.java:431)
at okhttp3.ResponseBody$BomAwareReader.read(ResponseBody.java:249)
at com.google.gson.stream.JsonReader.fillBuffer(JsonReader.java:1295)
at com.google.gson.stream.JsonReader.nextNonWhitespace(JsonReader.java:1333)
at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:549)
at com.google.gson.stream.JsonReader.peek(JsonReader.java:425)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:74)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:119)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:218)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:180)
at com.retrofitexample.demo.login.BrandRepoImp.getBrandList(BrandRepoImp.java:27)
at com.retrofitexample.demo.login.BrandRepoImp.main(BrandRepoImp.java:17)
Process finished with exit code 1

Is there any jax-rs like libraries on Android to implement restful service?

Hello guys I have very basic knowledge on rest services. I have implemented a basic program on Java to get output "hello world!" at URI http://localhost:8080/greeting/greet
package greeting;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
#Path("/greet")
public class Greet {
#GET
#Produces(MediaType.TEXT_PLAIN)
public String justGreet(){
return "hello world!";
}
}
I would like to implement similar kind on Android, so that I can see output at some URI on any browser in that network. I'm confusing which dependencies or libraries have to use for Android to get that. Hoping for answers.
Thanks a ton in Advance!
Edit: I have used Retrofit library as suggested, it's executing well but I cannot see the output "Hello World!" at this URI http://192.168.0.104:8080/greeting/greet1, like usig Java and Jax-rs.
here is the implementation
package abc.xyz.com.retrotut;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MainActivity extends AppCompatActivity {
private static final String URL = "http://192.168.0.104:8080/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiService api = retrofit.create(ApiService.class);
Greeting greet = new Greeting("Hello World!");
Call<Greeting> call = api.getGreeting(greet);
call.enqueue(new Callback<Greeting>() {
#Override
public void onResponse(Call<Greeting> call, Response<Greeting> response) {
Toast.makeText(getApplicationContext(), "Success", Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<Greeting> call, Throwable t) {
Toast.makeText(getApplicationContext(), "Failed", Toast.LENGTH_SHORT).show();
}
});
}
}
Pojo kind
public class Greeting {
private String greet;
public Greeting(String greet) {
this.greet = greet;
}
}
Interface
public interface ApiService {
#POST("greeting/greet1")
Call<Greeting> getGreeting(#Body Greeting greet);
}
However I'm getting "success", when executing application, I cannot get output what I've wanted. Are there any libraries which should I use or any alternatives?

Using JAVA RMI in Android application

I've read lots of threads about this issue, and i couldnt see a 'real' solution for it.
I made a java project - which is a rmi server and i have an android application which suppose to be also a rmi client.
When i checked if the server works I wasn't wise enough to test the client on an android project and i made a test client on a simple java project.
Now when i'm trying to connect my android application to server i fail because the android project doesn't recognize the java rmi package.
Why that happen? what should I do?
You can also use the following library LipeRMI
Here is an example of a Android client interacting with Java Server via LipeRMI.
Create the Following 2 classes and a interface for Java application.
//TestService.java
package test.common;
public interface TestService {
public String getResponse(String data);
}
//TestServer.java
import java.io.IOException;
import java.net.Socket;
import test.common.TestService;
import lipermi.exception.LipeRMIException;
import lipermi.handler.CallHandler;
import lipermi.net.IServerListener;
import lipermi.net.Server;
public class TestServer implements TestService {
public TestServer() {
try {
CallHandler callHandler = new CallHandler();
callHandler.registerGlobal(TestService.class, this);
Server server = new Server();
server.bind(7777, callHandler);
server.addServerListener(new IServerListener() {
#Override
public void clientDisconnected(Socket socket) {
System.out.println("Client Disconnected: " + socket.getInetAddress());
}
#Override
public void clientConnected(Socket socket) {
System.out.println("Client Connected: " + socket.getInetAddress());
}
});
System.out.println("Server Listening");
} catch (LipeRMIException | IOException e) {
e.printStackTrace();
}
}
#Override
public String getResponse(String data) {
System.out.println("getResponse called");
return "Your data: " + data;
}
}
//TestMain.java
public class TestMain {
public static void main(String[] args) {
TestServer testServer = new TestServer();
}
}
Android client:
//MainActivity.java
package com.example.lipermidemoandroidclient;
import java.io.IOException;
import test.common.TestService;
import lipermi.handler.CallHandler;
import lipermi.net.Client;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Looper;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
private String serverIP = "192.168.1.231";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnGet = (Button) findViewById(R.id.btnGet);
btnGet.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
new Conn().execute();
}
});
}
class Conn extends AsyncTask<Void, Void, MainActivity> {
#Override
protected MainActivity doInBackground(Void... params) {
Looper.prepare();
try {
CallHandler callHandler = new CallHandler();
Client client = new Client(serverIP, 7777, callHandler);
TestService testService = (TestService) client.getGlobal(TestService.class);
String msg = testService.getResponse("qwe");
//Toast.makeText(MainActivity.this, testService.getResponse("abc"), Toast.LENGTH_SHORT).show();
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
Looper.loop();
return null;
}
}
}
//TestService.java
package test.common;
public interface TestService {
public String getResponse(String data);
}
Add the LipeRMI library to both the projects
Make sure you add INTERNET permission in Android project
Also make sure you have the TestService.java file placed in same package name at both places for eg. test.common package here
Also change value of serverIP variable in Android MainActivity.java to the IP of the machine running the Java code.
I had the same problem and changed my communication to socket communication!
As far as I could figure out Java.rmi unfortunately does not come with Android and therefore it's not possible to use it.
However there are some more disucssions in this post.
Android doesn't support RMI. You should change to socket or raw TCP communication.

Categories