I'm making an android app with 2 activities and a Java class that reads/writes RFID data using NFC.
I'm using the enableReaderMode() method to enable reader/writer mode in the mainActivity, which then calls onTagDiscovered in a separate java class. Once in the onTagDiscovered method, I'm calling mainActivity.startNewActivity() to open a the second activity. I know that I'm reaching startNewActivity() because of a log message, but the activity is not actually starting. The app doesn't crash, and I'm not getting any errors, it just isn't starting. I've tried placing a button in the mainActivity and opening that way, and it works fine. It just doesn't work when I call the method from encode.java.
**I know that it is not necessary to open the activity from Encode.java, and that I could directly code this into MainActivity, but I'm preparing to do something more complex where I will need to open from Encode.java, and I want to test that the activity will open at all.
Here's the code
Encode.java
public class Encode implements NfcAdapter.ReaderCallback {
MainActivity mainActivity = new MainActivity();
public void onTagDiscovered(Tag tag) {
Log.i(TAG, "New tag discovered");
mainActivity.startNewActivity();
}
MainActivity
public void startNewActivity() {
Log.v(TAG, "in startNewActivity");
Intent intent = new Intent(this, Success.class);
startActivity(intent);
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.project" >
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.NFC"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />
<application
android:allowBackup="true"
android:icon="#drawable/xband"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<action android:name="android.nfc.action.TAG_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="#xml/nfc_tech" />
</activity>
<activity android:name=".Success" >
</activity>
</application>
</manifest>
Success.java
package com.project;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class Success extends Activity {
private static final String TAG = "encode";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.success_activity);
Log.v(TAG, "in success activity");
}
}
I tried adding the following code and then got this error message:
Encode.java
public void onTagDiscovered(Tag tag) {
Log.i(TAG, "New Tag Discovered");
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
mainActivity.startNewActivity();
}
});
}
02-20 11:52:27.739 22088-22088/com.project E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.project, PID: 22088
java.lang.NullPointerException
at android.app.Activity.startActivityForResult(Activity.java:3474)
at android.app.Activity.startActivityForResult(Activity.java:3435)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:817)
at android.app.Activity.startActivity(Activity.java:3677)
at android.app.Activity.startActivity(Activity.java:3645)
at com.project.MainActivity.startNewActivity(MainActivity.java:110)
at com.project.encoding.Encode$1.run(Encode.java:331)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5293)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
Someone at work was able to help me figure this out.
This wasn't working because I was creating a new instance of the MainActivity in Encode, instead of referencing the existing MainActivity.
In MainActivity we added:
private static MainActivity _instance = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
encode = new Encode();
enableReaderMode();
MainActivity._instance = this;
}
public static MainActivity getInstance() {
return _instance;
}
and in Encode we called the startNewActivity method by calling:
public void onTagDiscovered(Tag tag) {
Log.i(TAG, "New Tag Discovered");
MainActivity.getInstance().startNewActivity();
});
so that now Encode is using the existing instance of MainActivity
Instead of:
Intent intent = new Intent(this, Success.class);
Try: Intent intent = new Intent(getApplicationContext(), Success.class);
That worked for me one time cause it "Return the context of the single, global Application object of the current process. "
Related
I'm trying to send a simply customized broadcast by clicking a button, and the receiver will push a toast as it receives the broadcast. But as I clicked the button, nothing toasted with an error message in the logcat:
2021-01-18 16:23:18.870 480-480/? E/netmgr: Failed to open QEMU pipe 'qemud:network': Invalid argument
2021-01-18 16:23:20.931 485-485/? E/wifi_forwarder: qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:wififorward' service: Invalid argument
2021-01-18 16:23:20.931 485-485/? E/wifi_forwarder: RemoteConnection failed to initialize: RemoteConnection failed to open pipe
The MainActivity is:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest2.MY_BROADCAST");
sendBroadcast(intent);
}
});
}
And the BroadcastReceiver is:
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Toast.makeText(context, "My Broadcast Received", Toast.LENGTH_SHORT).show();
throw new UnsupportedOperationException("Not yet implemented");
}
}
I have also registered the action inside the BroadcastReceiver:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcasttest2">
<application
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.BroadcastTest2"
>
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.broadcasttest2.MY_BROADCAST" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Could anyone help me with that? Many thanks!
for in app broadcast communication you have to register the broadcast receiver in the Activity, in your case you missing an syntax inside onCreate like this one:
BroadcastReceiver myReceiver = new MyBroadcastReceiver();
registerReceiver(myReceiver, new IntentFilter('com.example.broadcasttest2.MY_BROADCAST'));
for more reference - Broadcast Receiver class and registerReceiver method
New to Android Studio here.
I am trying to make it so when I click on an image from a ViewHolder in a RecyclerView, it would open up another activity that opens up another layout.
However, I am getting this error even though I already declared the activity in my Manifest.
The code that is trying to create an Intent to start a new activity is a class is called StaggeredView inside app/core/StaggeredView. While the activity handler is called ImageView inside app/ImageView.
Error
android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.image_chan/android.widget.ImageView}; have you declared this activity in your AndroidManifest.xml?
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2065)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1727)
at android.app.Activity.startActivityForResult(Activity.java:5320)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:675)
at android.app.Activity.startActivityForResult(Activity.java:5278)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:662)
at android.app.Activity.startActivity(Activity.java:5664)
at android.app.Activity.startActivity(Activity.java:5617)
at com.example.image_chan.core.StaggeredAdapter$1.onClick(StaggeredAdapter.java:63)
at android.view.View.performClick(View.java:7448)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Code
onBindViewHolder (which overrides the function from class StaggeredAdapter which extends RecyclerView.Adapter<StaggeredAdapter.ViewHolder>)
public class StaggeredAdapter extends RecyclerView.Adapter<StaggeredAdapter.ViewHolder> {
/*...*/
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
RequestOptions requestOptions = new RequestOptions()
.error(R.drawable.error)
.placeholder(R.drawable.loader);
Glide.with(Context)
.load(urls.get(position))
.apply(requestOptions)
.into(holder.image);
holder.name.setText("SCORE: " + imgNames.get(position));
holder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Context viewContext = (Context) view.getContext();
Intent toView = new Intent(viewContext, ImageView.class);
viewContext.startActivity(toView);
}
});
}
/*...*/
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.image_chan">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:networkSecurityConfig="#xml/netconfig"
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.Image_chan">
<provider android:name=".core.Suggestions"
android:authorities="com.example.image_chan.core.Suggestions"/>
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/Theme.Image_chan.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ImageView"
android:label="image_chan"
android:theme="#style/Theme.Image_chan.NoActionBar">
</activity>
<activity
android:name=".Main"
android:label="image_chan"
android:theme="#style/Theme.AppCompat.DayNight.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.SEARCH"/>
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
</application>
</manifest>
Please follow these steps.
1.You should rename ImageView class to something else like ImageViewActivity or any thing.
2.Make sure this activity extends Activity or AppCompatActivity.
3.Make sure this activity is under directory app\src\main.
This should resolve your problem.
please help , when i run the app, the app launch a Fatal Error im learning
just i create a instat with a call but not run, (sorry for my english)
.......................................................................
my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.octa.appprueba3">
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
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" />
<category android:name="android.intent.category.APP_CONTACTS" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity"></activity>
</application>
</manifest>
my code:
public class SecondActivity extends AppCompatActivity {
private EditText editPhoneText;
private ImageButton imageCallButton;
private final int PHONE_CALL_CODE = 100;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
editPhoneText = (EditText) findViewById(R.id.editTextPhone);
imageCallButton = (ImageButton) findViewById(R.id.imageCallButton1);
imageCallButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
implicito();
}
});
}
public void implicito(){
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("Tel: 9999999" ));
startActivity(intent);
}
}
You may want to check whether your device can handle your intent by doing this:
PackageManager packageManager = getPackageManager();
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent);
} else {
Log.d(TAG, "Cannot handle this intent");
}
What's more, if you are placing a call like so, there is NO need to declare the permission in your manifest:
<uses-permission android:name="android.permission.CALL_PHONE" />
Because you are not directly calling someone within your app. You are actually transferring the "duty" to other apps which can handle your intent to call. This doesn't need a permission.
To directly make a call within your app, the intent should be Intent.ACTION_CALL, which needs the permission you declared.
Hope this will help.
There is no activity on your device that handles ACTION_DIAL for a Tel: scheme. Try:
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:9999999" ));
Case and whitespace are important when assembling a Uri.
Also note that even my revised Intent will not work on all devices, such as on an Android tablet that lacks a dialer.
OK, so the problem I'm having occurs when the startGame button is pressed. The app crashes when the button is pressed. The activity is instantiated in the manifest so I'm not sure where the error is. The code for the intent is a copy of the other one (which works) so I have no clue where I went wrong.
Error Log:
02-25 14:46:51.064: E/AndroidRuntime(1261): FATAL EXCEPTION: main
02-25 14:46:51.064: E/AndroidRuntime(1261): Process: com.example.hegemony, PID: 1261
02-25 14:46:51.064: E/AndroidRuntime(1261): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.hegemony/com.example.hegemony.PlayerTurn}: java.lang.NullPointerException
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hegemony"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.hegemony.SplashScreen"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.hegemony.StartScreen" >
<intent-filter>
<action android:name="com.example.hegemony.STARTSCREEN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.example.hegemony.SetupHomeScreen" >
<intent-filter>
<action android:name="com.example.hegemony.SETUPHOMESCREEN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.example.hegemony.SetupPlayer"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.example.hegemony.SETUPPLAYER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.example.hegemony.PlayerTurn"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.example.hegemony.PLAYERTURN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
Java Code of sending activity:
public class SetupHomeScreen extends Activity{
private ArrayList<Player> p = GameMaster.players;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setup_home_screen);
getActionBar().hide();
updatePlayers();
Button gotoInput = (Button) findViewById(R.id.btnSetupPlayer);
gotoInput.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent toInput = new Intent("com.example.hegemony.SETUPPLAYER");
startActivity(toInput);
}
});
Button startGame = (Button) findViewById(R.id.btnStartGame);
startGame.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent toStart = new Intent("com.example.hegemony.PLAYERTURN");
startActivity(toStart);
}
});
}
public void updatePlayers(){
TextView playerList = (TextView) findViewById(R.id.playerList);
String msg = "";
for(int i=0;i < p.size();i++)
msg = msg + "\n - "+p.get(i).getName();
playerList.setText(msg);
if(p.size() >=2){
Button enable = (Button) findViewById(R.id.btnStartGame);
enable.setEnabled(true);
}
}
}
Java code of receiving activity:
public class PlayerTurn extends Activity {
final ActionBar actionBar = getActionBar();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player_turn);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
};
}
}
Button startGame = (Button) findViewById(R.id.btnStartGame);
startGame.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent toStart = new Intent(SendingActivity.this, NewActivity.class);
startActivity(toStart);
}
});
I think this is how you should start an intent. Maybe its missing a context or the "activityname" is not the right way to do it. I tried to start an activity the way you are trying and it gave me an error as well, not the same one, but it didn't work.
I'm sorry if the solution I'm trying to provide doesn't work. This is really the first time I'm trying to help someone. I hope it works.
As per the logcat error message, your activity class is failing to instantiate. Instantiation involves the allocation and assignment of any class member variables. In the case of PlayerTurn, the only one is this:
final ActionBar actionBar = getActionBar();
The call to getActionBar() throws a NullPointerException because the activity's window has not been built yet - you should call getActionBar() after setContentView() has been called in onCreate(). You can resolve this by simply moving that line of code into onCreate().
If you still want to retain this as a class member variable, declare it but don't assign it:
ActionBar actionBar;
...and then do the assignment in onCreate():
actionBar = getActionBar();
I'm trying to get this to open an url when the icon is selected/clicked, but I get Syntax error on tokens, delete these tokens on the line String url =
String url = "http://www.google.co.uk/";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.openurl"
android:versionCode="1"
android:versionName="1.0" >
<application>
<activity android:name="OpenURL" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I've now got a bit further on this one but when I load the apk file the icon opens the browser with 2 windows - blank and the url. I;m also unable to use the back button to close the browser - it keeps opening the url. How can I correct these issues?
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="14" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name">
<activity
android:name="com.example.myapp.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
package com.example.myapp;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String url = "http://www.google.co.uk";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
}
Many thanks again!
This
String url = "http://www.google.co.uk/";
can never be the first line of a java file.
You file need a structure like:
package a.b.c; // optional
import java.util.List; // optional
public class ClassName { // mandatory
// your code
} // mandatory
If this fixes your error, you should consider reading a Java tutorial.
First of all add the permission for internet in your manifest:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
then your main should be like this:
public class Main extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.yourmainlayout);
Button button = (Button) findViewById(R.id.yourbuttonid);
button.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
String url = "http://www.google.co.uk/";
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(i);
}});
}
}