użyj PhoneStateListener, aby zobaczyć, kiedy połączenie jest zakończone. najprawdopodobniej będziesz musiał wyzwolić akcje słuchacza, aby zaczekały na rozpoczęcie połączenia (poczekaj, aż ponownie zmieni się z PHONE_STATE_OFFHOOK na PHONE_STATE_IDLE), a następnie napisz kod, aby przywrócić aplikację do stanu bezczynności.
może być konieczne uruchomienie odbiornika w usłudze, aby upewnić się, że działa, a aplikacja jest ponownie uruchamiana. przykładowy kod:
EndCallListener callListener = new EndCallListener();
TelephonyManager mTM = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
mTM.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);
Definicja słuchacza:
private class EndCallListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
if(TelephonyManager.CALL_STATE_RINGING == state) {
Log.i(LOG_TAG, "RINGING, number: " + incomingNumber);
}
if(TelephonyManager.CALL_STATE_OFFHOOK == state) {
Log.i(LOG_TAG, "OFFHOOK");
}
if(TelephonyManager.CALL_STATE_IDLE == state) {
Log.i(LOG_TAG, "IDLE");
}
}
}
W swoim Manifest.xml
pliku dodaj następujące uprawnienia:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Chodzi o pytanie zadane przez Startera.
Problem z Twoim kodem polega na tym, że nie przekazujesz numeru poprawnie.
Kod powinien wyglądać następująco:
private OnClickListener next = new OnClickListener() { public void onClick(View v) { EditText num=(EditText)findViewById(R.id.EditText01); String number = "tel:" + num.getText().toString().trim(); Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse(number)); startActivity(callIntent); } };
Nie zapomnij dodać uprawnienia w pliku manifestu.
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
lub
<uses-permission android:name="android.permission.CALL_PRIVILEGED"></uses-permission>
na numer alarmowy w przypadku, gdy
DIAL
jest używany.źródło
Mieliśmy ten sam problem i udało nam się go rozwiązać, używając a
PhoneStateListener
do identyfikacji zakończenia połączenia, ale dodatkowo musieliśmy wykonaćfinish()
pierwotną czynność przed jej ponownym uruchomieniemstartActivity
, w przeciwnym razie dziennik połączeń znajdowałby się przed nim.źródło
Znalazłem EndCallListener jako najbardziej funkcjonalny przykład, aby uzyskać opisane zachowanie (finish (), call, restart) Dodałem kilka SharedPreferences, aby Listener miał odniesienie do zarządzania tym zachowaniem.
My OnClick, inicjalizacja i EndCallListener odpowiadają tylko na połączenia z aplikacji. Inne połączenia zostały zignorowane.
import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.Log; public class EndCallListener extends PhoneStateListener { private String TAG ="EndCallListener"; private int LAUNCHED = -1; SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences( myActivity.mApp.getBaseContext()); SharedPreferences.Editor _ed = prefs.edit(); @Override public void onCallStateChanged(int state, String incomingNumber) { String _prefKey = myActivity.mApp .getResources().getString(R.string.last_phone_call_state_key), _bPartyNumber = myActivity.mApp .getResources().getString(R.string.last_phone_call_bparty_key); int mLastCallState = prefs.getInt(_prefKey, LAUNCHED); //Save current call sate for next call _ed.putInt(_prefKey,state); _ed.commit(); if(TelephonyManager.CALL_STATE_RINGING == state) { Log.i(TAG, " >> RINGING, number: " + incomingNumber); } if(TelephonyManager.CALL_STATE_IDLE == state && mLastCallState != LAUNCHED ) { //when this state occurs, and your flag is set, restart your app if (incomingNumber.equals(_bPartyNumber) == true) { //Call relates to last app initiated call Intent _startMyActivity = myActivity.mApp .getPackageManager() .getLaunchIntentForPackage( myActivity.mApp.getResources() .getString(R.string.figjam_package_path)); _startMyActivity.setAction( myActivity.mApp.getResources() .getString(R.string.main_show_phone_call_list)); myActivity.mApp .startActivity(_startMyActivity); Log.i(TAG, "IDLE >> Starting MyActivity with intent"); } else Log.i(TAG, "IDLE after calling "+incomingNumber); } } }
dodaj je do strings.xml
<string name="main_show_phone_call_list">android.intent.action.SHOW_PHONE_CALL_LIST</string> <string name="last_phone_call_state_key">activityLpcsKey</string> <string name="last_phone_call_bparty_key">activityLpbpKey</string>
i coś takiego w swoim Manifeście, jeśli chcesz wrócić do wyglądu i stylu sprzed rozmowy
<activity android:label="@string/app_name" android:name="com.myPackage.myActivity" android:windowSoftInputMode="stateHidden" android:configChanges="keyboardHidden" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.SHOW_PHONE_CALL_LIST" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
i umieść je w swojej „myActivity”
public static Activity mApp=null; //Before onCreate() ... onCreate( ... ) { ... if (mApp == null) mApp = this; //Links your resources to other classes ... //Test if we've been called to show phone call list Intent _outcome = getIntent(); String _phoneCallAction = mApp.getResources().getString(R.string.main_show_phone_call_list); String _reqAction = _outcome.getAction();//Can be null when no intent involved //Decide if we return to the Phone Call List view if (_reqAction != null &&_reqAction.equals(_phoneCallAction) == true) { //DO something to return to look and feel } ... myListView.setOnItemClickListener(new OnItemClickListener() { //Act on item when selected @Override public void onItemClick(AdapterView<?> a, View v, int position, long id) { myListView.moveToPosition(position); String _bPartyNumber = "tel:"+myListView.getString(myListView.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); //Provide an initial state for the listener to access. initialiseCallStatePreferences(_bPartyNumber); //Setup the listener so we can restart myActivity EndCallListener _callListener = new EndCallListener(); TelephonyManager _TM = (TelephonyManager)mApp.getSystemService(Context.TELEPHONY_SERVICE); _TM.listen(_callListener, PhoneStateListener.LISTEN_CALL_STATE); Intent _makeCall = new Intent(Intent.ACTION_CALL, Uri.parse(_bPartyNumber)); _makeCall.setComponent(new ComponentName("com.android.phone","com.android.phone.OutgoingCallBroadcaster")); startActivity(_makeCall); finish(); //Wait for call to enter the IDLE state and then we will be recalled by _callListener } }); }//end of onCreate()
użyj tego do zainicjowania zachowania swojego onClick w myActivity, np. po onCreate ()
private void initialiseCallStatePreferences(String _BParty) { final int LAUNCHED = -1; SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( mApp.getBaseContext()); SharedPreferences.Editor _ed = prefs.edit(); String _prefKey = mApp.getString(R.string.last_phone_call_state_key), _bPartyKey = mApp.getString(R.string.last_phone_call_bparty_key); //Save default call state before next call _ed.putInt(_prefKey,LAUNCHED); _ed.putString(_bPartyKey,_BParty); _ed.commit(); }
Powinieneś zauważyć, że kliknięcie listy numerów telefonów kończy Twoją działalność, powoduje połączenie z numerem i powrót do Twojej aktywności po zakończeniu połączenia.
Wykonywanie połączenia spoza aplikacji, gdy jest ona nadal w pobliżu, nie spowoduje ponownego uruchomienia Twojej działalności (chyba że jest to ten sam numer, z którym dzwoniono ostatnio).
:)
źródło
możesz użyć startActivityForResult ()
źródło
To jest rozwiązanie z mojego punktu widzenia:
ok.setOnClickListener(this); @Override public void onClick(View view) { if(view == ok){ Intent intent = new Intent(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:" + num)); activity.startActivity(intent); }
Oczywiście w definicji Activity (class) musisz zaimplementować View.OnClickListener.
źródło
Oto mój przykład: najpierw użytkownik wpisuje numer, który chce wybrać, a następnie naciska przycisk połączenia i zostaje przekierowany do telefonu. Po anulowaniu połączenia użytkownik zostaje odesłany z powrotem do aplikacji. W tym celu przycisk musi mieć metodę onClick (w tym przykładzie „makePhoneCall”) w pliku xml. Musisz również zarejestrować pozwolenie w manifeście.
Oczywisty
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
Czynność
import android.net.Uri; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.View; import android.widget.EditText; import android.widget.Toast; public class PhoneCall extends Activity { EditText phoneTo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_phone_call); phoneTo = (EditText) findViewById(R.id.phoneNumber); } public void makePhoneCall(View view) { try { String number = phoneTo.getText().toString(); Intent phoneIntent = new Intent(Intent.ACTION_CALL); phoneIntent.setData(Uri.parse("tel:"+ number)); startActivity(phoneIntent); } catch (android.content.ActivityNotFoundException ex) { Toast.makeText(PhoneCall.this, "Call failed, please try again later!", Toast.LENGTH_SHORT).show(); } } }
XML
<EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="phone" android:ems="10" android:id="@+id/phoneNumber" android:layout_marginTop="67dp" android:layout_below="@+id/textView" android:layout_centerHorizontal="true" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Call" android:id="@+id/makePhoneCall" android:onClick="makePhoneCall" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" />
źródło
@Override public void onClick(View view) { Intent phoneIntent = new Intent(Intent.ACTION_CALL); phoneIntent.setData(Uri.parse("tel:91-000-000-0000")); if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { return; } startActivity(phoneIntent); }
źródło
Jeśli zamierzasz używać listenera, musisz dodać to uprawnienie również do manifestu.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
źródło
Wewnątrz PhoneStateListener po obejrzeniu połączenia lepiej użyj:
Intent intent = new Intent(CallDispatcherActivity.this, CallDispatcherActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent);
Gdzie CallDispatcherActivity jest działaniem, w którym użytkownik uruchomił połączenie (w moim przypadku do dyspozytora taksówek). To tylko usuwa aplikację telefoniczną na Androida z góry, użytkownik wraca zamiast brzydkiego kodu, który tutaj widziałem.
źródło
((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE)).listen(this, LISTEN_NONE);
Intent intentRestart = new Intent(ControlPanel.this, ControlPanel.class);
. Powinienem zaznaczyć, że PhoneStateListener również znajduje się w ControlPanel. To znaczy, moim celem jest przywrócenie interfejsu użytkownika do stanu, w jakim znajdował się przed zainicjowaniem połączenia telefonicznego. Jakieś sugestie?Aby wrócić do swojego
Activity
, musisz posłuchaćTelephonyStates
. Na którylistener
można wysłaćIntent
do ponownego uruchomieniaActivity
, gdy telefon jest w stanie bezczynności.Przynajmniej tak to zrobię.
źródło
Intent callIntent = new Intent(Intent.ACTION_CALL); callIntent.setData(Uri.parse("tel:"+number)); startActivity(callIntent); **Add permission :** <uses-permission android:name="android.permission.CALL_PHONE" />
źródło
Spróbuj użyć:
finish();
pod koniec działania. Przekieruje Cię do poprzedniej aktywności.
źródło
Kiedy
PhoneStateListener
jest używane, należy upewnić się, żePHONE_STATE_IDLE
po aPHONE_STATE_OFFHOOK
jest używane do wyzwalania akcji, która ma zostać wykonana po wywołaniu. Jeśli wyzwolenie nastąpi po zobaczeniuPHONE_STATE_IDLE
, skończysz robiąc to przed wezwaniem. Ponieważ zobaczysz zmianę stanuPHONE_STATE_IDLE -> PHONE_STATE_OFFHOOK -> PHONE_STATE_IDLE.
źródło
((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE)).listen(new PhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE)
będzie nadal nasłuchiwał stanu telefonu i będzie aktywny, dopóki nie zostanie wyraźnie zatrzymany((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE)).listen(this, LISTEN_NONE)
// w setonclicklistener umieść ten kod:
EditText et_number=(EditText)findViewById(R.id.id_of_edittext); String my_number = et_number.getText().toString().trim(); Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse(my_number)); startActivity(callIntent);
// daj pozwolenie na wywołanie w manifeście:
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
źródło
@Dmitri Novikov,
FLAG_ACTIVITY_CLEAR_TOP
czyści każdą aktywną instancję na nowej. Może więc zakończyć starą instancję, zanim zakończy proces.źródło
Dodaj to jest twój xml:
android:autoLink="phone"
źródło
Kroki:
1) Dodaj wymagane uprawnienia w
Manifest.xml
pliku.<!--For using the phone calls --> <uses-permission android:name="android.permission.CALL_PHONE" /> <!--For reading phone call state--> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
2) Utwórz nasłuchiwanie zmian stanu telefonu.
public class EndCallListener extends PhoneStateListener { @Override public void onCallStateChanged(int state, String incomingNumber) { if(TelephonyManager.CALL_STATE_RINGING == state) { } if(TelephonyManager.CALL_STATE_OFFHOOK == state) { //wait for phone to go offhook (probably set a boolean flag) so you know your app initiated the call. } if(TelephonyManager.CALL_STATE_IDLE == state) { //when this state occurs, and your flag is set, restart your app Intent i = context.getPackageManager().getLaunchIntentForPackage( context.getPackageName()); //For resuming the application from the previous state i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); //Uncomment the following if you want to restart the application instead of bring to front. //i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); context.startActivity(i); } } }
3) Zainicjuj odbiornik w swoim
OnCreate
EndCallListener callListener = new EndCallListener(); TelephonyManager mTM = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE); mTM.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);
ale jeśli chcesz, aby wznowić swoją aplikację ostatni stan lub przynieść go ze stosu z powrotem , a następnie zastąpić
FLAG_ACTIVITY_CLEAR_TOP
zFLAG_ACTIVITY_SINGLE_TOP
Odwołaj się do tej odpowiedzi
źródło
Intent callIntent = new Intent(Intent.ACTION_CALL); callIntent .setData(Uri.parse("tel:+91-XXXXXXXXX")); startActivity(callIntent );
źródło
Kiedy zaczynasz rozmowę, wygląda dobrze.
Istnieje jednak różnica między Androidem 11+ a downem w przenoszeniu aplikacji na pierwszy plan.
Android 10 lub mniej musisz zacząć od nowa, Android 11+ po prostu używasz
BringTaskToFront
W stanie połączenia IDLE:
if (Build.VERSION.SDK_INT >= 11) { ActivityManager am = (ActivityManager) activity.getSystemService(Activity.ACTIVITY_SERVICE); am.moveTaskToFront(MyActivity.MyActivityTaskId, ActivityManager.MOVE_TASK_WITH_HOME); } else { Intent intent = new Intent(activity, MyActivity.class); activity.startActivity(intent); }
Ustawiam
MyActivity.MyActivityTaskId
wywołanie mojej aktywności w ten sposób, jeśli to nie działa, ustawiam tę zmienną na stronie aktywności nadrzędnej strony, do której chcesz wrócić.MyActivity.MyActivityTaskId = this.getTaskId();
MyActivityTaskId
jest zmienną statyczną w mojej klasie aktywnościpublic static int MyActivityTaskId = 0;
Mam nadzieję, że to zadziała. Używam powyższego kodu nieco inaczej, otwieram aplikację, gdy tylko odbierze połączenie, aby użytkownik mógł zobaczyć szczegóły dzwoniącego.
W tym też umieściłem kilka rzeczy
AndroidManifest.xml
:/*Dont really know if this makes a difference*/ <activity android:name="MyActivity" android:taskAffinity="" android:launchMode="singleTask" />
i uprawnienia:
<uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.REORDER_TASKS" />
Proszę zadawać pytania, jeśli lub kiedy utkniesz.
źródło