部分2持久前景的Andr​​oid服务,通过用户界面开始,工作在休眠模式下也一样,也开始在手机重启 [英] part-2 persistent foreGround android service that starts by UI, works at sleep mode too, also starts at phone restart

查看:169
本文介绍了部分2持久前景的Andr​​oid服务,通过用户界面开始,工作在休眠模式下也一样,也开始在手机重启的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

状态:真的很感谢所有的谁帮,并在这里指导和部分-1! 我做了code 出于研究和帮助给予和已经把该工作code在EDIT-1 。批评是欢迎,使code更好。

Status: Really thankful to all who helped and guided here and in part-1! I have made code out of research and help given and have put that working code in EDIT-1. Criticisms are welcomed to make the code better.

方案:

Scenario:

我问的问题提及部分-1,但由于某些原因,我能持续的无法让设计正确的策略与code,有<强>真正的整合和理智。

I asked the question mention in Part-1, but for some reason I can persistently cannot make a design and correct strategy with code that has true integration and sanity.

这是一个冗长的问题问题答案本来是缔结或者只是一个敲定插曲,所以我做了这个第二部分作为大纲。

It was a lengthy question and the question nor answer could have been concluded or finalized in just one episode, so I have made this second part as a synopsis.

可能是我无能,或只是干扰读了这么多scatered文档和不同的策略的答案,或者答案有不同的看法/编码风格。

May be I am incompetent or just disturbed reading so much scatered documentations and answers of different strategies, or answers are of different views/coding styles.

部分-1 <一个href="http://stackoverflow.com/questions/17005837/persistent-foreground-android-service-that-starts-by-ui-works-at-sleep-mode-too">part-1持续的前景机器人服务,通过用户界面开始,工作在休眠模式下也一样,也开始在手机重启

问:

Question:

下面有我想要的东西,观察不同的答案后,终于得出结论:

Heres what I wanted and had finally concluded after observing different answers:

需要的运行code每15分钟再予甚至当手机的在睡眠)。 那就需要唤醒锁我觉得呢?

Need to run code every 15 minuts (even when phone is at sleep). Would need wake locks I think?

            //AT boot, check shared preferences to see boolean "serviceEnabled"?
                    //if true, set alarm manager to run a service every 15 minuts.
                    //if false, do nothing.

            //On "enable" button clicked.
                    //make "serviceEnabled" boolean true in shared preferences.
                    //start alarm manager to run a service every 15 minuts.

            //on "Disable" button clicked.
                    //make "serviceEnabled" boolean false in shared preferences.
                    //stop alarm manager and deregister it to run ever.

任何一个可以COM prehensively告诉...什么code,我应该使用...? 我谦卑地感谢满研究的一个头痛的问题。

Can any one comprehensively tell... what code should I use...? I am humbly thanks full with a headache of research.

要求:

Requests:

请只回答,如果你自信,有经验的知道自己在做什么。

Please only answer if you confidently and with experience know what you are doing.

编辑-1启动:

EDIT-1-Start:

这是我到目前为止做出。请随意发表评论或批评。

这是在启动运行的足球运动员的类​​。

Booter class that runs on boot.

public class Booter extends BroadcastReceiver {

      public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
          Log.e("boot-status","BOOT_COMPLETED=================================================");
        //  SharedPreferences prefs = context.getSharedPreferences("$MYPACKAGE_preferences",0);
        //  if (prefs.getBoolean("startatboot",false)) {
        if(true){
        Intent updateIntent = new Intent();
        updateIntent.setClass(context, TheService.class);

        PendingIntent pendingIntent = PendingIntent.getService(context, 0, updateIntent, 0);
        AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, java.lang.System.currentTimeMillis()+5000,5000, pendingIntent);

        }
        }
      }


}

服务类

public class TheService extends Service{

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }
    PowerManager pm;
    PowerManager.WakeLock wl;
    @Override

      public int onStartCommand(Intent intent, int flags, int startId) {

        pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
        wl.acquire();


        startForeground(1, new Notification());

            ////// will do all my stuff here on in the method onStart() or onCreat()?

        Log.e("app-status","ping ====================================================");

        new Thread(new Runnable() {

            @Override
            public void run() {
                wl.release();
                stopSelf(); 
            }
        }).start();


        return START_STICKY;    
    }

    @Override
      public void onDestroy() {
        stop();
      }

    public void stop(){
        //if running
        // stop
        // make vars as false
        // do some stopping stuff
        stopForeground(true);


    }





}

GUI启动/停止

GUI to start / stop

public class SettingsActivity extends Activity {
  // some code to initialize things

    buttonStop.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent updateIntent = new Intent();
        updateIntent.setClass(SettingsActivity.this, TheService.class);

        PendingIntent pendingIntent = PendingIntent.getService(SettingsActivity.this, 0, updateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager)SettingsActivity.this.getSystemService(Context.ALARM_SERVICE);
        alarmManager.cancel(pendingIntent);
        //make sharepred boolean as false

        }
    });

    buttonStart.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent updateIntent = new Intent();
        updateIntent.setClass(SettingsActivity.this, TheService.class);

        PendingIntent pendingIntent = PendingIntent.getService(SettingsActivity.this, 0, updateIntent, 0);
        AlarmManager alarmManager = (AlarmManager)SettingsActivity.this.getSystemService(Context.ALARM_SERVICE);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, java.lang.System.currentTimeMillis()+5000,5000, pendingIntent);
        //make shared prefs boolean as true

        }
    });

Menifiest

Menifiest

  <?xml version="1.0" encoding="utf-8"?>
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.myapp"
      android:versionCode="1"
      android:versionName="1.0" >

      <uses-sdk
      android:minSdkVersion="10"
      android:targetSdkVersion="17" />

      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> // irrelevent here
      <uses-permission android:name="android.permission.INTERNET" />        // my app uses these though in service class.
      <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
      <uses-permission android:name="android.permission.WAKE_LOCK" />

      <application

      android:allowBackup="true"
      android:debuggable="true"
      android:icon="@drawable/ic_launcher"
      android:label="@string/app_name"
      android:theme="@style/AppTheme" >
      <activity
          android:name="com.example.myapp.MainActivity"
          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.myapp.SettingsActivity"
          android:label="@string/title_activity_settings" >
      </activity>

      <service android:name=".TheService" />
      <receiver android:name=".Booter" >
          <intent-filter>
          <action android:name="android.intent.action.BOOT_COMPLETED" />
          <category android:name="android.intent.category.HOME" />
          </intent-filter>
      </receiver>

      </application>

  </manifest>

编辑-1-END。

EDIT-1-END.

推荐答案

如果你只需要运行这个code每15分钟。那么你真的不需要保持服务的全天候运行。真的,不这样做,这是坏主意。你需要做的是这样的:

If you only need to run this code every 15 minutes. then you really don't need to keep the service running 24/7. Really, don't do it, it is bad idea. what you need to do is this:

  1. 使用AlarmManager安排警报每隔15分钟。此报警,然后用钓到一个BroadcastReceiver。该报警的已被RTC_WAKE_UP ,以便它唤醒了电话,如果它是在深睡眠,它必须是实时的,因为它会使用深度睡眠定时器。

  1. Use AlarmManager to schedule an alarm every 15 minutes. this alarm is then catched with a BroadcastReceiver. This alarm HAS TO BE RTC_WAKE_UP so that it wakes the phone up if it is in deep sleep and it has to be real time since it will use the deep sleep timer.

广播接收器将启动服务。现在这个调用的服务是这样做的:

Broadcast receiver will have to start a service. now this call to the service has to be done like this:

  • 2.1挡在了BroadcastReceiver一个wakelock和收购()吧。
  • 2.2开始的 IntenetService (这种类型的服务开始和结束自己的工作完成后)
  • 2.3版本的wakelock 在服务
  • 2.1 get a wakelock in the BroadcastReceiver and acquire() it.
  • 2.2 start a IntenetService (This type of services start and end themselves after work is done)
  • 2.3 release the wakelock in the service

还有就是如何在这里实现一个很好的例子: commonsware的WakefulIntentService 。你不必把它当作是,你可以使自己的服务和广播接收器。只要记住调用服务并将其释放时,该服务完成之前获得锁,否则该服务可能不会被调用。

There is a good example of how to implement this here: commonsware's WakefulIntentService. You don't have to use it as is, you can make your own service and broadcast receiver. Just remember to acquire the lock before calling the service and releasing it when the service is done, otherwise the service might not get called.

  1. 您的服务做什么,你要执行的每个15分钟。然后,你可以重新安排在15分钟另一个电话。你也可以检查执行服务时,并重新安排前,通过共享preferences启用。

至于你的活动控制您的服务:

As for your activity controlling your service:

  1. 当按钮为pressed检查共享preference状态并保存相反。
  2. 然后发送一个广播给你相同的接收器启动,如果他们已经启用了它的服务(或计划购买)。
  3. 如果是禁用,则取消任何时间表的服务。

至于你开机的要求:

  1. 在声明中您的清单即启动您的服务相同的接收器被调用时的动作android.intent.action.BOOT_COMPLETED被调用。
  2. 在声明权限:android.permission.RECEIVE_BOOT_COMPLETED

这是例子清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.yourcompany.yourapp"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="17" />

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <application
        android:allowBackup="false"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <activity
            android:name="com.yourcompany.yourapp.activities.HomeActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name="com.yourcompany.yourapp.services.ActionHandlerService" />
        <receiver android:name="com.yourcompany.yourapp.receivers.BootReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <category android:name="android.intent.category.HOME" />
            </intent-filter>
        </receiver>

    </application>
</manifest>

取消的实例和调度报警:

Example of cancelling and scheduling alarms:

public synchronized static void disableTimers(final Context context)
{
  Log.i(TAG, "Canceling Alarms");
  final Intent in = new Intent(Constants.Actions.TIMER_ACTION);
  final PendingIntent pi = PendingIntent.getBroadcast(context, 0, in, PendingIntent.FLAG_UPDATE_CURRENT);
  ((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).cancel(pi);
}

public synchronized static void enableTimer(final Context context)
{
  Log.i(TAG, "Enabling Alarm");
  final Intent in = new Intent(Constants.Actions.TIMER_ACTION);
  final PendingIntent pi = PendingIntent.getBroadcast(context, 0, in, PendingIntent.FLAG_UPDATE_CURRENT);
  ((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + FIFTEEN_MINUTES, pi);
}

启动该服务在启动时的例子:

Example of starting the service on boot up:

@Override
public void onReceive(final Context context, final Intent intent)
{
  final Intent in = new Intent(context, MyService.class);
  in.setAction(Actions.BOOT_RECEIVER_ACTION);
  Log.i(TAG, "Boot completed. Starting service.");
  MyService.acquireLock();
  context.startService(in);
}

和对服务解除锁定

private static volatile WakeLock mStaticWakeLock = null;

private synchronized static WakeLock getLock(final Context context)
{
  if (mStaticWakeLock == null)
  {
    final PowerManager mgr = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    mStaticWakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_PARAMETER);
    mStaticWakeLock.setReferenceCounted(true);
  }
  return mStaticWakeLock;
}

@Override
protected final void onHandleIntent(final Intent intent)
{
  try
  {
    run(intent);
  }
  finally
  {
    final WakeLock lock = getLock(getApplicationContext());
    if (lock.isHeld())
    {
      lock.release();
      Log.i(TAG, "Releasing WakeLock");
    }
  }
}

就是这样。

这篇关于部分2持久前景的Andr​​oid服务,通过用户界面开始,工作在休眠模式下也一样,也开始在手机重启的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆