我正在尝试为通知创建服务,该服务将在启动设备2分钟后启动(设备已启动)&将检查通知。
它也会每2分钟调用一次。基本上我试图在必要时向用户显示通知。
我在清单中写了这段代码:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.newsapp"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="internalOnly">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- For notifications /\ -->
<application
android:allowBackup="true"
android:icon="@drawable/logo"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name="com.example.newsapp.MainActivity$MyReciever"
android:enabled="true"
android:exported="true">
<!-- android:label="MyReciever"> -->
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<!-- for HTC devices /\ -->
</intent-filter>
</receiver>
<activity
android:name="com.example.newsapp.MainActivity"
android:label="@string/app_name"
android:launchMode="singleInstance"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
>
<!-- make full screen up /\ -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
这段代码用Java:
public static class NotificationService extends Service {
private WakeLock mWakeLock;
private Intent mintent;
/**
* Simply return null, since our Service will not be communicating with
* any other components. It just does its work silently.
*/
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* This is where we initialize. We call this when onStart/onStartCommand is
* called by the system. We won't do anything with the intent here, and you
* probably won't, either.
*/
private void handleIntent(Intent intent) {
// obtain the wake lock
Log.d("NotificationService", "is in handleIntent");
mintent = intent;
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "NewTag");//change the newtag
mWakeLock.acquire();
// check the global background data setting
ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
if (!cm.getBackgroundDataSetting()) {
stopSelf();
return;
}
// do the actual work, in a separate thread
new PollTask().execute(null,null,null);
}
private class PollTask extends AsyncTask<Object,Object,String> {
/**
* This is where YOU do YOUR work. There's nothing for me to write here
* you have to fill this in. Make your HTTP request(s) or whatever it is
* you have to do to get your updates in here, because this is run in a
* separate thread
*/
protected String doInBackground(Object... params) {
// do stuff!
Log.d("*************************", "is in doInBackground");
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME2);
String result1="";
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
envelope.dotNet = true;
try
{
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION2, envelope);
//Object result = (Object)envelope.getResponse(); // when calling a webmethod with parameters
SoapObject result = (SoapObject)envelope.getResponse(); // when calling a webmethod without parameters
if (result!=null)
{
PropertyInfo innerp=new PropertyInfo();
result.getPropertyInfo(0, innerp);
//SoapObject sobj=(SoapObject) result.getProperty(0);
result1= innerp.toString();
return result1;
}
else
{
}
}
catch (Exception e)
{
result1 = e.getMessage();
e.printStackTrace();
return null;
}
return null;
}
/**
* In here you should interpret whatever you fetched in doInBackground
* and push any notifications you need to the status bar, using the
* NotificationManager. I will not cover this here, go check the docs on
* NotificationManager.
*
* What you HAVE to do is call stopSelf() after you've pushed your
* notification(s). This will:
* 1) Kill the service so it doesn't waste precious resources
* 2) Call onDestroy() which will release the wake lock, so the device
* can go to sleep again and save precious battery.
*/
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
stopSelf();
if (result!=null && result.equals("true"))
{
//new doWork2().execute(null,null,null);
}
else
{
}
}
}
/**
* This is deprecated, but you have to implement it if you're planning on
* supporting devices with an API level lower than 5 (Android 2.0).
*/
@Override
public void onStart(Intent intent, int startId) {
handleIntent(intent);
}
/**
* This is called on 2.0+ (API level 5 or higher). Returning
* START_NOT_STICKY tells the system to not restart the service if it is
* killed because of poor resource (memory/cpu) conditions.
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("NotificationService*************************", "is in onStartCommand");
handleIntent(intent);
return START_NOT_STICKY;
}
/**
* In onDestroy() we release our wake lock. This ensures that whenever the
* Service stops (killed for resources, stopSelf() called, etc.), the wake
* lock will be released.
*/
public void onDestroy() {
super.onDestroy();
mWakeLock.release();
}
}
public static class MyReciever extends BroadcastReceiver {//remove static later
@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
//If this BroadcastReceiver was launched through a <receiver> tag, then the object is no longer alive after returning from this function
// TODO Auto-generated method stub
// in our case intent will always be BOOT_COMPLETED, so we can just set
// the alarm
// Note that a BroadcastReceiver is *NOT* a Context. Thus, we can't use
// "this" whenever we need to pass a reference to the current context.
// Thankfully, Android will supply a valid Context as the first parameter
target = arg0;
Log.d("BootReciever", "is in onRecieve");
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(arg0);
int minutes = prefs.getInt("interval",2);//change the 2- is the value to return if this doesn't return a value
AlarmManager am = (AlarmManager) arg0.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(arg0, NotificationService.class);//or com.example.newsapp.MainActivity.NotificationService.class
// arg0.startService(i);//lets try this
PendingIntent pi = PendingIntent.getService(arg0, 0, i, 0);
am.cancel(pi);//removes any alarm with matching intent
// by my own convention, minutes <= 0 means notifications are disabled
if (minutes > 0) {
am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + minutes*60*1000,
minutes*60*1000, pi);
Log.d("BootReciever", "minutes>0");
}
Toast.makeText(arg0, "onRecieve", Toast.LENGTH_LONG).show();
}
}
现在调用了onReceive
函数,但我的问题是NotificationService
类没有作为服务启动,我相信它没有被调用。我只想调用onStartCommand
类中的NotificationService
函数,因此它将调用handleIntent
方法&amp;然后它将通过调用Web服务方法来检查通知。
2分钟过后&amp;是时候开始NotificationService
我得到这个logcat:
02-25 11:22:30.927: D/dalvikvm(288): GC_CONCURRENT freed 1967K, 35% free 5820K/8916K, paused 87ms+10ms, total 204ms
02-25 11:22:34.319: E/ThrottleService(288): problem during onPollAlarm: java.lang.IllegalStateException: problem parsing stats: java.io.FileNotFoundException: /proc/net/xt_qtaguid/iface_stat_all: open failed: ENOENT (No such file or directory)
02-25 11:23:13.998: D/ExchangeService(603): Received deviceId from Email app: null
02-25 11:23:13.998: D/ExchangeService(603): !!! deviceId unknown; stopping self and retrying
02-25 11:23:19.067: D/ExchangeService(603): !!! EAS ExchangeService, onCreate
02-25 11:23:19.077: D/ExchangeService(603): !!! EAS ExchangeService, onStartCommand, startingUp = false, running = false
02-25 11:23:19.087: D/ExchangeService(603): !!! EAS ExchangeService, onStartCommand, startingUp = true, running = false
02-25 11:23:19.097: W/ActivityManager(288): Unable to start service Intent { act=com.android.email.ACCOUNT_INTENT } U=0: not found
02-25 11:23:19.097: D/ExchangeService(603): !!! Email application not found; stopping self
02-25 11:23:19.127: E/ActivityThread(603): Service com.android.exchange.ExchangeService has leaked ServiceConnection com.android.emailcommon.service.ServiceProxy$ProxyConnection@40d2b0e0 that was originally bound here
02-25 11:23:19.127: E/ActivityThread(603): android.app.ServiceConnectionLeaked: Service com.android.exchange.ExchangeService has leaked ServiceConnection com.android.emailcommon.service.ServiceProxy$ProxyConnection@40d2b0e0 that was originally bound here
02-25 11:23:19.127: E/ActivityThread(603): at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:969)
02-25 11:23:19.127: E/ActivityThread(603): at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:863)
02-25 11:23:19.127: E/ActivityThread(603): at android.app.ContextImpl.bindService(ContextImpl.java:1418)
02-25 11:23:19.127: E/ActivityThread(603): at android.app.ContextImpl.bindService(ContextImpl.java:1407)
02-25 11:23:19.127: E/ActivityThread(603): at android.content.ContextWrapper.bindService(ContextWrapper.java:473)
02-25 11:23:19.127: E/ActivityThread(603): at com.android.emailcommon.service.ServiceProxy.setTask(ServiceProxy.java:157)
02-25 11:23:19.127: E/ActivityThread(603): at com.android.emailcommon.service.ServiceProxy.setTask(ServiceProxy.java:145)
02-25 11:23:19.127: E/ActivityThread(603): at com.android.emailcommon.service.ServiceProxy.test(ServiceProxy.java:191)
02-25 11:23:19.127: E/ActivityThread(603): at com.android.exchange.ExchangeService$7.run(ExchangeService.java:1850)
02-25 11:23:19.127: E/ActivityThread(603): at com.android.emailcommon.utility.Utility$2.doInBackground(Utility.java:551)
02-25 11:23:19.127: E/ActivityThread(603): at android.os.AsyncTask$2.call(AsyncTask.java:287)
02-25 11:23:19.127: E/ActivityThread(603): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
02-25 11:23:19.127: E/ActivityThread(603): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
02-25 11:23:19.127: E/ActivityThread(603): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
02-25 11:23:19.127: E/ActivityThread(603): at java.lang.Thread.run(Thread.java:856)
02-25 11:23:19.127: W/ActivityManager(288): Unable to start service Intent { act=com.android.email.ACCOUNT_INTENT } U=0: not found
02-25 11:23:19.237: E/StrictMode(603): null
02-25 11:23:19.237: E/StrictMode(603): android.app.ServiceConnectionLeaked: Service com.android.exchange.ExchangeService has leaked ServiceConnection com.android.emailcommon.service.ServiceProxy$ProxyConnection@40d2b0e0 that was originally bound here
02-25 11:23:19.237: E/StrictMode(603): at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:969)
02-25 11:23:19.237: E/StrictMode(603): at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:863)
02-25 11:23:19.237: E/StrictMode(603): at android.app.ContextImpl.bindService(ContextImpl.java:1418)
02-25 11:23:19.237: E/StrictMode(603): at android.app.ContextImpl.bindService(ContextImpl.java:1407)
02-25 11:23:19.237: E/StrictMode(603): at android.content.ContextWrapper.bindService(ContextWrapper.java:473)
02-25 11:23:19.237: E/StrictMode(603): at com.android.emailcommon.service.ServiceProxy.setTask(ServiceProxy.java:157)
02-25 11:23:19.237: E/StrictMode(603): at com.android.emailcommon.service.ServiceProxy.setTask(ServiceProxy.java:145)
02-25 11:23:19.237: E/StrictMode(603): at com.android.emailcommon.service.ServiceProxy.test(ServiceProxy.java:191)
02-25 11:23:19.237: E/StrictMode(603): at com.android.exchange.ExchangeService$7.run(ExchangeService.java:1850)
02-25 11:23:19.237: E/StrictMode(603): at com.android.emailcommon.utility.Utility$2.doInBackground(Utility.java:551)
02-25 11:23:19.237: E/StrictMode(603): at com.android.emailcommon.utility.Utility$2.doInBackground(Utility.java:549)
02-25 11:23:19.237: E/StrictMode(603): at android.os.AsyncTask$2.call(AsyncTask.java:287)
02-25 11:23:19.237: E/StrictMode(603): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
02-25 11:23:19.237: E/StrictMode(603): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
02-25 11:23:19.237: E/StrictMode(603): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
02-25 11:23:19.237: E/StrictMode(603): at java.lang.Thread.run(Thread.java:856)
02-25 11:23:19.237: W/ActivityManager(288): Unbind failed: could not find connection for android.os.BinderProxy@40e43db8
02-25 11:23:19.277: D/dalvikvm(603): GC_CONCURRENT freed 358K, 17% free 2448K/2928K, paused 74ms+4ms, total 144ms
02-25 11:23:41.287: W/ActivityManager(288): Unable to start service Intent { flg=0x4 cmp=com.example.newsapp/.MainActivity$NotificationService (has extras) } U=0: not found
有什么想法吗?提前谢谢。
答案 0 :(得分:0)
这是有效的代码。它会每隔10分钟唤醒一次CPU,直到手机关机。
添加到Manifest.xml:
...
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
...
<receiver android:process=":remote" android:name="Alarm"></receiver>
...
代码:
package YourPackage;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.widget.Toast;
public class Alarm extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
// Put here YOUR code.
Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example
wl.release();
}
public void SetAlarm(Context context)
{
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, Alarm.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 10, pi); // Millisec * Second * Minute
}
public void CancelAlarm(Context context)
{
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
从服务设置闹钟:
package YourPackage;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
public class YourService extends Service
{
Alarm alarm = new Alarm();
public void onCreate()
{
super.onCreate();
}
public void onStart(Context context,Intent intent, int startId)
{
alarm.SetAlarm(context);
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
}
如果您想在电话启动时重复设置警报:
添加Manifest.xml的权限:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
...
<receiver android:name=".AutoStart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
...
创建新课程:
package YourPackage;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class AutoStart extends BroadcastReceiver
{
Alarm alarm = new Alarm();
@Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
alarm.SetAlarm(context);
}
}
}
请注意这样一个事实,即在启动时资源是高度争用的,因此您应该等待一段时间而不是解雇服务。