I'm trying to send an integer from one activity to another in Android studio. In my source class I have sent the data using putExtra() and in the recipient class, I am trying to receive it using getIntent(). However, I get the error 'Could not resolve method 'getIntent()' in the recipient class. Here is my code:
I'm a total newbie to Android studio as well as Java so if I'm missing something really obvious, please be considerate.
Source Activity:
public class AugmentedImageActivity extends AppCompatActivity {
private ArFragment arFragment;
private ImageView fitToScanView;
// Augmented image and its associated center pose anchor, keyed by the augmented image in
// the database.
private final Map<AugmentedImage, AugmentedImageNode> augmentedImageMap = new HashMap<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment);
fitToScanView = findViewById(R.id.image_view_fit_to_scan);
arFragment.getArSceneView().getScene().addOnUpdateListener(this::onUpdateFrame);
}
#Override
protected void onResume() {
super.onResume();
if (augmentedImageMap.isEmpty()) {
fitToScanView.setVisibility(View.VISIBLE);
}
}
/**
* Registered with the Sceneform Scene object, this method is called at the start of each frame.
*
* #param frameTime - time since last frame.
*/
private void onUpdateFrame(FrameTime frameTime) {
Frame frame = arFragment.getArSceneView().getArFrame();
// If there is no frame or ARCore is not tracking yet, just return.
if (frame == null || frame.getCamera().getTrackingState() != TrackingState.TRACKING) {
return;
}
Collection<AugmentedImage> updatedAugmentedImages =
frame.getUpdatedTrackables(AugmentedImage.class);
for (AugmentedImage augmentedImage : updatedAugmentedImages) {
switch (augmentedImage.getTrackingState()) {
case PAUSED:
// When an image is in PAUSED state, but the camera is not PAUSED, it has been detected,
// but not yet tracked.
int value=augmentedImage.getIndex();
Intent i = new Intent(AugmentedImageActivity.this, AugmentedImageNode.class);
i.putExtra("key",value);
startActivity(i);
String text = "Detected Image " + augmentedImage.getIndex();
SnackbarHelper.getInstance().showMessage(this, text);
break;
case TRACKING:
// Have to switch to UI Thread to update View.
fitToScanView.setVisibility(View.GONE);
// Create a new anchor for newly found images.
if (!augmentedImageMap.containsKey(augmentedImage)) {
AugmentedImageNode node = new AugmentedImageNode(this);
node.setImage(augmentedImage);
augmentedImageMap.put(augmentedImage, node);
arFragment.getArSceneView().getScene().addChild(node);
}
break;
case STOPPED:
augmentedImageMap.remove(augmentedImage);
break;
}
}
}
}
Recipient activity:
public class AugmentedImageNode extends AnchorNode {
private static final String TAG = "AugmentedImageNode";
// The augmented image represented by this node.
private AugmentedImage image;
private static CompletableFuture<ModelRenderable> ulCorner;
public AugmentedImageNode(Context context) {
Intent intent = getIntent();
Bundle extras = intent.getExtras();
int value = extras.getInt("key");
if (value == 0) {
// Upon construction, start loading the models for the corners of the frame.
if (ulCorner == null) {
ulCorner =
ModelRenderable.builder()
.setSource(context, Uri.parse("models/tinker.sfb"))
//.setSource(context, Uri.parse("models/borderfence-small2.sfb"))
.build();
}
}
}
#SuppressWarnings({"AndroidApiChecker", "FutureReturnValueIgnored"})
public void setImage(AugmentedImage image) {
this.image = image;
// If any of the models are not loaded, then recurse when all are loaded.
if (!ulCorner.isDone())// || !urCorner.isDone() || !llCorner.isDone() || !lrCorner.isDone())
{
CompletableFuture.allOf(ulCorner)//, urCorner, llCorner, lrCorner)
.thenAccept((Void aVoid) -> setImage(image))
.exceptionally(
throwable -> {
Log.e(TAG, "Exception loading", throwable);
return null;
});
}
// Set the anchor based on the center of the image.
setAnchor(image.createAnchor(image.getCenterPose()));
// Make the 4 corner nodes.
Vector3 localPosition = new Vector3();
Node cornerNode;
localPosition.set(-0.0f * image.getExtentX(), 0.1f, +0.5f * image.getExtentZ());
cornerNode = new Node();
cornerNode.setParent(this);
cornerNode.setLocalPosition(localPosition);
cornerNode.setLocalRotation(Quaternion.axisAngle(new Vector3(-1f, 0, 0), 90f));
cornerNode.setRenderable(ulCorner.getNow(null));
}
private void setLocalRotation() {
}
public AugmentedImage getImage() {
return image;
}
}
getIntent() method are only available in class which extends the activity[directly or indirectly]
Here is code how to use share preference in your scenario.I hope it will help you.
Instead of below code
Intent i = new Intent(AugmentedImageActivity.this, AugmentedImageNode.class);
i.putExtra("key",value);
startActivity(i);
Use this one
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
Editor editor = pref.edit();
editor.putInt("Key", "int value");
editor.commit();
And retrieve preference value on your AugmentedImageNode screen using below code
SharedPreferences settings = getSharedPreferences("MyPref", MODE_PRIVATE);
int snowDensity = settings.getInt("Key", 0); //0 is the default value
remove the first three lines of your AugmentedImageNode(Context context) in recipient activity and replace it with following
int value = getIntent().getIntExtra("key",0);
where 0 is just default value.
getintent is working if you are extent Activity and AppCompatActivity
for example:
MainActivity.java
choice_a.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent=new Intent(MainActivity.this,SecondActivity.class);
//putExtra(key name,default value);
intent.putExtra("int_key",22);
startActivity(intent);
}
});
SecondActivity.java
public class SecondActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
//get intent values
Intent intent = getIntent();
Bundle extras = intent.getExtras();
int value = extras.getInt("int_key");
Log.e("Int_Value", "" + value);
// another way
int i = getIntent().getIntExtra("int_key", 0);
Log.e("Int_Value", "" + i);
}
}
In your code you have extend AnchorNode
Related
Short:
I have Three classes: A (MainActivity), B (Secondary), C(Third).
A is parent of B is parent of C.
In A I make an Intend with Extra int idForUsage on B. B stores idForUsage in a variable int chosenId(works fine).
B does Stuff and makes an Intent with Extra int chosenId and int secondIdForUsage(works also fine).
C does Stuff and it works all fine.
When I´m now clicking the litte "back button" in the upper left corner to get to the parent activity the app crashes because I´m trying to access the Variable chosenId which seems to being set to default -1 (even if I´m trying to read the Extra again.)
public class MainActivity extends AppCompatActivity {
//references to Buttons etc
...
public static final String ChosenID = "com.example.Abzeichenschwimmer.ChosenSwimmerID";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//set up button stuff
...
//ListView which has clickable Items which trigger the Activity
lv_swimmerList = findViewById(R.id.lv_schwimmerListe);
//Listeners
lv_swimmerList.setOnItemClickListener(this::onListViewItemClick);
}
#Override
protected void onResume(){
super.onResume();
updateSchwimmerliste(dataBaseHelper);
}
public void onListViewItemClick(AdapterView<?> parent, View view, int position, long id) {
SchwimmerModel clickedSchwimmer = (SchwimmerModel) parent.getItemAtPosition(position);
Intent intent = new Intent(MainActivity.this, DisplaySchwimmer.class);
//Toast.makeText(MainActivity.this, String.valueOf(clickedSchwimmer.getId()), Toast.LENGTH_SHORT).show();
intent.putExtra(ChosenSwimmerID, clickedSchwimmer.getId());
startActivity(intent);
}
}
public class DisplaySchwimmer extends AppCompatActivity {
int chosenSwimmerID;
public static final String SchwimmerID = "com.example.Abzeichenschwimmer.schwimmerID";
public static final String AufgabenID = "com.example.Abzeichenschwimmer.aufgabenID";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_schwimmer);
lv_exc = findViewById(R.id.lv_aufgaben);
refreshValues();
showAufgabenOnListView(dataBaseHelper);
lv_exc.setOnItemClickListener(this::onListViewItemClick);
}
public void getIntentExtra(){
Intent intent = getIntent();
chosenSwimmerID = intent.getIntExtra(MainActivity.ChosenSwimmerID,-1);
}
public void onDeleteClick(View view){
SchwimmerModel toDeleteSwimmer = (SchwimmerModel) dataBaseHelper.getSchwimmerByID(chosenSwimmerID);
dataBaseHelper.deleteSchwimmer(toDeleteSwimmer);
Toast.makeText(this, "deleted", Toast.LENGTH_SHORT).show();
DisplaySchwimmer.this.finish();
}
public void refreshValues(){
getIntentExtra();
SchwimmerModel schwimmer = dataBaseHelper.getSchwimmerByID(chosenSwimmerID); <--- Main Error
}
private void showAufgabenOnListView(DataBaseHelper dataBaseHelper) {
getIntentExtra();
ArrayAdapter<ExcerciseModel> schwimmerArrayAdapter = new ArrayAdapter<ExcerciseModel>(DisplaySchwimmer.this, android.R.layout.simple_list_item_1, dataBaseHelper.getExcersisesForSwimmerByID(chosenSwimmerID));
lv_exc.setAdapter(schwimmerArrayAdapter);
}
public void onListViewItemClick(AdapterView<?> parent, View view, int position, long id) {
ExcerciseModel clickedExcerciseModel = (ExcerciseModel) parent.getItemAtPosition(position);
Intent intent2 = new Intent(DisplaySchwimmer.this, DisplayAufgabe.class);
intent2.putExtra(SchwimmerID, chosenSwimmerID);
intent2.putExtra(AufgabenID, clickedExcerciseModel.getId());
Log.e("aaa", String.valueOf(chosenSwimmerID));
startActivity(intent2); <-- Intentstart
}
#Override
protected void onResume(){
super.onResume();
showAufgabenOnListView(dataBaseHelper);
}
}
I hope the code (deleted many lines) is ok for an overview. Maybe someone knows the solution for this.
Thanks Maximus
When you press back from DisplayAufgabe to DisplaySchwimmer (the intent always is null)
Because you call getIntent di DisplaySchwimmer, you will get default value which is -1 (null intent extra)
When you try to call dataBaseHelper.getSchwimmerByID(chosenSwimmerID); is mean you try to get index -1 on database. You will always get error because accessing index -1.
My Suggestion
Add validation before call dbHelper i.e
if (chosenSwimmerID > -1){
SchwimmerModel schwimmer = dataBaseHelper.getSchwimmerByID(chosenSwimmerID);
}
Only getExtra when value available
if (intent.hasExtra(MainActivity.ChosenSwimmerID)){
chosenSwimmerID = intent.getIntExtra(MainActivity.ChosenSwimmerID,-1);
}
It all boiled down on using sharedPreferences. This helped a lot. A Second post from me explanined this problem more simplified and I found a solution.
This question already has answers here:
How do I pass data between Activities in Android application?
(53 answers)
Closed 6 years ago.
In the program below used for an android app in android studios, When getPercent() from the second class(Main2Activity) is invoked, it always returns 999(the default value), and the,
ttper = .....;
statement from the main class in the onClick() is never executed. Is there any specific reason for this? Can you guys point it out please!
This is the main activity,
public class MainActivity extends AppCompatActivity {
float i1m,i2m,mm,atp,assp;
float ttper=999;
boolean b=false;
EditText i1,i2,model,assignment,attendence;
Button b1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Context cont = this;
final Intent intent = new Intent(cont, Main2Activity.class);
b1=(Button)findViewById(R.id.button2);
b1.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
//try {
i1=(EditText)findViewById(R.id.int1);
i2=(EditText)findViewById(R.id.int2);
model=(EditText)findViewById(R.id.mod);
assignment=(EditText)findViewById(R.id.assign);
attendence=(EditText)findViewById(R.id.attend);
i1m = Float.parseFloat(String.valueOf(i1.getText()));
i2m = Float.parseFloat(i2.getText().toString());
mm = Float.parseFloat(model.getText().toString());
assp = Float.parseFloat(assignment.getText().toString());
atp = Float.parseFloat(attendence.getText().toString());
ttper = ((i1m / 10) + (i2m / 10) + ((mm / 100) * 15) + (assp) + ((atp >= 75.0f) ? ((atp - 75) / 5) : 0.0f));
//setValues();
startActivity(intent);
//}
//catch (Exception e) {
// Log.e("app crash",e.getMessage());
//}
}
});
}
/*void setValues()
{
/* i1m = Float.parseFloat(String.valueOf(i1.getText()));
i2m = Float.parseFloat(i2.getText().toString());
mm = Float.parseFloat(model.getText().toString());
assp = Float.parseFloat(assignment.getText().toString());
atp = Float.parseFloat(attendence.getText().toString());*/
}/*
float getPercent()
{
//float ttper=50.0f;
return ttper;
}
}
This is the second activity,
public class Main2Activity extends AppCompatActivity {
float tper=1.0f;
String str;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
TextView v1 = (TextView) findViewById(R.id.textView11);
MainActivity m1 = new MainActivity();
//m1.setValues();
//try {
str = String.valueOf(m1.getPercent()) + "%";
v1.setText(str);
//}
//catch (Exception e) {
// Log.e("app crash",e.getMessage());
//}
}
}
it can not work. If you create new MainActivity(), your ttper will be 999.
You should pass data between Activities in this way:
Put the new calculated ttper into Intent: intent.putExtra("ttper", ttper );
Then in MainActivity2 use getIntent().getFloatExtra("ttper", 999.0f);
You have an instance of MainActivity which has a variable ttper. You modify that value.
Then in another class Main2Activity you create a NEW instance of MainActivity and try to get that value, but ttper has the default value because this is a NEW instance and it hasn't been modified yet.
What you can do is defining ttper as static:
static float ttper=999;
You can even define your function getPercent() as static so you don't have to create a new instance of this class to get the value. You would just call MainActivity.getPercent().
For more information, read:
https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
Anyway, this is not the correct way of passing data from one activity to another. You should follow this guidelines: https://developer.android.com/training/basics/firstapp/starting-activity.html
You should use extras on intents to pass data between activies.
I'm writing a game to help teach my son some phonics: it's my first attempt at programming in Java, although I've previously used other languages. The game has four activities: a splash screen which initializes an array of variables before you dismiss it; another to choose a user; a third to choose which level of the game to play; and a fourth to actually play the game.
My problem was that if you go in and out of the game activity repeatedly, that activity would eventually crash -- logcat showed an OOM error. Watching the heap size as I did this, and looking at a heap dump with MAT, it looked as though I was leaking the whole of the fourth activity -- GC was just not being triggered.
I've tried lots of things to track down and fix the leak -- most of which are, I'm sure improvements (e.g. getting rid of all non-static inner classes from that activity) without fixing the problem. However, I've just tried running the same thing on an emulator (same target and API as my device) and there's no leak -- heap size goes up and down, GC is regularly triggered, it doesn't crash.
So I was going to post the code for the activity on here and ask for help spotting what might be causing the leak, but I'm no longer sure that's the right question. Instead I'm wondering why it works on the emulator, but not the phone... Does anyone have any ideas?
IDE: Android Studio 2.1
Target: Android 6, API 23 (Minimum SDK 8)
Emulator: Android Studio
Device: Sony Xperia Z2 (Now running 6.0.1, but I had the same issue pre recent update, i.e. on API 22)
Code for the activity:
public class GameActivity extends AppCompatActivity implements TextToSpeech.OnInitListener {
//TTS Object
private static TextToSpeech myTTS;
//TTS status check code
private int MY_DATA_CHECK_CODE = 0;
//LevelChooser request code
public static Context gameContext;
private int level;
public static String user;
private Typeface chinacat;
public static Activity gameActivity = null;
private static int[] goldstars = {R.drawable.goldstar1, R.drawable.goldstar2, R.drawable.goldstar3};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
gameActivity = this;
gameContext = this;
level = getIntent().getIntExtra("level", 1);
user = getIntent().getStringExtra("user");
chinacat = Typeface.createFromAsset(getAssets(), "fonts/chinrg__.ttf");
Intent checkTTSIntent = new Intent();
checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);
}
#Override
public void onStop() {
if (myTTS != null) {
myTTS.stop();
}
super.onStop();
}
#Override
public void onDestroy() {
if (myTTS != null) {
myTTS.shutdown();
}
Button ok_button = (Button) findViewById(R.id.button);
ok_button.setOnClickListener(null);
ImageView tickImageView = (ImageView) findViewById(R.id.tickImageView);
tickImageView.setOnClickListener(null);
super.onDestroy();
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_DATA_CHECK_CODE) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
myTTS = new TextToSpeech(this, this);
} else {
Intent installTTSIntent = new Intent();
installTTSIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installTTSIntent);
}
}
}
public void onInit(int initStatus) {
//if tts initialized, load layout and level and assign listeners for layout elements
if (initStatus == TextToSpeech.SUCCESS) {
myTTS.setLanguage(Locale.ENGLISH);
setContentView(R.layout.activity_main);
ImageView imageView = (ImageView) findViewById(R.id.myImageView);
PhonemeGroup levelGroup = MainActivity.gamelevel[level]; //set possible words
levelGroup.setSubset(); //randomize subset of possible words for actual test
PhonicsWord[] testSet = levelGroup.getSubset(); //fill array of test words
TextView[] targetView = new TextView[3]; //textviews for beginning, middle & end of word
targetView[0] = (TextView) findViewById(R.id.targetWord0);
targetView[1] = (TextView) findViewById(R.id.targetWord1);
targetView[2] = (TextView) findViewById(R.id.targetWord2);
TextView[] answersView = new TextView[3]; //textviews for possible user answer choices
answersView[0] = (TextView) findViewById(R.id.letter0);
answersView[1] = (TextView) findViewById(R.id.letter1);
answersView[2] = (TextView) findViewById(R.id.letter2);
//set first target word, image for word, and possible answers
testSet[0].setWord(levelGroup, targetView, answersView, imageView);
testSet[0].speakWord(myTTS);
//subset index is equal to array index for testSet, but visible to & settable by methods
levelGroup.setSubsetIndex(0);
for(int i=0; i<3; i++) {
answersView[i].setTypeface(chinacat);
}
TextView letter0 = (TextView) findViewById(R.id.letter0);
letter0.setOnClickListener(new LetterOnClickListener(testSet, levelGroup, targetView, answersView, 0) );
TextView letter1 = (TextView) findViewById(R.id.letter1);
letter1.setOnClickListener(new LetterOnClickListener(testSet, levelGroup, targetView, answersView, 1) );
TextView letter2 = (TextView) findViewById(R.id.letter2);
letter2.setOnClickListener(new LetterOnClickListener(testSet, levelGroup, targetView, answersView, 2) );
Button ok_button = (Button) findViewById(R.id.button);
ok_button.setOnClickListener(new OKButtonOnClickListener(testSet, levelGroup, targetView, level) );
ImageView tickImageView = (ImageView) findViewById(R.id.tickImageView);
tickImageView.setOnClickListener(new TickClick(myTTS, testSet, levelGroup, targetView, answersView, imageView) );
imageView.setOnClickListener(new WordImageClick(testSet, levelGroup) );
}
/*else if TODO*/
}
private static class WordImageClick implements View.OnClickListener {
//speaks the test word when the test image is clicked
PhonicsWord[] testSet;
PhonemeGroup levelGroup;
public WordImageClick(PhonicsWord[] testSet, PhonemeGroup levelGroup) {
this.testSet = testSet;
this.levelGroup = levelGroup;
}
#Override
public void onClick(View view) {
testSet[levelGroup.getSubsetIndex()].speakWord(myTTS);
}
}
private static class LetterOnClickListener implements View.OnClickListener {
PhonemeGroup levelGroup;
PhonicsWord currentWord;
PhonicsWord[] testSet;
TextView[] targetView;
TextView[] answersView;
int item;
int phonemeclicked;
public LetterOnClickListener(PhonicsWord[] testSet, PhonemeGroup levelGroup, TextView[] targetView, TextView[] answersView, int phonemeclicked) {
this.testSet = testSet;
this.levelGroup = levelGroup;
this.targetView = targetView;
this.answersView = answersView;
this.phonemeclicked = phonemeclicked;
}
#Override
public void onClick(View view) {
this.item = this.levelGroup.getSubsetIndex();
this.currentWord = this.testSet[item];
int i = currentWord.getOmit_index();
targetView[i].setText(answersView[phonemeclicked].getText());
}
}
private void crossClick(View view) {
view.setVisibility(View.INVISIBLE);
if(view.getTag()==4){
finish();
}
}
The static variable gameActivity is used so that when you've finished a level an external class can call GameActivity.gameActivity.finish() after it's displayed how many stars you've got for the level (it's also used to call GameActivity.gameActivity.findViewById in another external class).
public class ShowStarsWithDelay extends Handler {
public void handleMessage(Message msg) {
ImageView starView = (ImageView) ((LevelEndScreens) msg.obj).starView;
ImageView highscoreView = (ImageView) ((LevelEndScreens) msg.obj).highscoreView;
int num_currentstars = (int) ((LevelEndScreens) msg.obj).num_currentstars;
int num_finalstars = (int) ((LevelEndScreens) msg.obj).num_finalstars;
Boolean highscore = (Boolean) ((LevelEndScreens) msg.obj).highscore;
int[] goldstars = (int[])((LevelEndScreens) msg.obj).goldstars;
if(num_currentstars == num_finalstars) {
if(!highscore) {
starView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
GameActivity.gameActivity.finish();
}
});
}
else {
highscoreView.setImageResource(R.drawable.highscore);
highscoreView.setVisibility(View.VISIBLE);
highscoreView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
GameActivity.gameActivity.finish();
}
});
}
}
else {
starView.setImageResource(goldstars[num_currentstars++]);
Message message = new Message();
LevelEndScreens endScreens = new LevelEndScreens(starView, highscoreView, num_currentstars, num_finalstars, highscore, goldstars);
message.obj = endScreens;
this.sendMessageDelayed(message, 1000);
}
}
}
In general, you want to avoid having any static reference to a Context anywhere in your application (this includes Activity classes, of course). The only reference to a Context which MAY be acceptable is referencing the application context (as there is only one and it is always in memory while your app is alive anyway).
If you need a reference to the calling activity in one of your children, you'll need to pass the context as a parameter, or else use one of the child views methods to retrieve the context (such as getContext() for views and fragments).
More information that should help understand memory leaks and why this is important is here:
http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html
As an example, in your code for calling finish(), you could safely change it to this:
highscoreView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (v.getContext() instanceof Activity) {
((Activity)v.getContext()).finish();
}
}
});
To sum up, in order to fix your memory leaks, you'll need to remove the static keyword for all of your Context fields.
I have a problem, I want to click on the list, calling a new activity and rename the button to another name.
I tried several things, nothing worked, can someone please help me?
My class EditarTimes:
private AdapterView.OnItemClickListener selecionarTime = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView arg0, View arg1, int pos, long id) {
t = times.get(pos);
CadastroTimes cad = new CadastroTimes();
CadastroTimes.salvar.setText("Alterar");
Intent intent = new Intent(EditarTimes.this, CadastroTimes.class);
startActivity(intent);
}
};
public class CadastroTimes extends AppCompatActivity {
private Time t;
private timeDatabase db;
private EditText edID;
private EditText edNome;
public Button salvar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cadastro_times);
edID = (EditText) findViewById(R.id.edID);
edNome = (EditText) findViewById(R.id.edNome);
db = new timeDatabase(getApplicationContext());
salvar = (Button) findViewById(R.id.btnCadastrar);
salvar.setText("Cadastrar");
String newString;
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras == null) {
newString= null;
} else {
newString= extras.getString("Alterar");
}
} else {
newString= (String) savedInstanceState.getSerializable("Alterar");
}
//button in CadastroTimes activity to have that String as text
System.out.println(newString + " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
salvar.setText(newString);
}
public void salvarTime(View v) {
t = new Time();
t.setNome(edNome.getText().toString());
if (salvar.getText().equals("Alterar")) {
db.atualizar(t);
exibirMensagem("Time atualizado com sucesso!");
} else {
db.salvar(t);
exibirMensagem("Time cadastrado com sucesso!");
}
Intent intent = new Intent(this, EditarTimes.class);
startActivity(intent);
}
private void limparDados() {
edID.setText("");
edNome.setText("");
edNome.requestFocus();
}
private void exibirMensagem(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
}
public class EditarTimes extends AppCompatActivity {
private Time t;
private List<Time> times;
private timeDatabase db;
private ListView lvTimes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editar_times);
lvTimes = (ListView) findViewById(R.id.lvTimes);
lvTimes.setOnItemClickListener(selecionarTime);
lvTimes.setOnItemLongClickListener(excluirTime);
times = new ArrayList<Time>();
db = new timeDatabase(getApplicationContext());
atualizarLista();
}
private void excluirTime(final int idTime) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Excluir time?")
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage("Deseja excluir esse time?")
.setCancelable(false)
.setPositiveButton(getString(R.string.sim),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (db.deletar(idTime)) {
atualizarLista();
exibirMensagem(getString(R.string.msgExclusao));
} else {
exibirMensagem(getString(R.string.msgFalhaExclusao));
}
}
})
.setNegativeButton(getString(R.string.nao),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
builder.create();
builder.show();
atualizarLista();
}
private void atualizarLista() {
times = db.listAll();
if (times != null) {
if (times.size() > 0) {
TimeListAdapter tla = new TimeListAdapter(
getApplicationContext(), times);
lvTimes.setAdapter(tla);
}
}
}
private AdapterView.OnItemClickListener selecionarTime = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long id) {
t = times.get(pos);
Intent intent = new Intent(EditarTimes.this, CadastroTimes.class);
String strName = "Alterar";
intent.putExtra("Alterar", strName);
startActivity(intent);
}
};
private AdapterView.OnItemLongClickListener excluirTime = new AdapterView.OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int pos, long arg3) {
excluirTime(times.get(pos).getId());
return true;
}
};
private void exibirMensagem(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
public void telaCadastrar(View view) {
Intent intent = new Intent(this, CadastroTimes.class);
startActivity(intent);
}
public void botaoSair(View view) {
Intent intent = new Intent(this, TelaInicial.class);
startActivity(intent);
}
}
You can pass the button caption to CadastroTimes with intent as
Intent intent = new Intent(EditarTimes.this, CadastroTimes.class);
intent.putExtra("buttontxt","Changed Text");
startActivity(intent);
Then in CadastroTimes.java set the text of the button to the new value that you passed. The code will look like:
button = (Button)findViewById(R.id.button); // This is your reference from the xml. button is my name, you might have your own id given already.
Bundle extras = getIntent().getExtras();
String value = ""; // You can do it in better and cleaner way
if (extras != null) {
value = extras.getString("buttontxt");
}
button.setText(value);
Do remember to do it in onCreate after setContentView
//From Activity
Intent intent = new Intent(EditarTimes.this, CadastroTimes.class);
intent.putExtra("change_tag", "text to change");
startActivity(intent);
//To Activity
public void onCreate(..){
Button changeButton = (Button)findViewById(R.id.your_button);
// Button to set received text
Intent intent = getIntent();
if(null != intent &&
!TextUtils.isEmpty(intent.getStringExtra("change_tag"))) {
String changeText = intent.getStringExtra("change_tag");
// Extracting sent text from intent
changeButton.setText(changeText);
// Setting received text on Button
}
}
1: Use intent.putExtra() to share a value from one activity another activity, as:
In ActivityOne.class :
startActivity(
Intent(
applicationContext,
ActivityTwo::class.java
).putExtra(
"key",
"value"
)
)
In ActivityTwo.class :
var value = ""
if (intent.hasExtra("key")
value = intent.getStringExtra("key")
2: Modify button text programatically as:
btn_object.text = value
Hope this will help you
For changing the button text:
Use a static method to call from the other activity to directly modify the button caption.
Use an intent functionality, which is preferable.
Use an Interface and implement it, which is used for communicating between activities or fragment in a manner of fire and forget principle.
Now, i got you:
Your EditarTimes activity with listview:
//set setOnItemClickListener
youtListView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
Intent i = new Intent(EditarTimes.this, CadastroTimes.class);
//text which you want to display on the button to CadastroTimes activity
String strName = "hello button";
i.putExtra("STRING_I_NEED", strName);
}
});
In CadastroTimes activity,
under onCreate() method, get the text string as:-
String newString;
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras == null) {
newString= null;
} else {
newString= extras.getString("STRING_I_NEED");
}
} else {
newString= (String) savedInstanceState.getSerializable("STRING_I_NEED");
}
//button in CadastroTimes activity to have that String as text
yourButton.setText(newString);
Ok, so the first step would be to take the button you want and make it a public static object (and put it at the top of the class).
public static Button button;
Then you can manipulate that using this in another class:
ClassName.button.setText("My Button");
In your case it is
CadastroTimes.salvar.setText("Alterar");
if you want to change value from that do not do not go the activity via intent you can use file to save value to file or you have multiple values the use database and access
the value oncreate to set the value of text....
In my case, I had to send an EditText value from a Dialog styled Activity, which then got retrieved from a Service.. My Example is similar to some of the above answers, which are also viable.
TimerActivity.class
public void buttonClick_timerOK(View view) {
// Identify the (EditText) for reference:
EditText editText_timerValue;
editText_timerValue = (EditText) findViewById(R.id.et_timerValue);
// Required 'if' statement (to avoid NullPointerException):
if (editText_timerValue != null) {
// Continue with Button code..
// Convert value of the (EditText) to a (String)
String string_timerValue;
string_timerValue = editText_timerValue.getText().toString();
// Declare Intent for starting the Service
Intent intent = new Intent(this, TimerService.class);
// Add Intent-Extras as data from (EditText)
intent.putExtra("TIMER_VALUE", string_timerValue);
// Start Service
startService(intent);
// Close current Activity
finish();
} else {
Toast.makeText(TimerActivity.this, "Please enter a Value!", Toast.LENGTH_LONG).show();
}
}
And then inside my Service class, I retrieved the value, and use it inside onStartCommand.
TimerService.class
// Retrieve the user-data from (EditText) in TimerActivity
intent.getStringExtra("TIMER_VALUE"); // IS THIS NEEDED, SINCE ITS ASSIGNED TO A STRING BELOW TOO?
// Assign a String value to the (EditText) value you retrieved..
String timerValue;
timerValue = intent.getStringExtra("TIMER_VALUE");
// You can also convert the String to an int, if needed.
// Now you can reference "timerValue" for the value anywhere in the class you choose.
Hopefully my contribution helps!
Happy coding!
Accessing view reference of another Activity is a bad practice. Because there is no guarantee if the reference is still around by the time you access it (considering the null reference risk).
What you need to do is to make your other Activity read values (which you want to display) from a data source (e.g. persistence storage or shared preferences), and the other Activity manipulates these values. So it appears as if it changes the value of another activity, but in reality it takes values from a data source.
Using SharedPreferences:
Note: SharedPreferences saves data in the app if you close it but it will be lost when it has been deleted.
In EditarTimes.java:
private AdapterView.OnItemClickListener selecionarTime = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView arg0, View arg1, int pos, long id) {
t = times.get(pos);
SharedPreferences.Editor editor = getSharedPreferences("DATA", MODE_PRIVATE).edit();
editor.putString("btnText", "Your desired text");
editor.apply();
Intent intent = new Intent(EditarTimes.this, CadastroTimes.class);
startActivity(intent);
}
};
In CadastroTimes.java
public Button salvar;
salvar.setText(getSharedPreferences("DATA", MODE_PRIVATE).getString("btnText", ""));
//note that default value should be blank
As far as my thoughts go, I can realize that the problem is not with the code you provided as it seems to be implemented correctly. It is possible that you have saved the activityState somewhere in your actual code and because it is not implemented properly, the savedInstanceState found in the onCreate method is not null but the required information is missing or not correct. That's why newString is getting null and salvar textview is getting blank.
Here, I need to know which one is more useful to you - information from getIntent() or from savedInstanceState? The code you provided insists me to assume that savedInstanceState has got the preference.
If you prefer savedInstanceState, then you may use SharedPreferences like this to get the same value you want:
private SharedPreferences mPrefs;
private String newString;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
........
// try to get the value of alterarValue from preference
mPrefs = getSharedPreferences("MyData", MODE_PRIVATE);
newString = mPrefs.getString("alterarValue", "");
if (newString.equals("")){
// we have not received the value
// move forward to get it from bundle
newString = getIntent().getStringExtra("Alterar");
}
// now show it in salvar
salvar.setText(newString);
}
protected void onPause() {
super.onPause();
// you may save activity state or other info in this way
SharedPreferences.Editor ed = mPrefs.edit();
ed.putString("alterarValue", newString);
ed.commit();
}
Or if you don't need to get it from savedInstanceState, please use it:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
........
// try to get the value of alterarValue from bundle
String newString = getIntent().getStringExtra("Alterar");
// now show it in salvar
salvar.setText(newString);
}
That's all I know. Hope it will help. If anything goes wrong, please let me know.
I have an application that I have taking a picture, and then it is supposed to send the data from the picture to another activity using an intent.
I am trying to call the intent inside the jpegCallback, but the problem is I also need to release the camera through the preview class before calling the intent. However, I can not get to the original preview object from inside the callback, so I need a way to call MainActivity.doPictureResults() from inside the callback. Or I need a way to have a listener that fires after all of the picture callbacks are done.
Here is my MainActivity class which holds an instance of Preview class in the mPreview variable. The jpegCallback is at the bottom, and I want to call the doPictureResults from inside that, or setup another callback for after that function is done.
public class MainActivity extends Activity {
private final String TAG = "MainActivity";
private Preview mPreview;
Camera mCamera;
int numberOfCameras;
int cameraCurrentlyLocked;
//The first rear facing camera
int defaultCameraId;
/**
* Constructor
* #param savedInstanceState
*/
#Override
protected void onCreate(Bundle savedInstanceState) {Log.e(TAG, "onCreate");
super.onCreate(savedInstanceState);
//Hide the window title.
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
//Create a RelativeLayout container that will hold a SurfaceView,
//and set it as the content of our activity.
this.mPreview = new Preview(this);
setContentView(this.mPreview);
//Find the total number of cameras available
this.numberOfCameras = Camera.getNumberOfCameras();
//Find the ID of the default camera
CameraInfo cameraInfo = new CameraInfo();
for(int i = 0; i < this.numberOfCameras; i++) {
Camera.getCameraInfo(i, cameraInfo);
if(cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
this.defaultCameraId = i;
}
}
}
#Override
protected void onResume() {Log.e(TAG, "onResume");
super.onResume();
//Open the default i.e. the first rear facing camera.
this.mCamera = Camera.open();
this.cameraCurrentlyLocked = this.defaultCameraId;
this.mPreview.setCamera(mCamera);
}
#Override
protected void onPause() {Log.e(TAG, "onPause");
super.onPause();
//Because the Camera object is a shared resource, it's very
//Important to release it when the activity is paused.
this.mPreview.releaseCamera();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
//Inflate our menu which can gather user input for switching camera
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.camera_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
//Handle item selection
switch (item.getItemId()) {
case R.id.switchCam:
//Check for availability of multiple cameras
if(this.numberOfCameras == 1) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(this.getString(R.string.camera_alert)).setNeutralButton("Close", null);
AlertDialog alert = builder.create();
alert.show();
return true;
}
//OK, we have multiple cameras.
//Release this camera -> cameraCurrentlyLocked
this.mPreview.releaseCamera();
//Acquire the next camera and request Preview to reconfigure parameters.
this.mCamera = Camera.open((this.cameraCurrentlyLocked + 1) % this.numberOfCameras);
this.cameraCurrentlyLocked = (this.cameraCurrentlyLocked + 1) % this.numberOfCameras;
this.mPreview.switchCamera(mCamera);
//Start the preview
this.mCamera.startPreview();
return true;
case R.id.takePicture:
this.mCamera.takePicture(null, null, jpegCallback);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void doPictureResults(byte[] data) {
this.mPreview.releaseCamera();
//Release the camera and send the results of the image to the GetResults view
Intent resultsIntent = new Intent(MainActivity.this, ImageProcessorActivity.class);
resultsIntent.putExtra("image_data", data);
startActivity(resultsIntent);
}
/**
* Handles data for jpeg picture when the picture is taken
*/
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera mCamera) {Log.e(TAG, "jpegCallback");
String baseExternalDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = String.format("Assist/%d.jpg", System.currentTimeMillis());
FileOutputStream outStream = null;
try {
//Create the directory if needed
File assistDirectory = new File(baseExternalDir + File.separator + "Assist");
assistDirectory.mkdirs();
// Write to SD Card
outStream = new FileOutputStream(baseExternalDir + File.separator + fileName);
outStream.write(data);
outStream.close();
}
catch (FileNotFoundException e) {
Log.e(TAG, "IOException caused by PictureCallback()", e);
}
catch (IOException e) {
Log.e(TAG, "IOException caused by PictureCallback()", e);
}
//This is the type of thing I WANT to do....but its not possible.
MainActivity.doPictureResults();
}
};
}
One options would be to create a PictureCallback implementation that saved the information was required in doPictureResults. It's not clear if doPictureResults will be called anywhere else; if it's not, this is clean and isolates the functionality.
Another would be to have the activity itself implement PictureCallback so you have direct access to all the member variables without having to do any work at all. This allows doPictureResults to be called from other places.
public class MainActivity extends Activity implements PictureCallback {
...
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
....
case R.id.takePicture:
this.mCamera.takePicture(null, null, this);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
...
public void onPictureTaken(byte[] data, Camera mCamera) {
Log.d(TAG, "jpegCallback");
String baseExternalDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = String.format("%d.jpg", System.currentTimeMillis());
...
doPictureResults();
}
}
The only methods you can call on a class without an instance are static methods, but I don't know if that will do what you want here.