Wie zeige ich den Dialog eines Dienstes an?
Android-smspopup macht genau das.
Ein Dienst erhält eine SMS und startet eine Activity
mit:
Android:theme="@Android:style/Theme.Dialog"
EDIT: Mit diesem Code wird die Dialogaktivität hier gestartet
private void notifyMessageReceived(SmsMmsMessage message) {
(...)
context.startActivity(message.getPopupIntent());
(...)
}
Mit getPopupIntent()
wie folgt deklariert (Code hier ):
public Intent getPopupIntent() {
Intent popup = new Intent(context, SmsPopupActivity.class);
popup.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
popup.putExtras(toBundle());
return popup;
}
Die Klasse SmsPopupActivity
definiert offensichtlich die Dialogaktivität. Sein erklärt wie folgt in AndroidManifest.xml
:
<activity
Android:name=".ui.SmsPopupActivity"
Android:configChanges="keyboardHidden|orientation|screenSize"
Android:launchMode="singleTask"
Android:screenOrientation="user"
Android:taskAffinity="net.everythingandroid.smspopup.popup"
Android:theme="@style/DialogTheme" >
</activity>
Ein anderer Weg ohne eine Aktivität zu verwenden:
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setTitle("Title")
.setMessage("Are you sure?")
.create();
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();
Bitte beachten Sie, dass Sie diese Berechtigung verwenden müssen:
<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW" />
Von einem Service aus können Sie auf einfache Weise ein Material Design-Dialogfeld anzeigen, in dem Sie den Fenstertyp, die Attribute und die LayoutParams bearbeiten.
In diesem Handbuch wird davon ausgegangen, dass Sie die Android AppCompat-Bibliothek verwenden.
Diese Methode benötigt die Berechtigung SYSTEM_ALERT_WINDOW Berechtigung . Normalerweise hat ein Dienst, der einen Dialog anzeigen möchte, auch einige Ansichten über die Systembenutzeroberfläche (mit der WindowManager.addView()
-Methode hinzugefügt), sodass Sie diese Berechtigungsverwendung möglicherweise bereits im Manifest deklariert haben . Wenn nicht, füge diese Zeile hinzu:
<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW" />
In Android 6.0 Marshmallow muss der Benutzer explizit zulassen, dass Ihre App "über andere Apps zeichnet" . Sie können die Systemeinstellungen Activity, die den Switch enthalten, programmgesteuert starten:
@Override
protected void onResume() {
super.onResume();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
openOverlaySettings();
}
}
@TargetApi(Build.VERSION_CODES.M)
private void openOverlaySettings() {
final Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
try {
startActivityForResult(intent, RC_OVERLAY);
} catch (ActivityNotFoundException e) {
Log.e(TAG, e.getMessage());
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case RC_OVERLAY:
final boolean overlayEnabled = Settings.canDrawOverlays(this);
// Do something...
break;
}
}
In themes.xml
können Sie dieses Design erstellen und mit den Farben Ihrer App anpassen:
<style name="AppTheme.MaterialDialogTheme" parent="Theme.AppCompat.Light.Dialog">
<item name="colorPrimary">@color/brand_primary</item>
<item name="colorPrimaryDark">@color/brand_primary_dark</item>
<item name="colorAccent">@color/brand_accent</item>
<item name="Android:windowBackground">@drawable/dialog_background_light</item>
<item name="Android:textColorPrimary">@color/primary_text_light</item>
<item name="Android:textColorSecondary">@color/secondary_text_light</item>
<item name="Android:textColorTertiary">@color/secondary_text_light</item>
</style>
In Ihrem Service:
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this, R.style.AppTheme_MaterialDialogTheme);
dialogBuilder.setTitle(R.string.dialog_title);
dialogBuilder.setMessage(R.string.dialog_message);
dialogBuilder.setNegativeButton(R.string.btn_back,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}
);
final AlertDialog dialog = dialogBuilder.create();
final Window dialogWindow = dialog.getWindow();
final WindowManager.LayoutParams dialogWindowAttributes = dialogWindow.getAttributes();
// Set fixed width (280dp) and WRAP_CONTENT height
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.copyFrom(dialogWindowAttributes);
lp.width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 280, getResources().getDisplayMetrics());
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
dialogWindow.setAttributes(lp);
// Set to TYPE_SYSTEM_ALERT so that the Service can display it
dialogWindow.setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialogWindowAttributes.windowAnimations = R.style.DialogAnimation;
dialog.show();
Die Dokumentation schlägt vor, dass Sie Benachrichtigungen verwenden sollten. Prüfen Sie erneut, warum Sie möglicherweise Dialoge verwenden müssen. Was willst du erreichen?
als Erstes müssen Sie Ihre Activity in Service umsetzen
public static Activity mactivity;
und in On erstellen Sie dies
mactivity = YourActivity.this;
und wenn wir zu Ihrem Service wechseln, erklären Sie dies auch:
YourActivity mact;
YourActivity act;
und im Create-Service ist dies unser Casting
mact = (YourActivity) act.mactivity;
und der Benachrichtigungsdialog sieht folgendermaßen aus:
AlertDialog.Builder builder = new AlertDialog.Builder(mact);
builder.setMessage(getResources().getString(R.string.string));
builder.setIcon(R.drawable.chat);
builder.setTitle(R.string.app_name);
builder.setPositiveButton(getResources().getString(R.string.Ok), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// TODO Auto-generated method stub
your message
}
});
denken Sie daran, dass mact
die Cast-Klasse ist, die im Alert Builder verwendet werden soll. Das funktioniert gut, wenn ich hoffe, es hilft.
Ich rufe das unten im Dienst an, wenn ich einen Dialog anzeigen muss.
public void ShowYesNoDialog() {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
//Yes Button Clicked
break;
case DialogInterface.BUTTON_NEGATIVE:
//No button clicked
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Did the dialog display?")
.setPositiveButton("Yes", dialogClickListener)
.setNegativeButton("No", dialogClickListener);
AlertDialog alertDialog = builder.create();
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();
}
Stellen Sie sicher, dass Sie die unten stehende Berechtigung zum Manifest hinzugefügt haben . Android.permission.SYSTEM_ALERT_WINDOW
Ich denke auch, dass der Benutzer für SDK 23 und höher explizit die Berechtigung "Zeichnen über andere Apps" vom Anwendungsmanager für die App festlegen muss, die diesen Dienst startet.
Hier ist eine ausführlichere Erklärung, wie AlertDialog
mithilfe von transluzent Activity
vom Dienst angezeigt wird, und wie einige Probleme vermieden werden.