Comment afficher une boîte de dialogue à partir d'un service?
Android-smspopup fait exactement cela.
Un service reçoit un sms et commence une Activity
avec:
Android:theme="@Android:style/Theme.Dialog"
EDIT: L'activité de dialogue est lancée ici avec ce code
private void notifyMessageReceived(SmsMmsMessage message) {
(...)
context.startActivity(message.getPopupIntent());
(...)
}
Avec getPopupIntent()
déclaré comme suit (code ici ):
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;
}
SmsPopupActivity
class définit évidemment l'activité de dialogue. Sa déclaré comme suit dans 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>
Une autre manière sans utiliser une activité:
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setTitle("Title")
.setMessage("Are you sure?")
.create();
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();
Veuillez noter que vous devez utiliser cette autorisation:
<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW" />
À partir d'un service, vous pouvez facilement afficher une boîte de dialogue de style Material Design manipulant son type de fenêtre, ses attributs et ses LayoutParams.
Ce guide suppose que vous utilisez Android AppCompat libray.
Cette méthode nécessite le paramètre SYSTEM_ALERT_WINDOW permission . Généralement, un service qui souhaite afficher un dialogue a également des vues dessinées sur l'interface utilisateur du système (ajoutées à l'aide de la méthode WindowManager.addView()
), de sorte que vous avez peut-être déjà déclaré cette autorisation dans votre manifeste. . Sinon, ajoutez cette ligne:
<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW" />
Dans Android 6.0 Marshmallow , l'utilisateur doit autoriser explicitement votre application à "dessiner par-dessus d'autres applications" . Vous pouvez démarrer par programme les paramètres du système Activité qui contient le commutateur:
@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;
}
}
Dans themes.xml
, créez ce thème et personnalisez-le avec les couleurs de votre application:
<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>
Dans votre 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();
La documentation suggère que vous devriez utiliser les notifications. Réévaluez pourquoi vous pourriez avoir besoin d'utiliser des boîtes de dialogue. Qu'essayez-vous de réaliser?
pour commencer, vous devez lancer votre activité dans Service Ainsi, dans votre activité, ajoutez
public static Activity mactivity;
et dans Sur créer ajouter ceci
mactivity = YourActivity.this;
et quand nous passons à votre service, alse le déclare:
YourActivity mact;
YourActivity act;
et en créer un service c'est notre casting
mact = (YourActivity) act.mactivity;
et le dialogue d'alerte ressemblera à ceci:
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
}
});
n'oubliez pas que mact
est la classe de composition à utiliser dans Alert Builder ... cela fonctionne bien pour moi. J'espère que cela vous aidera.
J'appelle le ci-dessous, à l'intérieur du service lorsque je dois afficher une boîte de dialogue.
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();
}
Assurez-vous que la permission ci-dessous est ajoutée au manifeste . Android.permission.SYSTEM_ALERT_WINDOW
Je pense également que pour le SDK 23 et les versions ultérieures, l'utilisateur doit explicitement définir l'autorisation "Dessiner sur d'autres applications" du gestionnaire d'applications pour l'application qui démarre ce service.
Ici explique en détail comment afficher AlertDialog
à partir du service en utilisant translucent Activity
et comment éviter certains problèmes.