When I made an new activity .xml file in android studio, it created a corresponding .java file.
I set an onClick method call from new activity, but it still is looking for that method in mainActivity.java.
I want to define activities method in corrosopnding .java file and link .xml with .java
If I am understanding you correctly, you are trying to set an action onClick() for a button or some other view, however when you click it nothing happens. Is that right? It seems to me like your activity is tied to the wrong .xml file. Double check that in your .java files have the correct layout defined in setContentView();
For example...
In MainActivity.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // pay attention to this
Button button = (Button) findViewById(R.id.button); // or else it won't know where to find the button in the layout
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, Main2Activity.class);
tartActivity(intent);
}
});
}
In Main2Activity.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2); // pay attention to this too
}
Whenever you create a new activity on Android it will not come to life unless you tell it to by code. Now, if you look into your manifest file you will be able to see which one is the activity that is started with the program, the initial is the MainActivity.java file(It does not have to be named MainActivity but it is the default in Android)
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
If you look into your manifest file after you have added the second activity you will see a new <activity> tag with the name of the second activity that you added right before the end of the application tag:
<activity
android:name=".Main2Activity"
android:label="#string/title_activity_main2"
android:theme="#style/AppTheme">
</activity>
This means that your activities are properly registered on your manifest file(as they should)
In order for you to use it you would require something to call it, like a button click that activates an Intent just like Michael said above me. Try to go through the basic Android tutorial to see this happening and try and implement it yourself. Every view that you have in android corresponds to an activity file(for the most part, they can be fragments as well but that is a topic for another day) and most of the code corresponding the activity events will definitely require you to code your logic inside the activity file. Think of the java file as the controller, the xml layouts as the view, your controller file manipulates the view.
Related
So let's say I wanna make an app that scans an nfc tag when the user taps the "scan tag" button.
Currently I am having a few issues with it even though I spent the last week trying to figure it out on my own😅
The main issue that I am facing is that the app will scan nfc tags in the background (or at least looks like it) and will open a new instance of my app but with the name of "Nfc Service" (which is not what I named my app).
The other issue that I am facing is that, in the code, when I try to call my "readTag()" mehtod, it only works if it opens that "Nfc Service" thing I said before, otherwise it doesn't read the tag, but only breaks. From my understanding it looks like the readTag() method is running in the background rather than when I tell it to.
TL;DR: I don't want my app to scan nfc tags in the background but only on a button press.
Help would be massively appreciated especially because my deadline it tomorrow 😅 T-T
Here is some of my code (I can't show everything unfortunately):
AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ips.software.iasset_ips">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.IAssetIPS">
<activity android:name=".WebViews.AssetInfoWebView"></activity>
<activity android:name=".Activities.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="#xml/nfc_tech_filter" />
</activity>
</application>
</manifest>
xml/nfc_tech_filter:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.NfcA</tech>
</tech-list>
</resources>
MainActivity: (just the parts relevant to the question)
// package + all the imports
// ...
public class MainActivity extends AppCompatActivity {
private Button scanButton;
NfcAdapter adapter;
Tag tag;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
configureScanButton();
}
private void configureScanButton() {
scanButton= findViewById(R.id.scanButton);
scanButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
readTag();
}
});
}
public void readTag() {
adapter = NfcAdapter.getDefaultAdapter(this); // initialize the nfc reader
checkNfcSupport(); // check if device supports nfc, if not close and Toast.show
tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG); // read the tag
decodeSerialNumberFromTag(); // can't show you this function, but it's only decoding, it shouldn't be the cause of the problem
Toast.makeText(this, "Serial Number: " + serialNumber, Toast.LENGTH_LONG).show();
}
}
So yeah i think that's all, it would also be nice if I could call the readTag() method whenever I want to scan a new tag.
I talk too much, thank you in advance :D
The only way to start the interaction of you App to an NFC Tag is via the NFC Service, but if you program it properly it is possible to achieve the your desired behaviour.
First off, the manifest Intent filter are really only about telling the NFC Service to start/restart your App when a Tag of the right type comes in to range.
There is an interaction with the "launchMode" of your App as detailed in https://stackoverflow.com/a/64834600/2373819
The way to handle an NFC tag when your App is running is to use enableForegroundDispatch or use the better enableReaderMode APIs which tell the NFC Service to pass you the Tag object in different ways when a Tag comes in to range.
An example of the better enableReaderMode API for reading and writing is at https://stackoverflow.com/a/64921434/2373819 (You can ignore the writing bit)
It is not the normal workflow to do something with a Tag only when you press a button as a Tag might or might not be in range, what you are actually doing in your current readTag method when you press the button is just processing the Intent that was stored when the activity was started no actually I/O for reading is being done to the Tag. The Tag UID and any NDEF message stored on the Tag will have been cached in the Tag Object/Intent when it came in to range.
To do the similar with enableReaderMode in the onTagDiscovered method you would store the Tag Object is a global variable in the Activity class and then process it when you press the button with checking the Tag object is not null i.e. user has pressed the button with not Tag has every been in range.
If want to read other non cached data when you press the button you need to handle Tag out or range errors and other I/O errors as you would if your were processing the Tag immediately when it came in to range, just you are more likely to have them.
I would say it is always good practise when using NFC in your App to enableForegroundDispatch or use the better enableReaderMode to as the NFC service to send you the Tag Object even if you don't want to do anything with it at that point in time because it will prevent the NFC service launching another App to handle it or even itself displaying a basic information screen over the top of your App about the Tag that came in to range. e.g. have an empty method in onNewIntent or onTagDiscovered
Activity A has a list of categories (RecyclerView) in a fragment. When clicking on an item, a new Activity B is launched, which also contains a list of items (RecyclerView) in a fragment, via an adapter:
`
myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent dynamicCableView = new Intent(view.getContext(), CableOverview.class);
dynamicItemView.putExtra("systemModel", systemModelList.get(position));
view.getContext().startActivity(dynamicItemView);
}`
Clicking on one of those, Activity C, containing data pertaining to that item, is launched, basically like this:
public void goToAnActivity(View view) {
Intent Intent = new Intent(this, AnActivity.class);
startActivity(Intent);
}
When returning from Activity C via the back button to its parent Activity B, the previous state is not stored, so the list of items is gone whereas in my understanding, it should be retrieved from the stack. Instead onDestroy of B (NOT only of C) is called. I do NOT want to preserve data from Activity C but go back to its parent which should maintain its state. It basically should remember which category was selected to display its subset of items. I am using API 25.
I tried: overriding onSaveInstanceState in the fragment of B or in the activity. Doing away with the fragments and putting the lists in the activity itself. However, savedInstanceState is always null when navigating back.
How do I ensure my list can be recreated?
EDIT: Manifest contains:
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.Launcher">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
I found the solution when realizing that the problem actually was OnDestroy always getting called when navigating back. Thanks to #gokhan, I knew it was related to the launch mode. According to this answer, Activity B requires this line in the manifest:
android:launchMode="singleTop"
I was wondering if it is possible to make an android app and when the user hits the launch icon, the browser opens with a specific URL. I know that you can make shortcuts on your phone home screen with the URL you want but I was wondering if it is possible as an android app. So the app should don almost nothing just when i tap on it the browser should open..
is this possible? and is yes how should I think it?
Do this in the main activity's onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://stackoverflow.com"));
startActivity(intent);
finish();
}
in the manifest add noDisplay theme:
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme = "#android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Ugh, so many posts on StackOverflow similar to my problem but none fix it :/
I am currently learning android development. In my main activity I do:
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch(item.getItemId()){
case R.id.changeName:
Intent intent = new Intent(this, PreferenceActivity.class);
startActivityForResult(intent, 1);
return true;
}
return false;
}
Preference.java is a freshly created activity with nothing in it except the automatically created onCreate method. The error is:
android.content.ActivityNotFoundException: Unable to find explicit activity class {com.package.chat.oneway.client/android.preference.PreferenceActivity}; have you declared this activity in your AndroidManifest.xml?
My android manifest has:
<application
android:allowBackup="false"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name">
<activity
android:name=".ChatClient"
android:label="#string/app_name" />
<activity android:name=".Parent">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".PreferenceActivity"></activity>
</application>
As you can see, .PreferenceActivity is in the manifest. The packages for the ChatClient and PreferenceActivity activities are the same com.package.chat.oneway.client package.It's been driving me nuts for the past 4 hours.
As you can see, .PreferenceActivity is in the manifest.
Yes, it is. However, that is not what your Intent is using. If you look more closely at the error message, you will see that your Intent is using android.preference.PreferenceActivity.
This comes when you reuse existing class names. There are countless possible class names. Rename yours to something else, and you can avoid this sort of problem in the future.
Or, if you are completely set on having your class named PreferenceActivity, then remove the import android.preference.PreferenceActivity statement from the class where you are creating your Intent. Or, change your Intent to:
Intent intent = new Intent(this, com.package.chat.oneway.client.PreferenceActivity.class);
I want to be able to click on a TextView which will then direct me to a new page that will display a multi-level expandable list.
I have the expandable list created, and have made a new MainActivity.java file for it as it extends something different to the homepage
My manifest looks like this
<activity
android:name=".MainActivity"
android:layout_gravity="center"
android:label="Home"
android:theme="#style/AppTheme.NoActionBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- name defines the class that handles setting up the Activity
label will be the title for the activity
theme defines the theme to use -->
<activity android:name=".NLevelList"
android:label="Advanced Search"
android:theme="#style/AppTheme" />
I know I need to use an onClick Listener and have an onClick method in the MainActivity but I've been at it all morning and I don't understand how to do it, could someone please show me what to do
Fire an intent from your listener to start the new activity.
myTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, NLevelList.class);
startActivity(intent);
}
});
Please see the available documentation and training
http://developer.android.com/training/basics/firstapp/starting-activity.html#RespondToButton