I have uploaded a signed app on the play store. and today when I opened my firebase pannel in crashlytics it's showing 2 crashes in the last 24 hours. Both the crashes were on the same java class and line and also both on the Samsung phone only.
Here is the error: Fatal Exception: java.lang.RuntimeException
Error receiving broadcast Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x4200010....
It's in my receiver class: below is the code for the same
public void onReceive(final Context context, Intent intent) {
connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
if (alertdialog != null) {
alertdialog.dismiss();
}
} else {
builder = new AlertDialog.Builder(context);
View view = LayoutInflater.from(context).inflate(R.layout.internet_dialouge, null);
builder.setView(view);
builder.create();
builder.setCancelable(true);
alertdialog = builder.show();
view.findViewById(R.id.btnDismiss)
.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
alertdialog.dismiss();
}
});
view.findViewById(R.id.btnSetting)
.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
context.startActivity(new Intent(Settings.ACTION_SETTINGS));
}
});}}}}
Crashlytics showing error in this line: alertdialog = builder.show();
And I use this receiver class in the main activity like this:
myReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
myReceiver = new MyReceiver();
registerReceiver(myReceiver, intentFilter);
I am not understanding why this error in crashlytics.
"context" may be not initialized when your application reaches the line
builder = new AlertDialog.Builder(context);
Please check context is always initialized. You can check like this.
if(context!=null) {
//build alertdialog. }
Related
I have built a small chat app using firebase. I have also implemented firebaseui for logging in. The problem I am facing is, if the user has not signed up. Whenever the app launches it should take me directly to FirebaseUi signup options but what is happening with current code is for a milli second it shows the layout of main activity and then goes to FirebaseUi.
Also when I am pressing back button before exiting it again shows me the layout of main activity. I want the activity to get destroyed and take me to home (android) but it shows me main activity for a millisecond and then the app exits.
Why is this happening?
public class MainActivity extends AppCompatActivity {
private static final int RC_SIGN_IN = 1;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthStateListener;
private TextView mUserNameTextView;
private Button mSignOutButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mUserNameTextView = (TextView) findViewById(R.id.user_name_text_view);
mSignOutButton = (Button) findViewById(R.id.sign_out_button);
mAuth = FirebaseAuth.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
mAuthStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
mUserNameTextView.setText(user.getDisplayName());
} else {
// User is signed out
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setAvailableProviders(Arrays.asList(
new AuthUI.IdpConfig.EmailBuilder().build(),
new AuthUI.IdpConfig.GoogleBuilder().build()))
.build(),
RC_SIGN_IN);
}
}
};
mSignOutButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signOut();
}
});
}
private void signOut() {
FirebaseAuth.getInstance().signOut();
mUserNameTextView.setText("");
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
if (resultCode == RESULT_OK) {
// Sign-in succeeded, set up the UI
Toast.makeText(this, "Signed in!", Toast.LENGTH_SHORT).show();
} else if (resultCode == RESULT_CANCELED) {
// Sign in was canceled by the user, finish the activity
Toast.makeText(this, "Sign in canceled", Toast.LENGTH_SHORT).show();
finish();
}
}
}
#Override
protected void onPause() {
super.onPause();
if (mAuthStateListener != null) {
// when app is paused remove the state listener
mAuth.removeAuthStateListener(mAuthStateListener);
}
}
#Override
protected void onResume() {
super.onResume();
// adding the state listener
mAuth.addAuthStateListener(mAuthStateListener);
}
}
I believe you won't be able to make the Main Activity not display for a millisecond upon app start, since you are first opening the Main Activity and then you redirect it (if I understood correctly).
I can however help you with your problem when you press the back button.
Add this to your FirebaseUi code as a normal method:
#Override
public void onBackPressed() {
Intent intent = new Intent(CurrentActivity.this, NextActivity.class);
//replace "CurrentActivity" and "NextActivity" with your activity names
startActivity(intent);
}
This will open the activity you want when the back button is pressed.
When you start new activity after logged in using FirebaseUI then you need to finish(will remove the activity from backstack) the Login Activity when you start activity.
Intent intent = new Intent(ActivityA.this, NextActivity.class);
startActivity(intent);
finish();
I am writing a code which should return NFC tag value on the next activity ( page ) when NFC get detected during scan. What happens here is that when I launch the app for the first time it the first page shows for a fraction of a second and moves to second page directly ( activity ).
Here is the piece of code for the first activity ( which is just for asking user to tap to scan )
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
askPermissions();
mtxtViewNfcContent = (TextView) findViewById(R.id.text);
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Toast.makeText(this, "No NFC", Toast.LENGTH_SHORT).show();
finish();
return;
}
else {
Intent in = new Intent(Main2Activity.this, MainActivity.class);
startActivity(in);
}
What I want is the the to show the first page at launch and when user tap to nfc scan, show the output on the next page ( MainActivity).
PS : I am new to android, please excuse with my codes.
what are you doing until now is to exit the app when the device doesnot support nfc or to start another activity when the device supports nfc.
you are actually not listening at all to any tag.
here you have two possibilities:
first : read an nfc tag in the first activity and then creat a new intent with and put the result of tag reading as extra bundel.
two : listen to tag existance in the first activity and then send the tag to second one and read it in the second activity.
I would prefer the first secinario.
on firstActivity:
public class MainActivity extends AppCompatActivity {
private PendingIntent pendingIntent;
private IntentFilter[] writeTagFilters;
private NfcAdapter nfcAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.AppTheme);
setContentView(R.layout.activity_main);
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Toast.makeText(this, "No NFC", Toast.LENGTH_SHORT).show();
finish();
return;
}
setForeground();
}
private void setForeground() {
pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
writeTagFilters = new IntentFilter[]{tagDetected};
}
#Override
protected void onResume() {
super.onResume();
if (nfcAdapter != null) {
nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
}
processNfcTag(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
#Override
protected void onPause() {
super.onPause();
if (nfcAdapter != null) {
nfcAdapter.disableForegroundDispatch(this);
}
}
private void processNfcTag(Intent intent) {
//TODO: here you should to check if this intent is an NFC Intent, in case it is an nfc intent you could read it according of tag tech you have
// for example MifareUltralight.
MifareUltralight mfu = MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
try {
mfu.connect();
byte [] bytes = mfu.readPages(pageNumber);
mfu.close();
} catch (IOException e) {
e.printStackTrace();
}
// then you could get this bytes and send it to the other activity
}
please check this link to know how to send data between activities.
p.s: you should to check the code I have wrote it quickly.
You can use intent.putExtra (key,value) while calling the intent and use bundle on the result activity to fetch the variable data
use this while calling the intent
`Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("some_key", value);
intent.putExtra("some_other_key", "a value");
startActivity(intent);`
use this on result activity
`Bundle bundle = getIntent().getExtras();
int valueText = bundle.getInt("some_key");
String valueString = bundle.getString("some_other_key");
TextView textone =(TextView)findVeiwById(R.id.textone);
textone.setText(valueText);
TextView stringTextView = (TextView)FindViewById(R.id.stringTextView)
stringTextView.setText(valueString)`
I have a code for network change state in android. but now problem is that code shows the snack-bar when network state changed. i want that it will show dialogue box when network state get changed. I already done everything. i just want instead of snack-bar dialogue will be shown.
IntentFilter intentFilter = new IntentFilter(NetworkStateChangedReceiver.NETWORK_AVAILABLE_ACTION);
LocalBroadcastManager.getInstance(this).registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
boolean isNetworkAvailable = intent.getBooleanExtra(IS_NETWORK_AVAILABLE, false);
String networkStatus = isNetworkAvailable ? "connected" : "disconnected";
Snackbar.make(findViewById(R.id.activity_dashboard), "Network Status: " + networkStatus, Snackbar.LENGTH_LONG).show();
}
}, intentFilter);
Just use the AlertDialog.Builder to create an alert dialog instead of Snackbar. Something along the following lines should work,
IntentFilter intentFilter = new IntentFilter(NetworkStateChangedReceiver.NETWORK_AVAILABLE_ACTION);
LocalBroadcastManager.getInstance(this).registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
boolean isNetworkAvailable = intent.getBooleanExtra(IS_NETWORK_AVAILABLE, false);
String networkStatus = isNetworkAvailable ? "connected" : "disconnected";
//Snackbar.make(findViewById(R.id.activity_dashboard), "Network Status: " + networkStatus, Snackbar.LENGTH_LONG).show();
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.dialog_message).setTitle(R.string.dialog_title);
AlertDialog dialog = builder.create();
}
}, intentFilter);
This is a simple AlertDialog that you can use:
public static Dialog createSimpleOkDialog(Context context, String title, String message) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(context)
.setTitle(title)
.setMessage(message)
.setNegativeButton(android.R.string.ok, null);
return alertDialog.create();
}
I have SplashActivity, Activity A and Activity B.
When the Internet is not available, Splash activity redirects to Activity A and when Internet is available and is connected SplashActivity redirects to Activity B.
I would like to immediately close the Activity A when user is connected itself and Open Activity B when user is still inside the app and he open his wifi or mobile Data.
Here is the code I'm using in SplahsActivity to redirect to Activity A and Activity B as per Network status
public static boolean isNetworkStatusAvialable(Context context) {
ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();
}
and I check with
if (isNetworkStatusAvialable(getApplicationContext())) {
// Load Activity B
} else {
Load Activity A and Toast Message, " No Internet"
}
Thanks in advance.
In this case you should check network status using BroadcastReceiver because you immediately want to close current activity and move to other activity. So below is complete code for it:
ConnectivityStatusReceiver.java
public class ConnectivityStatusReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connMgr.getActiveNetworkInfo();
if (activeNetworkInfo != null) {
Toast.makeText(context, activeNetworkInfo.getTypeName() + " connected", Toast.LENGTH_SHORT).show();
// Your code to start Activity B
Activity activity = (Activity) context;
intent = new Intent(activity, ActivityB.class);
activity.startActivity(intent);
} else {
Toast.makeText(context, "No Internet or Network connection available", Toast.LENGTH_LONG).show();
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
ConnectivityStatusReceiver connectivityStatusReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connectivityStatusReceiver = new ConnectivityStatusReceiver();
}
#Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(connectivityStatusReceiver, intentFilter);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (connectivityStatusReceiver != null) {
// unregister receiver
unregisterReceiver(connectivityStatusReceiver);
}
}
}
To close Activity A you just add android:noHistory="true" in Manifest like below:
<activity android:label="#string/app_name" android:name="ActivityA"/>
Hope this will help you.
I want my app to auto-connect to already connected bluetooth device on restarting the app. Below is procedure I am performing:-
[Initially] Bluetooth device is 'ON': Then on starting the app.
[Behavior]--> Bluetooth device gets paired and connected successfully ( Intent 'ACTION_ACL_CONNECTED' is received)
Bluetooth device is 'ON': Closed the app, then started the app again.
[Behavior]--> Even though it is connected as displayed on Bluetooth setting, and Broadcast Receiver does not receive Intent 'ACTION_ACL_CONNECTED'.
Note:- On closing the app, it does not disconnect the bluetooth connection.
So, on successful connection app straightaway goes to the HomeScreen. Otherwise, the app goes to a screen having button that takes it to Bluetooth setting(onClickListener present in the code below)
I am new to android development, so I really don't know where am I going wrong. I looked up the solutions for similar issues and applied them, but to no effect.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_index);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
registerReceiver(mReceiver, filter);
IntentFilter filter1 = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
this.registerReceiver(mReceiver, filter1);
m_app = (BtApp) getApplication();
imagebt = (ImageView) this.findViewById(R.id.imagebt);
imagebt.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
final Toast tag = Toast.makeText(getApplicationContext(), "Connect to device", Toast.LENGTH_LONG);
tag.show();
new CountDownTimer(1000, 1000)
{
public void onTick(long millisUntilFinished) {tag.show();}
public void onFinish() {
//tag.show();
}
}.start();
if(mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()){
mBluetoothAdapter.startDiscovery();
}
Intent intentBluetooth = new Intent();
intentBluetooth.setAction(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
startActivity(intentBluetooth);
}
});
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if ( BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
m_app.m_main.setupCommPort();
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
m_app.m_device = device;
isconnected = true;
new Timer().schedule(new TimerTask() {
#Override
public void run() {
if ( m_app.m_main.m_BtService != null && m_app.m_main.m_BtService.getState() != BluetoothRFCommService.STATE_CONNECTED ) {
m_app.m_main.m_BtService.connect(device, false);
}
}
}, 3500);
} else if ( BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action) ) {
isconnected = false;
m_app.m_main.tabHost.setCurrentTab(0);
}
}
};
#Override
protected void onStop()
{
unregisterReceiver(mReceiver);
super.onStop();
}
You won't get BluetoothDevice.ACTION_ACL_CONNECTED event since the device is still connected. The event is fired only on changing of device state from disconnected to connected.
You have 2 options.
You can put your BroadcastReceiver with BluetoothDevice.ACTION_ACL_CONNECTED and BluetoothDevice.ACTION_ACL_DISCONNECTED filters into the Service and track the device connection state in the background. On your app startup you can ask the service to give you the current state of the device.
You can check if some of the Bluetooth profiles contains your device name in the list of connected devices.
For API 18+ you can use BluetoothManager#getConnectedDevices() for API below 18 you can use the following snippet (for each Bluetooth profile)
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
for (BluetoothDevice device : proxy.getConnectedDevices()) {
if (device.getName().contains("DEVICE_NAME")) {
deviceConnected = true;
}
}
if (!deviceConnected) {
Toast.makeText(getActivity(), "DEVICE NOT CONNECTED", Toast.LENGTH_SHORT).show();
}
mBluetoothAdapter.closeProfileProxy(profile, proxy);
}
public void onServiceDisconnected(int profile) {
// TODO
}
};
mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.A2DP);