Android
Zamiar
Szukaj…
Wprowadzenie
Intent to niewielka wiadomość przekazywana w systemie Android. Ta wiadomość może zawierać informacje o naszym zamiarze wykonania zadania.
Zasadniczo jest to pasywna struktura danych zawierająca abstrakcyjny opis akcji do wykonania.
Składnia
- Intent Intent ()
- Intent Intent (Intent intent)
- Intent Intent (ciąg akcji)
- Intent Intent (String string, Uri uri)
- Intent Intent (Context packageContext, Class <?> Cls)
- Intent Intent (ciąg znaków, Uri uri, pakiet kontekstowyContext, klasa <?> Cls)
- void startActivity (zamiar zamierzony)
- void startActivity (zamiar, opcje pakietu)
- void startActivityForResult (Intent intent, int requestCode)
- void startActivityForResult (Intent intent, int requestCode, opcje pakietu)
- Przeznaczenie putExtra (nazwa ciągu, wartość podwójna [])
- Przeznaczenie putExtra (nazwa ciągu, wartość int)
- Przeznaczenie putExtra (nazwa ciągu, wartość CharSequence)
- Przeznaczenie putExtra (nazwa ciągu, wartość char)
- Przeznaczenie putExtra (nazwa ciągu, wartość pakietu)
- Przeznaczenie putExtra (nazwa ciągu, wartość działki []
- Zamierzone putExtra (nazwa ciągu, wartość szeregowa)
- Przeznaczenie putExtra (nazwa ciągu, wartość int [])
- Przeznaczenie putExtra (nazwa ciągu, wartość zmiennoprzecinkowa)
- Przeznaczenie putExtra (nazwa ciągu, wartość bajtu [])
- Przeznaczenie putExtra (nazwa ciągu, długa [] wartość)
- Przeznaczenie putExtra (nazwa ciągu, wartość działki)
- Przeznaczenie putExtra (nazwa ciągu, wartość zmiennoprzecinkowa [])
- Przeznaczenie putExtra (nazwa ciągu, długa wartość)
- Przeznaczenie putExtra (nazwa ciągu, wartość ciągu [])
- Przeznaczenie putExtra (nazwa ciągu, wartość logiczna)
- Przeznaczenie putExtra (nazwa ciągu, wartość logiczna [])
- Przeznaczenie putExtra (nazwa ciągu, krótka wartość)
- Przeznaczenie putExtra (nazwa ciągu, podwójna wartość)
- Przeznaczenie putExtra (nazwa ciągu, krótka [] wartość)
- Przeznaczenie putExtra (nazwa ciągu, wartość ciągu)
- Zamierzony putExtra (nazwa ciągu, wartość bajtu)
- Przeznaczenie putExtra (nazwa ciągu, wartość char [])
- Przeznaczenie putExtra (nazwa ciągu, wartość CharSequence [])
Parametry
Parametr | Detale |
---|---|
zamiar | Zamiar rozpoczęcia |
Kod zapytania | Unikalny numer identyfikujący żądanie |
opcje | Dodatkowe opcje dotyczące sposobu rozpoczęcia działania |
Nazwa | Nazwa dodatkowych danych |
wartość | Wartość dodatkowych danych |
CHOOSE_CONTACT_REQUEST_CODE | kod żądania, aby zidentyfikować go w metodzie onActivityResult |
akcja | Wszelkie działania do wykonania w tym celu, np .: Intent.ACTION_VIEW |
uri | URI danych, które mają być użyte przez zamiar wykonania określonej akcji |
PackageContext | Kontekst używany do inicjowania zamiaru |
cls | Klasa do wykorzystania przez ten zamiar |
Uwagi
Ostrzeżenia dotyczące korzystania z ukrytych zamiarów
Podczas wywoływania niejawnej intencji zawsze pomocne jest sprawdzenie, czy system jest w stanie to obsłużyć.
Można to zrobić, sprawdzając za pomocą PackageManager.queryIntentActivities(Intent intent, int flags)
PackageManager pm = getActivity().getPackageManager();
if (intent.resolveActivity(pm) != null) {
//intent can be handled
startActivity(intent);
} else {
//intent can not be handled
}
Aktywność singleTask
która jest singleTask
lub singleTop
Gdy tryb uruchamiania działania to singleTask
lub singleTop
, onActivityResult
zostanie wywołany, gdy tylko działanie zostanie uruchomione z wartością zerową. Aby temu zapobiec, użyj Intent.setFlags(0)
aby zresetować domyślne flagi.
Rozpocznij aktywność
Ten przykład uruchomi DestinationActivity
z OriginActivity
.
Tutaj konstruktor Intent
przyjmuje dwa parametry:
- Kontekst jako pierwszy parametr (jest używany, ponieważ klasa Activity jest podklasą kontekstu)
- Klasa komponentu aplikacji, do którego system powinien dostarczyć zamiar (w tym przypadku działanie, które należy rozpocząć)
public class OriginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_origin);
Intent intent = new Intent(this, DestinationActivity.class);
startActivity(intent);
finish(); // Optionally, you can close OriginActivity. In this way when the user press back from DestinationActivity he/she won't land on OriginActivity again.
}
}
Innym sposobem utworzenia Intent
otwarcia DestinationActivity
jest użycie domyślnego konstruktora Intent
i użycie metody setClass()
celu poinformowania go, które działanie należy otworzyć:
Intent i=new Intent();
i.setClass(this, DestinationActivity.class);
startActivity(intent);
finish(); // Optionally, you can close OriginActivity. In this way when the user press back from DestinationActivity he/she won't land on OriginActivity
Przekazywanie danych między czynnościami
Ten przykład ilustruje wysyłając String
o wartości jako "Some data!"
od OriginActivity
do DestinationActivity
.
UWAGA: Jest to najprostszy sposób przesyłania danych między dwoma działaniami. Zobacz przykład użycia wzorca początkowego dla bardziej niezawodnej implementacji.
OriginActivity
public class OriginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_origin);
// Create a new Intent object, containing DestinationActivity as target Activity.
final Intent intent = new Intent(this, DestinationActivity.class);
// Add data in the form of key/value pairs to the intent object by using putExtra()
intent.putExtra(DestinationActivity.EXTRA_DATA, "Some data!");
// Start the target Activity with the intent object
startActivity(intent);
}
}
DestinationActivity
public class DestinationActivity extends AppCompatActivity {
public static final String EXTRA_DATA = "EXTRA_DATA";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_destination);
// getIntent() returns the Intent object which was used to start this Activity
final Intent intent = getIntent();
// Retrieve the data from the intent object by using the same key that
// was previously used to add data to the intent object in OriginActivity.
final String data = intent.getStringExtra(EXTRA_DATA);
}
}
Możliwe jest również, aby zdać inne primitive
typy danych, a także arrays
, Bundle
i Parcelable
danych. Przechodząc Serializable
jest również możliwe, ale należy unikać, ponieważ jest więcej niż trzy razy wolniej niż Parcelable
.
Serializable to standardowy interface
Java. Po prostu oznaczysz klasę jako Serializable
, implementując interface
Serializable
interface
a Java automatycznie serializuje ją w wymaganych sytuacjach.
Parcelable to interface
specyficzny dla systemu Android interface
który można zaimplementować na niestandardowych typach danych (tj. Własnych obiektach / obiektach POJO), pozwala spłaszczyć obiekt i zrekonstruować go bez potrzeby, aby miejsce docelowe musiało cokolwiek robić. Istnieje przykład dokumentacji umożliwiający nadanie obiektowi działki możliwej do połączenia .
Po parcelable
obiektu parcelable
do parcelable
możesz wysłać go jak typ pierwotny, z obiektem parcelable
:
intent.putExtra(DestinationActivity.EXTRA_DATA, myParcelableObject);
Lub w pakiecie / jako argument za fragmentem:
bundle.putParcelable(DestinationActivity.EXTRA_DATA, myParcelableObject);
a następnie przeczytaj go z celu w miejscu docelowym za pomocą getParcelableExtra:
final MyParcelableType data = intent.getParcelableExtra(EXTRA_DATA);
Lub podczas czytania fragmentu z pakietu:
final MyParcelableType data = bundle.getParcelable(EXTRA_DATA);
Po utworzeniu obiektu Serializable
możesz umieścić go w obiekcie docelowym:
bundle.putSerializable(DestinationActivity.EXTRA_DATA, mySerializableObject);
a następnie przeczytaj go z obiektu docelowego w miejscu docelowym, jak pokazano poniżej:
final SerializableType data = (SerializableType)bundle.getSerializable(EXTRA_DATA);
Wysyłać maile
// Compile a Uri with the 'mailto' schema
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
"mailto","[email protected]", null));
// Subject
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Hello World!");
// Body of email
emailIntent.putExtra(Intent.EXTRA_TEXT, "Hi! I am sending you a test email.");
// File attachment
emailIntent.putExtra(Intent.EXTRA_STREAM, attachedFileUri);
// Check if the device has an email client
if (emailIntent.resolveActivity(getPackageManager()) != null) {
// Prompt the user to select a mail app
startActivity(Intent.createChooser(emailIntent,"Choose your mail application"));
} else {
// Inform the user that no email clients are installed or provide an alternative
}
Spowoduje to wstępne wypełnienie wiadomości e-mail w aplikacji poczty wybranej przez użytkownika.
Jeśli chcesz dodać załącznik, możesz użyć Intent.ACTION_SEND
zamiast Intent.ACTION_SENDTO
. W przypadku wielu załączników możesz użyć ACTION_SEND_MULTIPLE
Uwaga: nie każde urządzenie ma dostawcę dla ACTION_SENDTO
, a wywołanie startActivity()
bez sprawdzenia za pomocą resolveActivity()
może spowodować resolveActivity()
ActivityNotFoundException.
Uzyskiwanie wyniku z innego działania
Używając startActivityForResult(Intent intent, int requestCode)
, możesz rozpocząć inne Activity
a następnie otrzymać wynik z tego Activity
w onActivityResult(int requestCode, int resultCode, Intent data)
. Wynik zostanie zwrócony jako Intent
. Intencja może zawierać dane za pośrednictwem pakietu
W tym przykładzie MainActivity
uruchomi DetailActivity
a następnie oczekuje od niego wyniku. Każdy typ żądania powinien mieć własny kod żądania int
, aby w przesłoniętej onActivityResult(int requestCode, int resultCode, Intent data)
w MainActivity
można określić, które żądanie przetworzyć, porównując wartości requestCode
i REQUEST_CODE_EXAMPLE
(choć w tym przykład jest tylko jeden).
Główna aktywność:
public class MainActivity extends Activity {
// Use a unique request code for each use case
private static final int REQUEST_CODE_EXAMPLE = 0x9345;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create a new instance of Intent to start DetailActivity
final Intent intent = new Intent(this, DetailActivity.class);
// Start DetailActivity with the request code
startActivityForResult(intent, REQUEST_CODE_EXAMPLE);
}
// onActivityResult only get called
// when the other Activity previously started using startActivityForResult
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// First we need to check if the requestCode matches the one we used.
if(requestCode == REQUEST_CODE_EXAMPLE) {
// The resultCode is set by the DetailActivity
// By convention RESULT_OK means that whatever
// DetailActivity did was executed successfully
if(resultCode == Activity.RESULT_OK) {
// Get the result from the returned Intent
final String result = data.getStringExtra(DetailActivity.EXTRA_DATA);
// Use the data - in this case, display it in a Toast.
Toast.makeText(this, "Result: " + result, Toast.LENGTH_LONG).show();
} else {
// setResult wasn't successfully executed by DetailActivity
// Due to some error or flow of control. No data to retrieve.
}
}
}
}
DetailActivity:
public class DetailActivity extends Activity {
// Constant used to identify data sent between Activities.
public static final String EXTRA_DATA = "EXTRA_DATA";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
final Button button = (Button) findViewById(R.id.button);
// When this button is clicked we want to return a result
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Create a new Intent object as container for the result
final Intent data = new Intent();
// Add the required data to be returned to the MainActivity
data.putExtra(EXTRA_DATA, "Some interesting data!");
// Set the resultCode as Activity.RESULT_OK to
// indicate a success and attach the Intent
// which contains our result data
setResult(Activity.RESULT_OK, data);
// With finish() we close the DetailActivity to
// return back to MainActivity
finish();
}
});
}
@Override
public void onBackPressed() {
// When the user hits the back button set the resultCode
// as Activity.RESULT_CANCELED to indicate a failure
setResult(Activity.RESULT_CANCELED);
super.onBackPressed();
}
}
Kilka rzeczy, o których musisz wiedzieć:
Dane są zwracane dopiero po wywołaniu
finish()
. Musisz wywołaćsetResult()
przed wywołaniemfinish()
, w przeciwnym razie wynik nie zostanie zwrócony.Upewnij się, że
Activity
nie używaandroid:launchMode="singleTask"
, czy spowoduje toActivity
do uruchomienia w osobnym zadaniem i dlatego nie otrzyma wynik z niego. Jeśli TwojeActivity
używasingleTask
jako trybu uruchamiania, natychmiastonActivityResult()
z kodem wynikuActivity.RESULT_CANCELED
.Zachowaj ostrożność podczas korzystania z
android:launchMode="singleInstance"
. Na urządzeniach wcześniejszych niż Lollipop (Android 5.0, API Level 21) Działania nie zwrócą wyniku.
- Podczas wywoływania
startActivityForResult()
można użyć jawnych lub niejawnych zamiarów. Rozpoczynając jedno z własnych działań w celu uzyskania wyniku, powinieneś użyć wyraźnej intencji, aby zapewnić oczekiwany wynik. Jednoznaczneintent
są zawsze dostarczane do celu bez względu na to, co zawiera;filter
nie jest sprawdzany. Ale niejawna intencja jest dostarczana do komponentu tylko wtedy, gdy może przejść przez jeden z filtrów komponentu.
Otwórz adres URL w przeglądarce
Otwieranie za pomocą domyślnej przeglądarki
Ten przykład pokazuje, jak można programowo otworzyć adres URL we wbudowanej przeglądarce internetowej, a nie w aplikacji. Pozwala to Twojej aplikacji na otwarcie strony internetowej bez konieczności dołączania uprawnienia INTERNET
do pliku manifestu.
public void onBrowseClick(View v) {
String url = "http://www.google.com";
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
// Verify that the intent will resolve to an activity
if (intent.resolveActivity(getPackageManager()) != null) {
// Here we use an intent without a Chooser unlike the next example
startActivity(intent);
}
}
Monitowanie użytkownika o wybranie przeglądarki
Zauważ, że w tym przykładzie użyto metody Intent.createChooser()
:
public void onBrowseClick(View v) {
String url = "http://www.google.com";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
// Note the Chooser below. If no applications match,
// Android displays a system message.So here there is no need for try-catch.
startActivity(Intent.createChooser(intent, "Browse with"));
}
W niektórych przypadkach adres URL może zaczynać się od „www” . W takim przypadku otrzymasz ten wyjątek:
android.content.ActivityNotFoundException
: Nie znaleziono działania obsługującego zamiar
Adres URL musi zawsze zaczynać się od „http: //” lub „https: //” . Dlatego kod powinien go sprawdzić, jak pokazano w poniższym fragmencie kodu:
if (!url.startsWith("https://") && !url.startsWith("http://")){
url = "http://" + url;
}
Intent openUrlIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
if (openUrlIntent.resolveActivity(getPackageManager()) != null) {
startActivity(openUrlIntent);
}
Najlepsze praktyki
Sprawdź, czy na urządzeniu nie ma aplikacji, które mogą odbierać ukryte zamiary. W przeciwnym razie aplikacja ulegnie awarii, gdy startActivity()
. Aby najpierw sprawdzić, czy aplikacja istnieje, aby otrzymać zamiar, wywołaj polecenie resolveActivity()
na obiekcie Intent. Jeśli wynik nie jest startActivity()
null, istnieje co najmniej jedna aplikacja, która może obsłużyć zamiar i można bezpiecznie wywołać startActivity()
. Jeśli wynik jest zerowy, nie należy używać zamiaru i, jeśli to możliwe, należy wyłączyć funkcję, która wywołuje zamiar.
Czyszczenie stosu działań
Czasami możesz chcieć rozpocząć nową aktywność podczas usuwania poprzednich aktywności z tylnego stosu, więc przycisk Wstecz nie zabierze Cię z powrotem do nich. Jednym z przykładów może być uruchomienie aplikacji związanej z logowaniem, która prowadzi do głównej aktywności aplikacji, ale po wylogowaniu chcesz zostać przekierowany z powrotem do loginu bez szansy na powrót. W takim przypadku możesz ustawić flagę FLAG_ACTIVITY_CLEAR_TOP
dla tego celu, co oznacza, że uruchamiane działanie jest już uruchomione w bieżącym zadaniu (LoginActivity), a następnie zamiast uruchamiania nowej instancji tego działania, wszystkie pozostałe działania na górze z tego zostanie zamknięty, a ten zamiar zostanie dostarczony do (obecnie na wierzchu) starej aktywności jako nowy zamiar.
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Możliwe jest również użycie flag FLAG_ACTIVITY_NEW_TASK
wraz z FLAG_ACTIVITY_CLEAR_TASK
jeśli chcesz wyczyścić wszystkie działania z tylnego stosu:
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
// Closing all the Activities, clear the back stack.
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Zamiar URI
Ten przykład pokazuje, jak rozpocząć zamiar z przeglądarki:
<a href="intent://host.com/path#Intent;package=com.sample.test;scheme=yourscheme;end">Start intent</a>
Ta intencja uruchomi aplikację z pakietem com.sample.test
lub otworzy Google Play z tym pakietem.
Również ten zamiar można uruchomić za pomocą javascript:
var intent = "intent://host.com/path#Intent;package=com.sample.test;scheme=yourscheme;end";
window.location.replace(intent)
W działaniu tego hosta i ścieżkę można uzyskać z zamierzonych danych:
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
Uri data = getIntent().getData(); // returns host.com/path
}
Zamierzona składnia URI:
HOST/URI-path // Optional host
#Intent;
package=[string];
action=[string];
category=[string];
component=[string];
scheme=[string];
end;
Przekazywanie wiadomości do innych komponentów
Intencji można użyć do rozsyłania wiadomości do innych komponentów aplikacji (takich jak działająca usługa w tle) lub do całego systemu Android.
Aby wysłać transmisję w aplikacji , użyj klasy LocalBroadcastManager
:
Intent intent = new Intent("com.example.YOUR_ACTION"); // the intent action
intent.putExtra("key", "value"); // data to be passed with your broadcast
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(context);
manager.sendBroadcast(intent);
Aby wysłać transmisję do komponentów poza aplikacją, użyj metody sendBroadcast()
na obiekcie Context
.
Intent intent = new Intent("com.example.YOUR_ACTION"); // the intent action
intent.putExtra("key", "value"); // data to be passed with your broadcast
context.sendBroadcast(intent);
Informacje na temat odbierania transmisji można znaleźć tutaj: Odbiornik transmisji
CustomTabsIntent dla niestandardowych kart Chrome
Korzystając z CustomTabsIntent
, można teraz skonfigurować niestandardowe karty Chrome , aby dostosować kluczowe komponenty interfejsu użytkownika w przeglądarce, która jest otwierana z Twojej aplikacji.
Jest to dobra alternatywa dla korzystania z WebView w niektórych przypadkach. Pozwala wczytać stronę internetową z zamiarem, z dodatkową możliwością wprowadzenia wyglądu przeglądarki do twojego wyglądu.
Oto przykład, jak otworzyć adres URL za pomocą CustomTabsIntent
String url = "https://www.google.pl/";
CustomTabsIntent intent = new CustomTabsIntent.Builder()
.setStartAnimations(getContext(), R.anim.slide_in_right, R.anim.slide_out_left)
.setExitAnimations(getContext(), android.R.anim.slide_in_left, android.R.anim.slide_out_right)
.setCloseButtonIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_arrow_back_white_24dp))
.setToolbarColor(Color.parseColor("#43A047"))
.enableUrlBarHiding()
.build();
intent.launchUrl(getActivity(), Uri.parse(url));
Uwaga:
Aby użyć niestandardowych kart, musisz dodać tę zależność do swojego build.gradle
compile 'com.android.support:customtabs:24.1.1'
Udostępnianie wielu plików poprzez zamiar
Lista ciągów przekazana jako parametr do metody share()
zawiera ścieżki wszystkich plików, które chcesz udostępnić.
Zasadniczo zapętla ścieżki, dodaje je do Uri i rozpoczyna działanie, które może akceptować Pliki tego typu.
public static void share(AppCompatActivity context,List<String> paths) {
if (paths == null || paths.size() == 0) {
return;
}
ArrayList<Uri> uris = new ArrayList<>();
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_SEND_MULTIPLE);
intent.setType("*/*");
for (String path : paths) {
File file = new File(path);
uris.add(Uri.fromFile(file));
}
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
context.startActivity(intent);
}
Wzór początkowy
Ten wzorzec jest bardziej rygorystycznym podejściem do rozpoczęcia Activity
. Jego celem jest poprawienie czytelności kodu, przy jednoczesnym zmniejszeniu złożoności kodu, kosztów konserwacji i łączenia komponentów.
Poniższy przykład implementuje wzorzec początkowy, który zwykle jest implementowany jako metoda statyczna na samym Activity
. Ta statyczna metoda akceptuje wszystkie wymagane parametry, konstruuje prawidłową Intent
podstawie tych danych, a następnie uruchamia Activity
.
Intent
to obiekt, który zapewnia powiązanie środowiska wykonawczego między oddzielnymi komponentami, takimi jak dwa działania. Zamiar reprezentuje „zamiar zrobienia czegoś przez aplikację”. Możesz użyć zamiarów do wielu różnych zadań, ale tutaj twoja intencja rozpoczyna inną aktywność.
public class ExampleActivity extends AppCompatActivity {
private static final String EXTRA_DATA = "EXTRA_DATA";
public static void start(Context context, String data) {
Intent intent = new Intent(context, ExampleActivity.class);
intent.putExtra(EXTRA_DATA, data);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if(!intent.getExtras().containsKey(EXTRA_DATA)){
throw new UnsupportedOperationException("Activity should be started using the static start method");
}
String data = intent.getStringExtra(EXTRA_DATA);
}
}
Ten wzorzec pozwala również na wymuszenie przekazywania dodatkowych danych z zamiarem.
Przykład ExampleActivity
można następnie uruchomić w następujący sposób, w którym context
jest kontekstem działania:
ExampleActivity.start(context, "Some data!");
Uruchom usługę niezwiązaną za pomocą zamiaru
Usługa to składnik działający w tle (w wątku interfejsu użytkownika) bez bezpośredniej interakcji z użytkownikiem. Niezwiązana usługa została właśnie uruchomiona i nie jest powiązana z cyklem życia żadnej działalności.
Aby uruchomić usługę, możesz to zrobić, jak pokazano w poniższym przykładzie:
// This Intent will be used to start the service
Intent i= new Intent(context, ServiceName.class);
// potentially add data to the intent extras
i.putExtra("KEY1", "Value to be used by the service");
context.startService(i);
Możesz użyć dowolnych dodatków od celu, używając onStartCommand()
:
public class MyService extends Service {
public MyService() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
if (intent != null) {
Bundle extras = intent.getExtras();
String key1 = extras.getString("KEY1", "");
if (key1.equals("Value to be used by the service")) {
//do something
}
}
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
Podziel się intencją
Dziel się prostymi informacjami z różnymi aplikacjami.
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));
Udostępnij obraz innym aplikacjom.
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)));
Uruchom dialer
Ten przykład pokazuje, jak otworzyć domyślny program do wybierania numerów (aplikacja, która wykonuje regularne połączenia) z już podanym numerem telefonu:
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:9988776655")); //Replace with valid phone number. Remember to add the tel: prefix, otherwise it will crash.
startActivity(intent);
Wynik działania powyższego kodu:
Otwórz mapę Google o określonej szerokości i długości geograficznej
Możesz przekazać szerokość i długość geograficzną z aplikacji do mapy Google za pomocą funkcji Intent
String uri = String.format(Locale.ENGLISH, "http://maps.google.com/maps?q=loc:%f,%f", 28.43242324,77.8977673);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(intent);
Przekazywanie różnych danych przez zamiar działania
1. Przekazywanie danych całkowitych:
SenderActivity
Intent myIntent = new Intent(SenderActivity.this, ReceiverActivity.class);
myIntent.putExtra("intVariableName", intValue);
startActivity(myIntent);
ReceiverActivity
Intent mIntent = getIntent();
int intValue = mIntent.getIntExtra("intVariableName", 0); // set 0 as the default value if no value for intVariableName found
2. Przekazywanie podwójnych danych:
SenderActivity
Intent myIntent = new Intent(SenderActivity.this, ReceiverActivity.class);
myIntent.putExtra("doubleVariableName", doubleValue);
startActivity(myIntent);
ReceiverActivity
Intent mIntent = getIntent();
double doubleValue = mIntent.getDoubleExtra("doubleVariableName", 0.00); // set 0.00 as the default value if no value for doubleVariableName found
3. Przekazywanie danych ciągu:
SenderActivity
Intent myIntent = new Intent(SenderActivity.this, ReceiverActivity.class);
myIntent.putExtra("stringVariableName", stringValue);
startActivity(myIntent);
ReceiverActivity
Intent mIntent = getIntent();
String stringValue = mIntent.getExtras().getString("stringVariableName");
lub
Intent mIntent = getIntent();
String stringValue = mIntent.getStringExtra("stringVariableName");
4. Przekazywanie danych ArrayList:
SenderActivity
Intent myIntent = new Intent(SenderActivity.this, ReceiverActivity.class);
myIntent.putStringArrayListExtra("arrayListVariableName", arrayList);
startActivity(myIntent);
ReceiverActivity
Intent mIntent = getIntent();
arrayList = mIntent.getStringArrayListExtra("arrayListVariableName");
5. Przekazywanie danych obiektu:
SenderActivity
Intent myIntent = new Intent(SenderActivity.this, ReceiverActivity.class);
myIntent.putExtra("ObjectVariableName", yourObject);
startActivity(myIntent);
ReceiverActivity
Intent mIntent = getIntent();
yourObj = mIntent.getSerializableExtra("ObjectVariableName");
Uwaga: pamiętaj, że Twoja klasa niestandardowa musi implementować interfejs
Serializable
.
6. Przekazywanie danych HashMap <Ciąg, Ciąg>:
SenderActivity
HashMap <Ciąg, Ciąg> hashMap;
Intent mIntent = new Intent(SenderActivity.this, ReceiverActivity.class);
mIntent.putExtra("hashMap", hashMap);
startActivity(mIntent);
ReceiverActivity
Intent mIntent = getIntent();
HashMap<String, String> hashMap = (HashMap<String, String>)
mIntent.getSerializableExtra("hashMap");
7. Przekazywanie danych bitmapowych:
SenderActivity
Intent myIntent = new Intent(SenderActivity.this, ReceiverActivity.class);
myIntent.putExtra("image",bitmap);
startActivity(mIntent);
ReceiverActivity
Intent mIntent = getIntent();
Bitmap bitmap = mIntent.getParcelableExtra("image");
Wyświetlanie selektora plików i czytanie wyniku
Rozpoczęcie działania Selektora plików
public void showFileChooser() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
// Update with mime types
intent.setType("*/*");
// Update with additional mime types here using a String[].
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
// Only pick openable and local files. Theoretically we could pull files from google drive
// or other applications that have networked files, but that's unnecessary for this example.
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
// REQUEST_CODE = <some-integer>
startActivityForResult(intent, REQUEST_CODE);
}
Czytanie wyniku
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// If the user doesn't pick a file just return
if (requestCode != REQUEST_CODE || resultCode != RESULT_OK) {
return;
}
// Import the file
importFile(data.getData());
}
public void importFile(Uri uri) {
String fileName = getFileName(uri);
// The temp file could be whatever you want
File fileCopy = copyToTempFile(uri, File tempFile)
// Done!
}
/**
* Obtains the file name for a URI using content resolvers. Taken from the following link
* https://developer.android.com/training/secure-file-sharing/retrieve-info.html#RetrieveFileInfo
*
* @param uri a uri to query
* @return the file name with no path
* @throws IllegalArgumentException if the query is null, empty, or the column doesn't exist
*/
private String getFileName(Uri uri) throws IllegalArgumentException {
// Obtain a cursor with information regarding this uri
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor.getCount() <= 0) {
cursor.close();
throw new IllegalArgumentException("Can't obtain file name, cursor is empty");
}
cursor.moveToFirst();
String fileName = cursor.getString(cursor.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME));
cursor.close();
return fileName;
}
/**
* Copies a uri reference to a temporary file
*
* @param uri the uri used as the input stream
* @param tempFile the file used as an output stream
* @return the input tempFile for convenience
* @throws IOException if an error occurs
*/
private File copyToTempFile(Uri uri, File tempFile) throws IOException {
// Obtain an input stream from the uri
InputStream inputStream = getContentResolver().openInputStream(uri);
if (inputStream == null) {
throw new IOException("Unable to obtain input stream from URI");
}
// Copy the stream to the temp file
FileUtils.copyInputStreamToFile(inputStream, tempFile);
return tempFile;
}
Przekazywanie obiektu niestandardowego między działaniami
Możliwe jest również przekazanie obiektu niestandardowego do innych działań za pomocą klasy Bundle
.
Istnieją dwa sposoby:
- Interfejs z możliwością
Serializable
- dla Java i Androida - Interfejs
Parcelable
- wydajność pamięci, tylko dla Androida (zalecane)
Paczka
Przetwarzanie paczkowe jest znacznie szybsze niż serializowanie. Jednym z powodów tego jest to, że mówimy wprost o procesie serializacji zamiast używać refleksji do wnioskowania. Ma również uzasadnienie, że kod został mocno zoptymalizowany do tego celu.
public class MyObjects implements Parcelable {
private int age;
private String name;
private ArrayList<String> address;
public MyObjects(String name, int age, ArrayList<String> address) {
this.name = name;
this.age = age;
this.address = address;
}
public MyObjects(Parcel source) {
age = source.readInt();
name = source.readString();
address = source.createStringArrayList();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(age);
dest.writeString(name);
dest.writeStringList(address);
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public ArrayList<String> getAddress() {
if (!(address == null))
return address;
else
return new ArrayList<String>();
}
public static final Creator<MyObjects> CREATOR = new Creator<MyObjects>() {
@Override
public MyObjects[] newArray(int size) {
return new MyObjects[size];
}
@Override
public MyObjects createFromParcel(Parcel source) {
return new MyObjects(source);
}
};
}
Wysyłanie kodu aktywności
MyObject mObject = new MyObject("name","age","Address array here");
//Passing MyOject
Intent mIntent = new Intent(FromActivity.this, ToActivity.class);
mIntent.putExtra("UniqueKey", mObject);
startActivity(mIntent);
Odbieranie obiektu w działaniu docelowym.
//Getting MyObjects
Intent mIntent = getIntent();
MyObjects workorder = (MyObjects) mIntent.getParcelable("UniqueKey");
Możesz przekazać obiekt Arraylist of Parceble jak poniżej
//Array of MyObjects
ArrayList<MyObject> mUsers;
//Passing MyObject List
Intent mIntent = new Intent(FromActivity.this, ToActivity.class);
mIntent.putParcelableArrayListExtra("UniqueKey", mUsers);
startActivity(mIntent);
//Getting MyObject List
Intent mIntent = getIntent();
ArrayList<MyObjects> mUsers = mIntent.getParcelableArrayList("UniqueKey");
Uwaga: istnieją wtyczki Android Studio, takie jak ta, umożliwiające generowanie kodu paczki
Serializowalny
Wysyłanie kodu aktywności
Product product = new Product();
Bundle bundle = new Bundle();
bundle.putSerializable("product", product);
Intent cartIntent = new Intent(mContext, ShowCartActivity.class);
cartIntent.putExtras(bundle);
mContext.startActivity(cartIntent);
Odbieranie obiektu w działaniu docelowym.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = this.getIntent().getExtras();
Product product = null;
if (bundle != null) {
product = (Product) bundle.getSerializable("product");
}
Arraylist
obiektu Serializable: taki sam jak przekazywanie pojedynczego obiektu
Obiekt niestandardowy powinien implementować interfejs Serializable
.
Uzyskiwanie wyniku z działania na fragment
Jak Pierwsze wynikają z innej działalności trzeba nazwać Fragment
„s metody startActivityForResult(Intent intent, int requestCode)
. Zauważ, że nie powinno nazywać getActivity().startActivityForResult()
jak to zajmie tył wynik do Fragment
„s dominującej Activity
.
Otrzymanie wyniku można wykonać za pomocą metody Fragment
onActivityResult()
. Musisz upewnić się, że nadrzędna aktywność fragmentu również zastępuje onActivityResult()
i wywołuje jej super
implementację.
W poniższym przykładzie ActivityOne
zawiera FragmentOne
, który uruchomi ActivityTwo
i oczekuje od niego wyniku.
ActivityOne
public class ActivityOne extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one);
}
// You must override this method as the second Activity will always send its results to this Activity and then to the Fragment
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
}
activity_one.xml
<fragment android:name="com.example.FragmentOne"
android:id="@+id/fragment_one"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Fragment Jeden
public class FragmentOne extends Fragment {
public static final int REQUEST_CODE = 11;
public static final int RESULT_CODE = 12;
public static final String EXTRA_KEY_TEST = "testKey";
// Initializing and starting the second Activity
private void startSecondActivity() {
Intent intent = new Intent(getActivity(), ActivityTwo.class);
startActivityForResult(REQUEST_CODE, intent);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE && resultCode == RESULT_CODE) {
String testResult = data.getStringExtra(EXTRA_KEY_TEST);
// TODO: Do something with your extra data
}
}
}
ActivityTwo
public class ActivityTwo extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_two);
}
private void closeActivity() {
Intent intent = new Intent();
intent.putExtra(FragmentOne.EXTRA_KEY_TEST, "Testing passing data back to ActivityOne");
setResult(FragmentOne.RESULT_CODE, intent); // You can also send result without any data using setResult(int resultCode)
finish();
}
}