Android Room - Select All then write to text file - android

I followed the Android Room with a View tutorial and I was successfully able to recreate the tutorial app. All of my code can be found in that tutorial. The only difference with my app now is my MainActivity is a webView and then when the user clicks on a button in the toolbar, they're taken to the Room with a View app functionality exactly how it is in the tutorial. So essentially I just added another activity beforehand.
I've tried using the methods getAllWords() and getAlphabetizedWords() associated with LiveData and dumped the results into the Logcat, but they always come out in a hash-like string (Ex: Word#6f2f356). I'm trying to get the exact value of the word I'm pulling from the Room database.
I have 2 issues currently:
I'd like to select all of the words in the Room database table from the MainActivity.
After selecting all terms from the table, I'd like to write them all to a text file or CSV.
In my MainActivity I'm using the function below to send the user to the start of the Room with a View tutorial functionality (WordList). My WordList class is the equivalent to the tutorial's MainActivity. Within this WordList class, I've tried using getAllWords() and it returns the terms in a hash-like state.
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.nix_menu_back:
onBackPressed();
break;
case R.id.nix_menu_forward:
onForwardPressed();
break;
case R.id.nix_menu_refresh:
nixWebView.reload();
break;
case R.id.nix_string_list:
nixWebView.reload();
Intent intent = new Intent(this, WordList.class);
startActivity(intent);
break;
}
return super.onOptionsItemSelected(item);
}
Can someone please explain to me how to select all terms in the Room database and output them in a readable format to Logcat and an internal text file?
Any help is appreciated, and my sincerest apologies if this is a repeat! I've checked around SO and the only question I found related to my situation didn't cover this situation.
I'm happy to provide more code if asked. Thank you everyone!

Hashy looking strings
If you want your Word object to be printed in a readable object you should override the method public String toString() for that class since the default implementation returns that hashy looking String.
Some light on this could be:
public class Word {
// Other stuff you may have
#Override
public String toString() {
return this.wordID+" - "this.wordContent;
}
}
And this could print: "12 - Cat"
To list all words.
The methods provided in that codelab are enough to list all the words contained in the SQLite DB.
To save them in an external file as plain text.
Check this other stack overflow question
Don't forget to add
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
In your AndroidManifest.xml file!

Related

Fill ListView With Items From Previous Activity

I'm new to Android programming, and still teaching myself to code.
Currently I'm teaching myself about GridViews and still coding that project with tutorials so I have nothing to show right now, but the basic idea is the following...
If I have images of groceries in GridView in the first activity and when you click an image you will be able to open a new activity with a larger image and you could input the number how many you things you need, like 5 apples or whatever.
All of that is more or less clear to me how to do.
But how would I send the number and image to a new (third) activity with a ListView that would list all the items you need to buy at the grocery store? How would I be able to fill the list only with items after you enter the number on the previous activity with the large picture and click an "OK" or "Add" button or whatever and not list absolutely everything?
Thanks!
It's difficult at first, but you can use an SQLiteDatabase to store the data.
It's not a quick solution for you, but definitely worth learning about if you're serious to learn android. Here's a link to the official stuff:
https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
I personally used this tutorial:
http://www.androidwarriors.com/2016/02/android-sqlite-database-tutorial-sqlite.html?m=1
Sharing some data between multiple activities or fragments is a very common situation. One way around it is implementing a Singleton Pattern.
In your case you can design some kind of data structure for your purpose and manage it inside shared singleton class. For example something like this:
public class ShoppingListManager {
private static ShoppingListManager instance = new ShoppingListManager();
private List<ShoppingItem> shoppingList;
public static ShoppingListManager getInstance() {
return instance;
}
public List<ShoppingItem> getShoppingList() {
return shoppingList;
}
public void addShoppingItem(ShoppingItem item) {
this.shoppingList.add(item);
}
...
// Make the constructor private so that this class cannot be instantiated
private ShoppingListManager(){
shoppingList = new ArrayList<String>();
}
}
Then you can access your data anywhere in your code and manage shared data in any way you'd like.
ShoppingListManager.getInstance().getShoppingList();
// You can add items in any activity
ShoppingListManager.getInstance().addShoppingItem(item);
One point to remember never store context in singleton classes as it will lead to memory leaks.

Android : Get String / Input from other Activity

I have an audio recorder (activity_audio_record_test.xml // AudioRecordTest.java) which opens via an onClick from another activity(addemployee.xml // AddEmployee.java)
On the addemployee I have a text input which is being used to capture the project refrence number.
<EditText
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/txtName"
android:inputType="number"
android:maxLength="5"
android:digits="0123456789"
android:singleLine="true"
/>
which in the Java relates to
txtName=(EditText)findViewById(R.id.txtName);
and
public void btnAddEmp_Click(View view)
{
boolean ok=true;
try
{
Spannable spn=txtAge.getText();
String name=txtName.getText().toString();
int age=Integer.valueOf(spn.toString());
int deptID=Integer.valueOf((int)spinDept.getSelectedItemId());
Employee emp=new Employee(name,age,deptID);
dbHelper.AddEmployee(emp);
}
catch(Exception ex)
{
ok=false;
CatchError(ex.toString());
}
finally
{
if(ok)
{
//NotifyEmpAdded();
Alerts.ShowEmpAddedAlert(this);
txtEmps.setText("Number of Inspections on Device "+String.valueOf(dbHelper.getEmployeeCount()));
}
}
}
by the way, I know that the project refrence is called name, i'll get around to changing that later.
Anyhow, I am writing these audio recordings to a DB and a BYTE BLOB (or at least I plan to and the same with the photos too https://stackoverflow.com/posts/comments/25412248?noredirect=1). I need to use this project ref/txtName/Name field as the unique ID for this? is it possible to "parse"? this over the the second activity?
Thanks in advance,
Henry
More specific details
Page one (activity AddEmployee.Java // addemplyee.xml) is used to type details, multiple text field etc... Page two (activity activity_audio_record_test.xml // AudioRecordTest.java) is called by an onClick to open the second activity, record and save audio notes before returning to the main activity to finish entering the details. There is an input field (project ref/txtName/Name) on the main activity, which must be used as an identifier for the audio notes, to tie them in with the project. How can I get the user inputed ID from, the main activity over to the second activity...so that I am able to use it as a value for an input into the DB?
Hope this helps...
I am not sure if this counts as an answer as such, so I am not going to accept it, however it is a solution.
I am moving all the intents into one activity. Therefore, there is no need to pass the data through to my second activity. Instead, I can just pull the same txtName field to write my data table, image table and audio notes table in one hit.
Simple outside(but not so outside) of the box solution to the problem at hand... Window, white board pen and a flow chart diagram of data transfer helped me here...

Application with different requests sent to a database (SQL) depending on buttons clicked

I still am a beginner in Android development and will try to make my question as clear as possible with a schema of what I have in my mind.
Purpose of this application:
- I want the user to have the choice between a few buttons and when clicking on any of them, it would open a list view with different content according to the button.
ex : if you click on "Category_1" button, only elements with a fitting id will appear in the listview.
So far, I have :
- defined my "handler" class (extends SQLiteOpenHelper) : name/path of DB, definition of CRUD, .getReadableDatabase, etc.
- define a class for my table, in my case "Restaurants.java" with getters/setters and constructor.
- defined my MainActivity with empty listeners for my button.
- defined my "DatabaseAdapter.java" in which I want to define the methods/sql requests which will communicate with the database and get the information I want from it.
- defined my ListViewActivity with nothing to display so far.
Here is a schema of what I want with the idea of how to make it to try to optimize my application :
To sum up:
- I want a listener for each button setting a variable to a certain value (for example: "if you click on 1 then set the value of A to 1") and opening the ListViewActivity.
- There would be a method defined in "...Adapter.java" sending a request to the database and having the variable A defined earlier as an input.
- And then, when clicking on the button, the ListViewActivity will open and call the method from "..Adapter.java", and finally display the results.
So, here are my questions :
- First of all, is the design optimized enough to allow my application to run fast? I think it should as all the button open only one activity and there is only one method defined for all buttons.
- I have a hard time defining the method in "...Adapter.java" which will be called from my ListViewAcitivity. The input should be the variable obtained when clicking on the button but I don't really know how to get a variable in one activity, open a second activity where to display results by using the variable in a third activity... :s
Is it fine to set a variable to a certain value when we click on a button and use this variable in another class as an input for a method?
public findNameInTable(int A){
string sql = " select NAME from MY_TABLE where CAT1 = " + A;
c = database.rawQuery(sql, null); }
Thanks in advance for any indications, suggestions or links which could help me to make my application come true, and sorry if some questions really sounds newbie, I am starting !
Have a good day !
Part 1: The best way I have found to pass variables to other activities is with a putExtra(String, variable);. Say you change the variable name on a button press, you can then call:
YourNewActivityClassName var = new YourNewActivityClassName();
Intent i = new Intent(context, YourNewActivityClassName.class);
i.putExtra("name", name);
startActivity(i);
Then in the activity you just created, you can call this in the onCreate method:
Intent i = getIntent();
final String name = i.getStringExtra("name");
Of course this is assuming the variable was defined as a String before the putExtra was called.
If you want to use other variable types, there are different get***Extra commands you can call like getIntExtra(int, defaultval) but the putExtra will still be used to send it.
Part 2: For calling a method with a variable assigned in a button click, I have found the best way to do this is with a "holder class" this holder can be defined as a final, and a button press assigns a value to one of it's slots. Here is my holder for Integers:
public class holder {
int to;
public void setTo(int to){
this.to = to;
}
public int getTo(){
return to;
}
}
I instantiate my class as final within my on create final holder hold = new holder();
then call my hold.setTo(int); within a list click listener. When I want to get the data, I simply call hold.getTo(); and I have my integer.
Heres a similar post: Pass value outside of public void onClick
Hope this helps!
Mike

Pulling data from one Tab Activity to another

Everything I've read about Intents talks about using them to push data, or to start one Activity from another Activity. I want to pull data from an Activity that's already running.
The Tab Layout tutorial at http://developer.android.com/resources/tutorials/views/hello-tabwidget.html illustrates what I want to do. (My app is doing some engineering calculations instead, but the tutorial code provides a good analogy to my app.) The tutorial creates an app with three tabs, and each tab hosts a separate activity.
To expand on the example in the tutorial, suppose I select an artist in the Artists tab/activity. I want to be able to select the Albums tab/activity and have it display all the albums featuring that artist.
It seems to me that I need to use an Intent to do this. All of the tutorials I've found assume that I would create a "See albums" Button in the Artists tab/activity, and that pressing the Button would execute an Intent that starts the Albums activity and passes artistName.
I DO NOT want to create that Button. Real estate on the Artists layout is precious, and I have a perfectly good Albums tab, AND the HelloTabWidget activity already contains an intent to create the Albums tab.
Besides, a user will want to skip back and forth between Album and Artist in order to change artist selections, and the tabs are a perfectly good way to do this. There's no need to complicate the UI with another button.
So how can I have the Albums activity PULL artistName from the Artists activity when the Albums tab is selected (or the Albums layout is displayed), rather than have the Artists activity START Albums and PUSH the artistName?
Equivalents I can think of from other programming worlds:
Global variables. Discouraged in Android devt, right? And if they do exist, what are they called?
A getter, like artistName = Artists.getArtistName(); . I get the feeling that it's not that easy.
Writing to, and reading from, a file - that is, mass storage or non-volatile memory. I don't need the artistName value to be permanent. It will be reset to null every time the user launches the application.
So how is it done in the Android world? Do I use an Intent - and if so, how?
Global variables were the right answer.
I thought Java discouraged their use, but a couple of links that appeared in the "Related" links on the right margin of this window mentioned them directly. One was "Android: How to declare global variables?" and the other was "how to pass value betweeen two tab in android". Both pointed to the Application Class as the place to define global variables and methods. Armed with this new knowledge, I found an article called "Android Application Class" on the Xoriant blog that expanded on the StackOverflow answers.
It's best to review those three links first. I need to add some tips to what those authors have said.
Your Application class has to be in its own separate file. (That might be a "duh" to some people, but not to everybody.) Here's a good framework for an example called Something.java:
public class Something extends Application {
// Put application wide (global) variables here
// Constants are final, so they don't have to be private
// But other variables should be declared private;
// use getters/setters to access them
public final boolean FEET = false;
public final boolean METERS = true;
private boolean units = FEET;
#Override
public void onCreate() {
super.onCreate();
// Put any application wide (global) initialization here
}
// Put application wide (global) methods here
public boolean getUnits() {
return units;
}
public void setUnits(boolean whichOne) {
units = whichOne;
}
}
I'm using Eclipse with the ADT plug-in, in Windows XP. Eclipse doesn't always behave properly if you edit XML code directly, so it's best to open AndroidManifest.xml, then select the Application tab and enter your application name in the Name field. You don't need to put a dot or period in front of the name. Just type in the name of your class, like "Globals" or "MyApplication" or whatever. (Note that this is the default application in your Manifest. You don't have to create a separate <application></application> tag.
This step may not be necessary on an actual Android device, but it was necessary for the emulator: you need to use the getApplicationContext() command in every onCreate() and every method that will be accessing the global variables and methods. I tried to put it outside of onCreate() with the rest of my activity wide variables, and it didn't work. Putting it inside every method seems wasteful, but both the emulator and the Android device work fine with it that way. Here's a sample showing how I used it:
public void fooBar() {
// Access to global variables and methods
final Something s = (Something)getApplicationContext();
// ...
// This next line demonstrates both a global method and a global variable
if (s.getUnits() == s.FEET) {
// do something with feet
} else {
// do something with meters instead
}
// ...
}
Those were the only hiccups I encountered. The three references that I have listed, taken together, are otherwise pretty complete.

Manipulating with array adapter or with the underlaying data?

In the book The Busy Coders Guide to Android Development from CommonsWare, there is a chapter explaining how to work with the context menus.
In one example in that chapter, the context menu offers option for removing item from a list view that is generated from an ArrayList<String> object named words.
In the example the onContextItemSelected method is implemented like this:
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
ArrayAdapter<String> adapter=(ArrayAdapter<String>)getListAdapter();
switch (item.getItemId()) {
case R.id.remove:
adapter.remove(words.get(info.position));
return true;
default:
...
}
The line where adapter.remove(...) is called seems strange to me because of following fact:
Let's say the words object contains following items (in that order)
alfa
beta
gama
alfa
Now, when user loads the context menu upon the 2nd alfa and selects the option for removing it, the mentioned line actually removes the 1st alfa. And that seems wrong to me.
Instead, I would do something like this:
...
words.remove(info.position);
adapter.notifyDataSetChanged();
...
I'm not that good in Java and Android programming, so I would like to hear your opinion to this, because I want to be sure I understand well how adapters should be used.
Your idea sounds good.
The example is defunct if it behaves like you have described and you should tell Mark about it so he can check it as well (he'll probably do it anyway since he is very active on this site).

Categories

Resources