Mit Service den Hintergrund ausführen und Benachrichtigungen erstellen
Ich möchte, dass meine app zu starten-Dienst, wenn die Schaltfläche geklickt wird, und der Dienst sollte im hintergrund laufen, um zu zeigen, eine Benachrichtigung zu einem bestimmten Zeitpunkt des Tages. Ich habe den folgenden code, um dies zu tun. Aber es zeigt Fehler, die ich nicht verstehe. Ich bin neu auf Android und dies ist meine erste app mit Service. Jede Hilfe würde geschätzt werden. Vielen Dank im Voraus.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.newtrial"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.newtrial.CreateNotificationActiviy"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.newtrial.ResultActivity"
android:label="@string/title_activity_result" >
</activity>
<service android:enabled="true" android:name=".UpdaterServiceManager" />
</application>
</manifest>
CreateNotificationActiviy.java
package com.example.newtrial;
import android.os.Bundle;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class CreateNotificationActiviy extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.create_notification_activiy);
Button b=(Button)findViewById(R.id.button1);
b.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
//TODO Auto-generated method stub
startService(new Intent(CreateNotificationActiviy.this, UpdaterServiceManager.class));
}
});
}
public void createNotification(View view) {
//Prepare intent which is triggered if the
//notification is selected
Intent intent = new Intent(this, ResultActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
//Build notification
//Actions are just fake
Notification noti = new Notification.Builder(this)
.setContentTitle("Notification Title")
.setContentText("Click here to read").setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//hide the notification after its selected
noti.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, noti);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.create_notification_activiy, menu);
return true;
}
}
UpdaterServiceManager.java
package com.example.newtrial;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
public class UpdaterServiceManager extends Service {
private final int UPDATE_INTERVAL = 60 * 1000;
private Timer timer = new Timer();
private static final int NOTIFICATION_EX = 1;
private NotificationManager notificationManager;
CreateNotificationActiviy not;
public UpdaterServiceManager() {
not=new CreateNotificationActiviy();
}
@Override
public IBinder onBind(Intent intent) {
//TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
//code to execute when the service is first created
super.onCreate();
Log.i("MyService", "Service Started.");
showNotification();
}
public void showNotification()
{
final Calendar cld = Calendar.getInstance();
int time = cld.get(Calendar.HOUR_OF_DAY);
if(time>12)
{
not.createNotification(null);
}
else
{
AlertDialog.Builder alert=new AlertDialog.Builder(this);
alert.setMessage("Not yet");
alert.setTitle("Error");
alert.setPositiveButton("OK", null);
alert.create().show();
}
}
@Override
public void onDestroy() {
if (timer != null) {
timer.cancel();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startid)
{
return START_STICKY;
}
private void stopService() {
if (timer != null) timer.cancel();
}
}
ResultActivity.java
package com.example.newtrial;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
public class ResultActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result);
TextView tv=(TextView)findViewById(R.id.textView1);
tv.setText("After notification is clicked" );
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.result, menu);
return true;
}
}
Logcat
12-10 12:14:04.286: I/Process(872): Sending signal. PID: 872 SIG: 9
12-10 12:14:11.774: I/MyService(893): Service Started.
12-10 12:14:12.094: D/AndroidRuntime(893): Shutting down VM
12-10 12:14:12.094: W/dalvikvm(893): threadid=1: thread exiting with uncaught exception (group=0x414c4700)
12-10 12:14:12.124: E/AndroidRuntime(893): FATAL EXCEPTION: main
12-10 12:14:12.124: E/AndroidRuntime(893): java.lang.RuntimeException: Unable to create service com.example.newtrial.UpdaterServiceManager: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
12-10 12:14:12.124: E/AndroidRuntime(893): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2587)
12-10 12:14:12.124: E/AndroidRuntime(893): at android.app.ActivityThread.access$1600(ActivityThread.java:141)
12-10 12:14:12.124: E/AndroidRuntime(893): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1338)
12-10 12:14:12.124: E/AndroidRuntime(893): at android.os.Handler.dispatchMessage(Handler.java:99)
12-10 12:14:12.124: E/AndroidRuntime(893): at android.os.Looper.loop(Looper.java:137)
12-10 12:14:12.124: E/AndroidRuntime(893): at android.app.ActivityThread.main(ActivityThread.java:5103)
12-10 12:14:12.124: E/AndroidRuntime(893): at java.lang.reflect.Method.invokeNative(Native Method)
12-10 12:14:12.124: E/AndroidRuntime(893): at java.lang.reflect.Method.invoke(Method.java:525)
12-10 12:14:12.124: E/AndroidRuntime(893): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
12-10 12:14:12.124: E/AndroidRuntime(893): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
12-10 12:14:12.124: E/AndroidRuntime(893): at dalvik.system.NativeStart.main(Native Method)
12-10 12:14:12.124: E/AndroidRuntime(893): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
12-10 12:14:12.124: E/AndroidRuntime(893): at android.view.ViewRootImpl.setView(ViewRootImpl.java:563)
12-10 12:14:12.124: E/AndroidRuntime(893): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:269)
12-10 12:14:12.124: E/AndroidRuntime(893): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
12-10 12:14:12.124: E/AndroidRuntime(893): at android.app.Dialog.show(Dialog.java:281)
12-10 12:14:12.124: E/AndroidRuntime(893): at com.example.newtrial.UpdaterServiceManager.showNotification(UpdaterServiceManager.java:65)
12-10 12:14:12.124: E/AndroidRuntime(893): at com.example.newtrial.UpdaterServiceManager.onCreate(UpdaterServiceManager.java:41)
12-10 12:14:12.124: E/AndroidRuntime(893): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2577)
12-10 12:14:12.124: E/AndroidRuntime(893): ... 10 more
Kommentar zu dem Problem
Sie können nicht erstellen Sie ein gültiges
Aktivität
mit new
selbst. Ansonsten Duplikat von stackoverflow.com/questions/1207269/... InformationsquelleAutor der Frage user2648852 | 2013-12-10
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die Frage ist relativ alt, aber ich hoffe, dass dieser post noch relevant sein könnte für andere.
TL;DR: verwenden AlarmManager um einen task zu planen, verwenden Sie IntentService, siehe Beispiel-code hier;
Was dieser test-Anwendung(und Unterricht):
Einfache helloworld-app, die sendet Sie die Meldung alle 2 Stunden. Ein Klick auf die Benachrichtigung, öffnet sich die sekundären Aktivitäten werden in der app; löschen von Mitteilung tracks.
Wann sollten Sie es verwenden:
Sobald Sie ausführen müssen einige Aufgaben nach einem Zeitplan.
Mein eigener Fall: einmal ein Tag, ich möchte zu Holen, neue Inhalte vom server, verfassen Sie eine Mitteilung auf der Grundlage der Inhalte, die ich bekam, und zeigen Sie auf Benutzer.
, Was zu tun ist:
Erstellen wir als erstes 2 Aktivitäten: MainActivity, die beginnt notification-service und NotificationActivity, die gestartet werden, indem Sie auf die Benachrichtigung:
activity_main.xml
MainActivity.java
und NotificationActivity ist jede beliebige Aktivität, die Sie mit oben kommen kann. NB! Vergessen Sie nicht, fügen Sie beide Tätigkeiten in AndroidManifest.
Dann erstellen wir
WakefulBroadcastReceiver
broadcast receiver, rief ich NotificationEventReceiver im code oben.Hier werden wir
AlarmManager
FeuerPendingIntent
alle 2 Stunden (oder mit einer anderen Frequenz), und geben Sie die behandelten Aktionen dieser Absicht inonReceive()
Methode. In unserem Fall - wakefully startIntentService
, die wir angeben werden, die in den späteren Schritten. DieseIntentService
würde generieren Benachrichtigungen für uns.Auch, dass dieser receiver enthält einige helper-Methoden, wie das erstellen von PendintIntents, die wir später verwenden werden
NB1! Als ich bin mit
WakefulBroadcastReceiver
, ich muss hinzufügen, extra-Erlaubnis in mein manifest:<uses-permission android:name="android.permission.WAKE_LOCK" />
NB2! Ich benutze es Wachen version von broadcast-receiver, wie ich will, um sicherzustellen, dass das Gerät nicht zu gehen Sie zurück zu schlafen, während mein
IntentService
's Betrieb. In der Hallo-Welt-es ist nicht so wichtig (wir haben keine lang andauernden Betrieb in unserem Dienst, aber stellen Sie sich vor, wenn Sie zu Holen, relativ große Dateien vom server während dieses Vorgangs). Lesen Sie mehr über das Gerät Wach hier.NotificationEventReceiver.java
Nun erstellen wir eine
IntentService
tatsächlich Benachrichtigungen erstellen.Gibt es, wir geben Sie
onHandleIntent()
die Antworten auf NotificationEventReceiver's Absicht passierten wir instartWakefulService
Methode.Wenn es die Löschen-Aktion - wir melden es unserer Analysen, zum Beispiel. Wenn es zu Start-Meldung Absicht - dann mit
NotificationCompat.Builder
wir Komponieren neue Meldung und zeigt es durchNotificationManager.notify
. Beim verfassen der Mitteilung, wir sind auch Einstellung pending intents für klicken Sie auf und entfernen von Aktionen. Ziemlich Einfach.NotificationIntentService.java
Fast fertig. Jetzt Stell ich auch broadcast-receiver für BOOT_COMPLETED, TIMEZONE_CHANGED, und TIME_SET Ereignisse zu re-setup meine AlarmManager, einmal Gerät neu gestartet wurde oder die Zeitzone geändert hat (Zum Beispiel, Benutzer-geflogen aus den USA nach Europa und Sie nicht wollen, Benachrichtigung, pop-up, in der Mitte der Nacht, aber war klebrig, um die lokale Zeit 🙂 ).
NotificationServiceStarterReceiver.java
Müssen wir auch registrieren, alle unsere services, broadcast Receiver in der AndroidManifest:
Das ist es!
Den Quellcode für dieses Projekt finden Sie hier. Ich hoffe, Sie finden diesen Beitrag hilfreich.
InformationsquelleAutor der Antwort Konstantin Loginov
Ihre Fehler in UpdaterServiceManager in der onCreate-und showNotification-Methode.
Sind Sie versuchen zu zeigen
notification
ausService using Activity Context
. In der Erwägung, dassEvery Service has its own Context,
benutzen Sie einfach die, dass. Sie brauchen nicht zupass a Service an Activity's Context.
ich sehe nicht ein, warum Sie einem bestimmtenActivity's Context to show Notification.
Setzen Sie Ihre createNotification Methode in UpdateServiceManager.class. Und entfernen CreateNotificationActivity nicht vom Service.
InformationsquelleAutor der Antwort Nepster