Second post here, the first one was extremely helpful so thank you for those that contributed. I will try to be concise with the issue I'm having. I am using android studio in intellij to develop an application. Part of the functionality of the app is a fragment that accepts a new username input from the end user, and then stores that username into my database (a preexisting database that has been linked to intellij). I am new to java and only in the last couple days started to change from creating UI with swing and awt, to xml files. My understanding is that xml files are data descriptors and useful for creating static objects/widgets while the .java files use java to create behaviors for the objects by referencing their IDs created in the xml file. Now comes the confusing part for me, and forgive me if this seems like a no brainer, as I'm pretty new to all this- I have "piggybacked" off a base shell for a android app, and as best as I can tell, setOnClickListener is essentially the android java version of action listeners. I added to the method that essentially took a button and navigated from one fragment to the next, with code that connects to the database, and then executes the stored procedure presumably when the "next"/"submit" button is clicked. Now here's the catch: obviously when a submit button is clicked, there is no user defined username that gets passed into the stored procedure, so obviously it won't work. The problem is, the TextEdit text field that I created is created in an xml file with no way to reference it or manipulate it in the java code, yet it accepts "text" parameters and works fine in the emulator. Obviously I want the stored procedure to take the user inputs in that text field and store it as a new username in the database, but since xml just describes data, and there isn't any defined text field in the java code, I'm at a loss for how to accomplish this task. I can't just write up an action listener and attach it to the xml id of the TextEdit because there isn't anything in the xml file that explains where the actual typed characters are! I know, higher level programming issues. Can anyone help explain how to do what I'm trying to do? Preferably as much as possible in laymans terms. Here is the code:
package com.example.callit;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.sql.*;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
public class FirstFragment extends Fragment {
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_first, container, false);
}
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.button_first).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NavHostFragment.findNavController(FirstFragment.this)
.navigate(R.id.action_FirstFragment_to_SecondFragment);
String sqldatabase = "//database connection url";
try {
Connection con = DriverManager.getConnection(sqldatabase);
CallableStatement cs = con.prepareCall("{EXEC [dbo].[CreateUser] #UserName = N'Dog', #UserID = #UserID OUTPUT}");
cs.execute();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
});
}
}
I included it in case there was something inherently wrong with the connection to the database code (I also am aware that I should disconnect from the database as well). I would like to note that the code runs without errors, it just doesn't do what it should (for the reasons I explained above). Any help would be greatly appreciated!
Related
In Android Studio, developing in Java, I have the following (a somewhat minimized version of what I'm trying to do).
package com.example.japanesequiz;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
String[] hiragana = {"あ", "か"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button generate = findViewById(R.id.generate);
TextView questionText = findViewById(R.id.question_text);
RadioGroup radioGroup = new RadioGroup(this);
MainActivity ma_inst = this;
generate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Random rand = new Random();
int hir_index = rand.nextInt(2);
questionText.setText(hiragana[hir_index]);
RadioButton rb1 = new RadioButton(ma_inst);
rb1.setId(View.generateViewId());
rb1.setText("Ah");
radioGroup.addView(rb1);
RadioButton rb2 = new RadioButton(ma_inst);
rb2.setId(View.generateViewId());
rb2.setText("Ka");
radioGroup.addView(rb2);
}
});
}
}
The basic idea is that I want to have the main screen initially mostly blank, but with a button at the bottom. When tapped, it eventually show some text and a radio button group. (I haven't yet fully built out the rest, of course.)
But at this stage what I expect when I launch the app is to see the mostly blank screen, and maybe if I tap the button it will generate some text and options (that then do nothing, further implementation to come).
But the app never launches. Instead, Graddle finishes building, I get a terminal saying that it's launching the app, but it hangs and times out.
If I had to guess -- and this is a guess because I'm very new to Android development -- there is some issue with grabbing the this instance and then using it in the OnClickListener. I'm not certain what the issue is, but it's the only thing I see here that looks fishy. Also, I'm not sure how else one is supposed to add objects to the current activity from inside of the anonymous class passed into the OnClickListener since, there, a reference to this then refers to the anonymous inner class.
I know that it is possible to use a lambda instead, and that probably resolves the issue, but I want to really understand what's going on here, since it seems like it might be conceptually important for later development.
My question: If I have correctly understood this much, then how does a lambda get around this issue? If I've not correctly understood then I'd appreciate any insight, thanks!
There are many questions in one question. First, let me try to answer your title question: "How to get context inside a mouse click listener":
There are many ways, but you can consider this one (your click lisener's onClick has the signature void onClick(View view), hence you have access to view.
view.getContext()
Next, nothing wrong with these though you better migrate to view binding https://developer.android.com/topic/libraries/view-binding as butterknife is deprecated officially
Button generate = findViewById(R.id.generate);
TextView questionText = findViewById(R.id.question_text);
Next, you don't really need this trick in order to get activity in your lambda:
MainActivity ma_inst = this;
Instead and if really needed, you can always do Context context = MainActivity.this;
Lastly, I think the issue the app never launches roots into something else not related with title question you posted, unfortunately.
I am trying to make a spinner I have selectively translate strings on a page. I have my app set up to translate the bulk of the page based on locale languages already. In the image below, The locale language will effect the top string, but I have a spinner on my home page that has all the available android languages in it, and I want users to be able to select one of the spinner items, and as a result the bottom string in the picture below will be translated to that language. I can't find a way to set it up, all the advice I've seen so far is just how to configure the application to set up locale language's. Any direction would be greatly appreciated!
I think you can use Android-LocalizationActivity
Here a portion of its readme:
It's basic for android application to be supported multiple languages. Yeah! It's very easy because android has String Resource. Developer just had to prepare the text for different languages then android system will use itself. But frequently problem is "On-time Language Changing". Because the String Resource was designed to be depending on current device language. but if we want to change the language by click some button. It will be difficult to handle it. This problem will solved because I have created a new library to handle application language. It called "Localization Activity" library.
It's so simple to implement it. Just extend your Activity with LocalizationActivity. Here a sample code with Button:
import android.os.Bundle;
import android.view.View;
import com.akexorcist.localizationactivity.LocalizationActivity;
public class MainActivity extends LocalizationActivity implements View.OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple);
findViewById(R.id.btn_th).setOnClickListener(this);
findViewById(R.id.btn_en).setOnClickListener(this);
}
#Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.btn_en) {
setLanguage("en");
} else if (id == R.id.btn_th) {
setLanguage("th");
}
}
}
When user click btn_th (Thailand), all language will be translated to Thai language. So you only need to adjust it with spinner.
I'm trying to learn to create an Android fragment to implement an amount insert box which I can reuse throughout my application. So I create a simple xml file which has some EditText boxes. I then created the associated java file called AmountFragment.java:
public class AmountFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.amount_fragment, container, false);
return view;
}
}
I then use this fragment in another xml file:
<fragment
android:name="com.example.android.ui.widget.AmountFragment"
android:id="#+id/transaction_amount"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
This works fine so far. It shows the fragment fine and I can insert numbers in it. I now want to be able to get the inserted text in the mainActivity. So I read this page on Fragments from the Android docs, but I'm totally lost. The code they show makes no sense at all to me. I need to define an interface, but I have no clue what I have to do with it. I tried simply copy-pasting it over, but I get an InflateException. Since I don't even know what's going on I have no clue where to look for a solution.
So my question: can anybody give me some pointers on how to interface this fragment with the Activity in which I use it?
Try the following code.
In MainActivity.java add
public void getMessage(Object obj) {
Log.d("My App", "Look at my object " + obj.toString();
}
That will get objects from your AmountFragment, then in your AmountFragment write:
String anyObject = "Yay something";
((MainActivity)getActivity()).getMessage(anyObject);
What's happening here is that getActivity() will get the instance of the Activity which contains the fragment, then you cast it to your activity, MainActivity, and call the receiver method you wrote for it.
first off I was wondering if there are even HTML parsers that work with Android app programming or not, or if all I have access to is the html commands listed on the Android developers web site. The reason is I am making an app that allows you to access the Zelda Wikia and instead of hard coding everything such as the titles of the video games I wanted to go ahead and pull the names using the MediaWiki API, the command I found was this:
http://zelda.wikia.com/api.php?action=query&list=categorymembers&cmtitle=Category:Games&cmlimit=500
This returns all of the titles in HTML formatting and the only way that I can think to pull what I need from what this returns is using an HTML parser, but I am not sure that there is one that works with Android programming and if so how I would even go about pulling what I need from this. After I get the data from this I want to display it in a ListView and when the title is clicked it will take the user to the Wikia for that specific title in a WebView. Is this the way I should be going about this or are there any other recommendations that anyone has, please I really need help. The rest of the code is as follows just incase anyone wants to see what I have:
package com.lvlup.kikurself.zeldatest;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
public class zeldaGames extends ListActivity {
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
String[] values = new String[] { "The Legend of Zelda", "Zelda II: The
Adventure of Link", "The Legend of Zelda: Ocarina of Time",};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
final ListView zeldaList = getListView();
zeldaList.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long thisID)
{
Object o = (zeldaList.getItemAtPosition(position));
String gameName_temp = (o.toString());
Intent newIntent = new Intent(v.getContext(), gameDisp.class);
newIntent.putExtra("tempG", gameName_temp);
startActivity(newIntent);
}
});
Thank you for taking the time to read this.
I wouldn't use a parser on the phone. Before you know, the owner of the page could come up with a new layout, ruining your app.
Instead, I would build a webservice (PHP with DomXML is an exelent choice) which parses the given site, and returns file in XML, JSON or other format. And then I would write an app to use the parser webservice as a datasource.
In this way, you will have a lot more computer power. You only have to maintain one instance of the parser, an you know it works on any device, that has downloaded your app.
Maybe sounds like a lot of work, but trust me on this - you'll be better of.
Personal and profesional experience
Append &format=xml to your URL to get machine-readable data. See MW help on API formats at https://www.mediawiki.org/wiki/API:Data_formats and general API help at https://www.mediawiki.org/wiki/API
What I did was create two .java files. One that can compile and run on a 1.5 phone (SDK3) and then one that works on 2.0(SDK5) So for this example i'll call the 1.5 file ExampleOld and the new one Example. I was wondering if i just made activity like this if it would work sort of like a "portal" and pick the activity to load depending on the SDK so there is no crash or compile errors. Are there any changes I should make to my code? Maybe anyone out there that's had to do this before. thanks!
package com.my.app;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
public class ExamplePortal extends Activity {
int sdk=new Integer(Build.VERSION.SDK).intValue();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (sdk<5) {
Intent v = new Intent(this, ExampleOld.class);
startActivity(v);
}
else {
Intent v = new Intent(this, Example.class);
startActivity(v);
}
}
}
What you're doing (correct me if I'm wrong) is trying to maintain backwards compatibility while making use of new APIs if the user is running a newer android version. The best way to do this is to follow the tutorial Google posted here. This avoids any verification issues and is really the best way to do stuff imho.
I would put this decision in a Factory Class to avoid having these if-else statements all over the codebase.