ActiveAndroid - How to save data into Android database - android

I have an Android app in which I'm getting data from an API. Now I need to save this data from the API into an ActiveAndroid table.
So I've got stuck on that part.
Here is my table Partners(Active Android):
#Table(name = "Partners")
public class Partners extends Model {
#Column(name = "Name")
public String name;
public Partners() {}
public Partners(String name) {
this.name = name;
}
}
This is my POJO model:
public class Partner {
#Expose
#Column(name = "name")
private List<String> name;
public List<String> getName() {
return name;
}
public void setName(List<String> name) {
this.name = name;
}
}
And here is part of code where I'm getting data and trying to save it into ActiveAndroid table:
public class DownloadMain extends Fragment implements Callback<Partner> {
private static final String TAG = DownloadMain.class.getSimpleName();
private Button dloadPartners;
private Call callPartners;
public DownloadMain() {}
public DownloadMain newInstance() { return new DownloadMain(); }
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.download_main, container, false);
dloadPartners = (Button) view.findViewById(R.id.downloadPartners);
dloadPartners.setOnClickListener(btnListener);
callPartners = APIHelper.getApiService().getPartners();
return view;
}
Button.OnClickListener btnListener = (new Button.OnClickListener() {
#Override
public void onClick(View v) {
callPartners.clone().enqueue(DownloadMain.this);
insertPartners();
}
});
#Override
public void onResponse(Call call, Response response) {
if(response.body() == null) {
try {
response.errorBody().string();
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getActivity(), "No Partners!", Toast.LENGTH_SHORT).show();
} else {
List<String> partners = (List<String>) response.body();
Log.d(TAG, "Number of partners received: " + partners.size());
Toast.makeText(getActivity(), "Partners downloaded!", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call call, Throwable t) {
}
private void insertPartners() {
ActiveAndroid.beginTransaction();
try {
for (int i = 0; i < 100; i++) {
Partner partner = new Partner();
partner.getName();
//partner.save();
}
ActiveAndroid.setTransactionSuccessful();
} finally {
ActiveAndroid.endTransaction();
}
}
}
The problem is how to save data I get from the API into table, so I need few tips and advice how to properly do that.
Question: I need some tips how to save data I get from web with retrofit into ActiveAndroid table?

please check my old weather app project, where I'f already used ActiveAndroid.
Here's one of my saving to database methods:
public void saveCityDataToDatabase(Forecast forecast) {
ActiveAndroid.beginTransaction();
try {
if (WeatherApplication.getCityList().size() > 0) {
new Delete().from(City.class).execute();
}
forecast.getCity().getCoord().save();
forecast.getCity().save();
ActiveAndroid.setTransactionSuccessful();
} finally {
ActiveAndroid.endTransaction();
}
Log.d("DATABASE", "WeatherApplication: " + WeatherApplication.getCityList());
} }
From: https://github.com/piotrek1543/LocalWeather/blob/master/app/src/main/java/com/piotr/localweather/repositories/WeatherDatabaseRepository.java
With ActiveAndroid is really easy to save Objects like Weather or Wind, but for some purposes you would need to use TypeSerializer. In your example you would use it to deserialize and save List<String>.
As you may notice from its Github page: https://github.com/pardom/ActiveAndroid
this libary is not maintained more than two years, so I can say clearly that is deprecated and not good to use to fresh projects. It may have many bugs. For me, implementation of this lib was a pretty painful.
Instead of ActiveAndroid, I would recommend you to use Realm, greenDao or ORMLite library to store your data.
Hope it would help

First of all create a parameterless constructor and call super in it.
public Partners() {
super();
}
then a partern.save() should suffice.
To retreive all the parterns you could do something like
List<Partner> partners = new Select().from(Partner.class).execute());
if you get the Partner object fro web via retrofit, probably you are using Gson to put the json in partner object. so you can make that object extending model, put a paramterless constructor like above and put a #Table annotation.

Related

Retrofit parse selective JSON data

I am parsing JSON data from this URL. Calling like this:
call.enqueue(new Callback<List<Gift>>() {
#Override
public void onResponse(Call<List<Gift>> call, Response<List<Gift>> response) {
List<Gift> places = response.body();
}
}
But I don't want this. I want to first check if the flag is 0. If it is, then I want to get only the values of the list key. And want to use the following model:
class Gift extends RealmObject{
String code, name;
//getters & setters
}
How can I achieve this?
Any help is highly appreciated.
Try this way sample
class GiftList{
String flag;
String flag1;
List<Gift> gifts;
}
call.enqueue(new Callback<List<GiftList>>() {
#Override
public void onResponse(Call<List<GiftList>> call, Response<List<GiftList>> response) {
List<GiftList> places = response.body();
if(places.getFlag().equals("0"){
List<Gift> gifts=places.getList();
}
}
You can create another POJO to store your Gift class, which store the outer value like flag and flag1, then you can access the flag to determine if you are going to go into list
here is how it looks like:
class GiftResponse extends RealmObject{
int flag;
String flag1;
Gift[] list;
//getters & setters
}
and keep your Gift class as it is, then you can get the data like:
call.enqueue(new Callback<GiftResponse>() {
#Override
public void onResponse(Call<GiftResponse> call, Response<GiftResponse> response) {
GiftResponse res = response.body();
if(res.getFlag() == 0) {
Gift[] arrGifts = res.getList();
}
}
}
ofcourse using this approach you change the call response type.
You can create a ResponseWrapper class as below:
public class ResponseWrapper<T> {
private T data;
#JsonProperty("flag")
public int flag;
#JsonProperty("flag1")
public String flag1;
public T getData() {
return data;
}
}
And modify your callback
call.enqueue(new Callback<ResponseWrapper<List<Gift>>>() {
#Override
public void onResponse(Call<ResponseWrapper<List<Gift>>> call, Response<ResponseWrapper<List<Gift>>> response) {
int flag = response.body().flag;
List<Gift> places = response.body().getData();
}
}

Can't make retrofit and Gson pull data from deployd

I am very new to Android development. I have this little project of mine that I need to get to work by accessing an api that I created locally on my mac with deployd. The api is accessible from localhost:2403/subjects. I have followed the retrofit and gson guide but so far I only keep errors and nothing viable to work with. At this point im kinda stuck. I need to get the subjects from the api and show them in a scrollable list.
I have set up Retrofit and Gson to be able to talk to the API. Therefore I have made a few classes and interfaces.
First the Subject class
public class Subject {
int id;
String name;
int ects;
int grade;
int period;
int main;
public int getMain() {
return main;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public int getEcts() {
return ects;
}
public int getGrade() {
return grade;
}
public int getPeriod() {
return period;
}
}
then I created a HslSubjects class which is plain and simple to hold all the subjects I get.
public class HslSubjects {
List<Subject> subjects;
}
and the api interface
public interface subjectEndpointApi {
#GET("/subjects")
Call<HslSubjects> loadSubjects();
}
followed by an adapter
public class SubjectResponse {
#SerializedName("subjects")
List<Subject> subjects;
public SubjectResponse() {
subjects = new ArrayList<Subject>();
}
public static SubjectResponse parseJSON(String response) {
Gson gson = new GsonBuilder().create();
SubjectResponse subjectResponse = gson.fromJson(response, SubjectResponse.class);
return subjectResponse;
}
}
Finally in my mainActivity I run everything
public class MainActivity extends ListActivity implements Callback<HslSubjects> {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
requestWindowFeature(Window.FEATURE_PROGRESS);
ArrayAdapter<Subject> arrayAdapter = new ArrayAdapter<Subject>(this, android.R.layout.simple_list_item_1, android.R.id.text1, new ArrayList<Subject>());
setListAdapter(arrayAdapter);
setProgressBarIndeterminateVisibility(true);
setProgressBarVisibility(true);
Log.i("api", "preparing to make the api call");
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://10.0.3.2:2403") //10.0.3.2
.addConverterFactory(GsonConverterFactory.create())
.build();
// preparing the call in retrofit
subjectEndpointApi subjectEndpointApi = retrofit.create(subjectEndpointApi.class);
Call<HslSubjects> call = subjectEndpointApi.loadSubjects();
call.enqueue(this);
}
#Override
public void onResponse(Call<HslSubjects> call, Response<HslSubjects> response) {
setProgressBarIndeterminateVisibility(false);
HslSubjects hslSubjects = response.body();
Log.i("subjects", "end of response");
}
#Override
public void onFailure(Call<HslSubjects> call, Throwable t) {
Toast.makeText(MainActivity.this, t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
Log.i("subjects", "Oops error");
}
}
But somehow it always goes to the onFailure class. The emulator gives the following error:
Seems like your server JSON is not what you are expecting on your device.
Error says that android wants JSON object, but the json you pass is kinda array.
Try to add logging and see what is the problem there.
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
So I guess you should write something like:
public interface subjectEndpointApi {
#GET("/subjects")
Call<List<Subject>> loadSubjects();
}

How to get JSON array from web api with retrofit and active android

I have an web api which gives me array of partners and it looks like this:
[
"partner1",
"partner2",
"partner3",
"....",
"parner222"
]
I have Table partners (ActiveAndroid) in which I would like to save all partners from api.
#Table(name = "Partners")
public class Partners extends Model {
#Column(name = "Name")
String name;
public Partners() {}
public Partners(String name) {
this.name = name;
}
}
Here is my Pojo model class:
public class Partners {
#SerializedName("name")
#Expose
private List<String> name = new ArrayList<String>();
public List<String> getName() {
return name;
}
public void setName(List<String> name) {
this.name = name;
}
}
This is my interface
public interface APIService {
#GET("Partners")
Call<Partners> getPartners();
}
And this is my APIHelper with api url
public class APIHelper {
public static APIService apiService;
public static APIService getApiService() {
if (apiService == null) {
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://part-oflink.domain.com/partners.json/")
.addConverterFactory(GsonConverterFactory.create()).build();
apiService = retrofit.create(APIService.class);
}
return apiService;
}
}
And this is Fragment where I have an Button on which I would like to implement onClick method to get data from API and save it into Partners table.
public class DownloadMain extends Fragment implements Callback<Partners> {
private Button dloadPartners;
private Call<Partners> callPartners;
public static APIService apiService;
public DownloadMain() {}
public DownloadMain newInstance() { return new DownloadMain(); }
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.download_main, container, false);
dloadPartners = (Button) view.findViewById(R.id.downloadPartners);
dloadPartners.setOnClickListener(btnListener);
callPartners = APIHelper.getApiService().getPartners();
callPartners.enqueue(this);
return view;
}
Button.OnClickListener btnListener = (new View.OnClickListener() {
#Override
public void onClick(View v) {
//here I need to implement that on click downloads me data
// and save it into my Partners table
}
});
#Override
public void onResponse(Call<Partners> call, Response<Partners> response) {
//here I'm trying to put api response into array list
if (response.body() != null) {
ArrayList<String> partnersList = new ArrayList<>();
partnersList = response.body();
}
}
#Override
public void onFailure(Call<Partners> call, Throwable t) {
}
}
And now I have stuck. I would like to implement onClick Button method to get data from API. In onResponse() method I'm trying to put data into ArrayList to check if data is recieved. And also I would like to save this data into my table partners.
I would be grateful if someone could help me or guide me to fix this. This is first time I'm doing with retrofit and api.
Can somebody help me or guide me to successfully get data from API and save it into table Partners?
The way you are trying to parse the JSON string(array of partners) is not the appropriate. Your JSON should like this:
{
"partners":
["partner1", "partner2", "partner3", ...]
}
And the POJO model class should be:
class Partners{
private List<String> partners;
public Partners(){}
public void setList(List<String> partners) {
this.partners = partners;
}
public List<String> getList() {
return this.partners;
}
//setter and getter methods
}
If the response is not empty then for printing the values:
for(Partner partner: response){
Log.d("Partner Name",partner.name);
}
And if you are using any ORM for the database, then call its DAO and pass the values to save in the DB.

How to structure my app using MVP with rxjava and retrofit to get data out of Observables?

So I'll try to keep this question as to-the-point as possible, but it will involve code snippets that traverse an entire codepath.
For context, I am fairly new and completely self-taught for Android dev, so please notify me of any clear misunderstandings/poor organization throughout. The main focus of the question is bug I am experiencing now, which is that, after a network request, the variable that was supposed to be set as a result of that network request is null, because the code moved forward before the network request completed.
Here is my activity method. It is supposed to populate the mFriends variable with the result of mUserPresenter.getUserList(), which is (unfortunately) null:
/**
* Grabs a list of friends, populates list with UserAdapter
*/
#Override
public void onResume(){
super.onResume();
mUserPresenter = new UserPresenter();
mFriends = mUserPresenter.getUserList();
if (mGridView.getAdapter() == null) {
UserAdapter adapter = new UserAdapter(getActivity(), mFriends);
mGridView.setAdapter(adapter);
}
else{
((UserAdapter)mGridView.getAdapter()).refill(mFriends);
}
}
Here is how I am structuring my UserPresenter method getUserList:
public List<User> getUserList()
{
ApiService.get_friends(this);
return mUserList;
}
The real magic happens in the ApiService class:
public static void get_friends(final UserPresenter userPresenter){
ApiEndpointInterface apiService = prepareService();
apiService.get_friends().
observeOn(AndroidSchedulers.mainThread())
.subscribe(
new Action1<List<User>>()
{
#Override
public void call(List<User> users) {
userPresenter.setList(users);
}
}
);
}
My thinking was, that by calling userPresenter.setList(users) in ApiService, that would set mUserList to the response from the api request. However, instead, mUserList == null at the time that getUserList responds.
Any ideas of how I can structure this?
I have also started to learn something similar. Here, I would rather use callbacks.
In your presenter,
public void setList(List<User> users) {
yourView.setUserList(users);
}
And your activity which implements a view (MVP)
#Override
public void setUserList(List<User> users) {
((UserAdapter)mGridView.getAdapter()).refill(mFriends);
}
Also, check that retrofit is not returning null list.
I have a made a small app when I was learning about all this. It fetches user data from GitHub and shows in a list. I was also working with ORMLite and Picasso so some db stuff is there. Dagger Dependency is also used (but you can ignore that). Here's the link.
Here's how my Presenter behaves:
private DataRetrieverImpl dataRetriever;
#Override
public void getUserList(String name) {
dataRetriever.getUserList(name);
}
#Override
public void onEvent(DataRetrieverEvent event) {
UserList userList = (UserList)event.getData();
mainView.setItems(userList);
}
DataRetrieverImpl works as a module (sort of).
private DataRetriever dataRetriever;
restAdapter = new RestAdapter.Builder().setEndpoint(SERVER_END_POINT).build();
dataRetriever = restAdapter.create(DataRetriever.class);
public void getUserList(final String name) {
Log.i(TAG, "getting user list for: " + name);
Observable<UserList> observable = dataRetriever.getUserList(name);
Log.i(TAG, "subscribe to get userlist");
observable.subscribe(new Action1<UserList>() {
#Override
public void call(UserList userList) {
eventBus.post(new DataRetrieverEvent("UserList", userList));
// save to database
for (User user : userList.getItems()) {
Log.i(TAG, user.getLogin());
try {
dbHelper.create(user);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
throwable.printStackTrace();
}
});
}
And DataRetriever is interface for retrofit. I'm sorry for the naming confusion.
public interface DataRetriever {
#GET("/search/users")
public Observable<UserList> getUserList(#Query("q") String name);
}
Any my Activity,
#Override
public void setItems(final UserList userList) {
runOnUiThread(new Runnable() {
#Override
public void run() {
UserAdapter userAdapter = (UserAdapter)recyclerView.getAdapter();
userAdapter.setUserList(userList);
userAdapter.notifyItemRangeInserted(0, userAdapter.getItemCount());
}
});
}

Parse Android SDK, saveAll subclass objects?

I'm using the Parse SDK on Android. There doesn't seem to be any documentation on using the ParseObject.saveAll(List<ParseObject>) method. I have a subclass called Test which extends ParseObject. I've been able to use most ParseObject methods so far, but I would like to save the whole list using the saveAll method, but it requires a List<ParseObject> and won't accept List<Test>. Any ideas?
Your ParseObject model may like this
class Person extends ParseObject
{
public static String NAME = “name”;
public static int AGE = “age”;
public void setName(String name)
{
put(NAME,name);
}
public void setAge(int age)
{
put(AGE,age);
}
public Stirng getName()
{
return get(NAME);
}
public int getAge()
{
return get(AGE);
}
}
now,Person is subclass of ParseObject. You can use ParseObject.saveAll(List personList)
Person person1 = new Person();
person1.setName("Mike");
person1.setAge(18);
Person person2 = new Person();
person2.setName("John");
person2.setAge(25);
List<Person> personList = new ArrayList<Person>();
personList.add(person1);
personList.add(person2);
ParseObject.saveAll(personList);
Found a solution here: https://parse.com/questions/how-to-use-parseobjectsaveall-on-subclass
Let's say you have your 3 Game object, game1, game2, game3, this should work:
List mygames = new ArrayList();
mygames.addAll(Arrays.asList(game1, game2, game3));
ParseObject.saveAllInBackground(mygames);
An alternative solution could be to write a custom save all method inside the subclass:
public static void saveAllInBackground(
final List<MySubclass> objects,
final SaveCallback savecallback) {
counter = 0;
for (MySubclass mySubclass : objects) {
mySubclass.saveEventually(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
counter++;
if (counter == objects.size()) {
savecallback.done(null);
}
} else {
savecallback.done(e);
}
}
});
}
}

Categories

Resources