How to end an outgoing phone call while connecting? - java

So I try to make a app that will test if a phone can call phone numbers. And the main point is that when i push a call button and when the connection begins app ends a call and if there is no connection app shows an error. I managed to do a part where when button is clicked app calls a phone number but I can't come up with solution for ending a cal when there is connection (ringing). Is there any way to make this possible?
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
String phone = "8686868686";
Intent intent = new Intent(Intent.ACTION_CALL, Uri.fromParts("tel", phone, null));
startActivity(intent);
if (ActivityCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
return;
}
/*Context mContext = getApplicationContext();
TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
if (tm != null) {
boolean success = tm.endCall();
// success == true if call was terminated.
}*/
}
});

Related

Using mKeyguardManager for lockscreen only displays when opening the application

In Java, I am trying to implement a feature where only the admin (person who knows the device password) can access an information screen and when they click on a button within the app in the MainActivity, the lock screen will appear as a form of authentication and display another activity screen on success. Is this possible?
So far, I noticed that the authentication only displays when I open the app and not when I press the button in an onClickListener. Most of the solutions I've seen are doing it this way. I have the code in MainActivity within an onCreate() method.
MainActivity
ActivityResultLauncher<Intent> activityResultLaunch = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
#Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
// There are no request codes
Intent data = result.getData();
} else {
finish();
}
}
});
start_end_button_add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
authScreen(activityResultLaunch);
}
});
private void authScreen(ActivityResultLauncher<Intent> activityResultLaunch) {
KeyguardManager mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
if (!mKeyguardManager.isKeyguardSecure()) {
// Show a message that the user hasn't set up a lock screen.
} else {
Intent intent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, null);
if (intent != null) {
startActivityForResult.launch(intent, REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS);
}
}
Intent intent = new Intent(DetectorActivity.this, SearchActivity.class);
startActivity(intent);
finish();
}
Currently, the app immediately goes to the SearchActivity class without having the lock screen displayed in between. Even if I get into the app after PIN code entered is a success, it still doesn't get into the activityResultLaunch success condition as per the new implementation referenced here by user Martin Zeitler.
Reference:
https://mobile-security.gitbook.io/mobile-security-testing-guide/android-testing-guide/0x05f-testing-local-authentication#:~:text=In%20Android%2C%20there%20are%20two,and%20the%20Biometric%20Authentication%20flow.

How to stop signInWithEmailAndPassword when another activity is started?

I am working on a login app using FirebaseAuth, I am implementing two separate Activities, one to work online and other for offline. There is third starter activity that tries to automatically login a user if his data is present on the SharedPreferences. When finish() is called on an activity signInWithEmailAndPassword won't stop.
when internet is not working and "Work Offline" button is clicked , it will lead the user to ActivityOffline. But when internet is restored while the user is on ActivityOffline , out of nowhere ActivityOnline will pop up because of signInWithEmailAndPassword on the starter activity which is already finished.
How can i stop signInWithEmailAndPassword when my Work Offline button is clicked?
public class Starter extends AppCompatActivity {
Button useOffline;
String email;
String password;
FirebaseAuth mAuth = FirebaseAuth.getInstance();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_starter);
Prefs prefs = new Prefs(this);
email = prefs.getStringEntry("email");
password = prefs.getStringEntry("password");
useOffline = findViewById(R.id.use_offline);
useOffline.setOnClickListener(v -> {
Intent intent = new Intent(Starter.this, OfflineActivity.class);
startActivity(intent);
finish();
});
final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(() -> useOffline.setVisibility(View.VISIBLE), 5000);
if (email.equals("") || password.equals("")) {
Intent intent = new Intent(Starter.this, LoginActivity.class);
startActivity(intent);
finish();
} else {
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(task -> {
if (task.isSuccessful()) {
prefs.setStringEntry("UID", Objects.requireNonNull(FirebaseAuth.getInstance().getCurrentUser()).getUid());
Intent intent = new Intent(Starter.this, OnlineActivity.class);
startActivity(intent);
} else {
prefs.removeEntry("email");
prefs.removeEntry("password");
Intent intent = new Intent(Starter.this, LoginActivity.class);
startActivity(intent);
}
finish();
});
}
}
}
You can set a boolean flag to true when offline button press and check this flag before start online activity.

How to start new activity on nfc tag discovery?

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)`

NullPointerException on Intent between two Activities

I am trying to send an Intent value between two activities, though it appears, having read this, that in my second activity, the received intent is null; having encoutnered an NPE at runtime.
The intended functionality behind this is: 'the user scans a code in Activity A' -> 'a true value received and packed into an intent' -> 'Activity B opens, unpacks the intent and checks that the intent value is true' -> 'if true, the height of an ImageView in the activity is reduced by a set amount'.
I am therefore, not sure why my Intent is received as null in Activity B, as I would like this check to happen so that the height is updated when the activity opens?
Activity A:
//do the handling of the scanned code being true and display
//a dialog message on screen to confirm this
#Override
public void handleResult(Result result) {
final String myResult = result.getText();
Log.d("QRCodeScanner", result.getText());
Log.d("QRCodeScanner", result.getBarcodeFormat().toString());
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Activity Complete!");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
//the user has pressed the OK button
#Override
public void onClick(DialogInterface dialog, int which) {
scannerView.resumeCameraPreview(QRActivity.this);
//pack the intent and open our Activity B
Intent intent = new Intent(QRActivity.this, ActivityTank.class);
intent.putExtra("QRMethod", "readComplete");
startActivity(intent);
}
});
builder.setMessage(result.getText());
AlertDialog alert1 = builder.create();
alert1.show();
}
Activity B:
// in onCreate, I check that the bundled intent is true
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tank);
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if (extras == null) {
//then the extras bundle is null, and nothing needs to be called here
}
else {
String method = extras.getString("QRmethod");
if (method.equals("readComplete")) {
updateTank();
}
}
}
}
//this is the method that is called when the intent check is true
public int tHeight = 350;
public void updateTank() {
ImageView tankH = (ImageView)findViewById(R.id.tankHeight);
ViewGroup.LayoutParams params = tankH.getLayoutParams();
params.height = tHeight - 35;
tankH.setLayoutParams(params);
}
In Activity B you have a typo while pulling QRMethod from the Intent extras. You are using QRmethod while you have set extras with 'QRMethod'.
You can use :
In first activity ( MainActivity page )
Intent i = new Intent(MainActivity.this,SecondActivity.class);
i.putExtra("QRmethod","readComplete" );
then you can get it from your second activity by :
In second activity ( SecondActivity page )
Intent intent = getIntent();
String YourtransferredData = intent.getExtras().getString("QRmethod");
You can get string value by using intent.getStringExtra() method like this in your second activity.
if (getIntent() != null){
getIntent().getStringExtra("QRmethod") //this s your "readComplete" value
}

Android: Broadcast Receiver does not receive BluetoothDevice.ACTION_ACL_CONNECTED on restarting the application

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);

Categories

Resources