2016-12-20 9 views
1

Я работаю на приложение, которое тест состояния на сервере каждые 15 мин и толчок уведомление, я использовал Alarm Manager, broadcast receiver & Intent Service. все прекрасно работало, и я получаю это состояние с сервера отлично, когда приложение работает или в фоновом режиме, пока я не удалил его из последних приложений, каждая вещь останавливается и не может получить это состояние с сервера. Я искал ... и ничего не получаю, но мой друг скажет мне, что я должен зарегистрировать свой broadcast receiver в создании класса продлить из приложения.Broadcast приемник зарегистрироваться в на создание класса простираться от применения

Я не знаю, как это сделать .. так что мне нужна помощь, пожалуйста,

Основная деятельность Класс

public class MainActivity extends AppCompatActivity { 

    static TextView TvText; 
    Button Btn11, Btn22; 
    AlarmManager alarm; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     supportRequestWindowFeature(Window.FEATURE_NO_TITLE); 
     setContentView(R.layout.activity_main); 

     alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); 

     TvText = (TextView) findViewById(R.id.tv_Text); 
     Btn11 = (Button) findViewById(R.id.btn_11); 
     Btn22 = (Button) findViewById(R.id.btn_22); 
     Btn22.setEnabled(false); 
    } 

    public void Btn11OC(View view) { 
     scheduleAlarm(); 
     Btn11.setEnabled(false); 
     Btn22.setEnabled(true); 
    } 

    public void Btn22OC(View view) { 
     if (alarm!= null) { 
      cancelAlarm(); 
     } 
     Btn11.setEnabled(true); 
     Btn22.setEnabled(false); 
    } 

    // Setup a recurring alarm every half hour 
    public void scheduleAlarm() { 
     // Construct an intent that will execute the AlarmReceiver 
     Intent intent = new Intent(getApplicationContext(), broadtest.class); 
     intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 
     // Create a PendingIntent to be triggered when the alarm goes off 
     final PendingIntent pIntent = PendingIntent.getBroadcast(this, broadtest.REQUEST_CODE, 
      intent, PendingIntent.FLAG_UPDATE_CURRENT); 
     // Setup periodic alarm every 5 seconds 
     alarm.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 
      900000L, pIntent); 
    } 

    public void cancelAlarm() { 
     Intent intent = new Intent(getApplicationContext(),  broadtest.class); 
     intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 
     final PendingIntent pIntent = PendingIntent.getBroadcast(this, broadtest.REQUEST_CODE, 
      intent, PendingIntent.FLAG_UPDATE_CURRENT); 
     alarm.cancel(pIntent); 
    } 
} 

вразброс приемник

public class broadtest extends WakefulBroadcastReceiver { 
    public static final int REQUEST_CODE = 12345; 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     Intent i = new Intent(context, MyService.class); 
     context.startService(i); 
    } 
} 

AppController Класс

public class AppController extends Application { 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

    } 
} 

MyService класс

public class MyService extends IntentService { 
    static int NOTIFICATION_ID = 0; 

    public MyService() { 
     super("MyService"); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     String url = "http://test.com/testts.php"; 
     // Tag used to cancel the request 
     String tag_string_req = "string_req"; 

     StringRequest strReq = new StringRequest(Request.Method.GET, 
      url, new Response.Listener<String>() { 

      @Override 
      public void onResponse(String response) { 
       Log.d("Volley Log", response); 
       Toast.makeText(MyService.this, response, Toast.LENGTH_SHORT).show(); 
       if (response.equals("0")){ 
        sendNotification("Titel Test 1111", "Body Test 1111"); 
       }else if (response.equals("1")){ 
        sendNotification("Titel Test 2222", "Body Test 2222"); 
       }else { 
        sendNotification("Titel Test 3333", "Body Test 3333"); 
       } 
      } 
     }, new Response.ErrorListener() { 

      @Override 
      public void onErrorResponse(VolleyError error) { 
       Toast.makeText(MyService.this, error.toString(), Toast.LENGTH_SHORT).show(); 
       VolleyLog.d("Volley Log", "Error: " + error.getMessage()); 
      } 
     }); 
     // Adding request to request queue 
     int socketTimeout = 30000;//30 seconds - change to what you want 
     RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, 
       DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT); 
     strReq.setRetryPolicy(policy); 
     AppController.getInstance().addToRequestQueue(strReq, tag_string_req); 
     // Setup periodic alarm every 5 seconds 
    } 

    private void sendNotification(String title, String messageBody) { 
     long[] pattern = {500,500,500,500,500,500,500,500,500}; 
     Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 
     NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) 
      .setSmallIcon(R.mipmap.ic_launcher) 
      .setContentTitle(title) 
      .setContentText(messageBody) 
      .setAutoCancel(true) 
      .setSound(alarmSound) 
      .setLights(Color.BLUE, 500, 500) 
      .setVibrate(pattern); 

     NotificationManager notificationManager = 
      (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 

     if (NOTIFICATION_ID > 1073741824) { 
      NOTIFICATION_ID = 0; 
     } 
     notificationManager.notify(NOTIFICATION_ID++, notificationBuilder.build()); 
    } 
} 

Manifest.xml

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

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.WAKE_LOCK" /> 

<application 
    android:name=".AppController" 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 
    <activity android:name=".MainActivity"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

    <receiver 
     android:name=".broadtest" 
     android:process=":remote"> 
    </receiver> 

    <service 
     android:name=".MyService" 
     android:exported="false"> 
    </service> 
</application> 

+1

где ваш манифест Android? –

+0

Извините ... я пишу сейчас –

+1

Почему вы используете приемник/услугу в другом процессе? Разрешены ли разрешения? –

ответ

1

Вам необходимо запустить службу в качестве переднего плана обслуживания. Когда вы очищаете приложение из списка недавних убивает службу

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

     NotificationCompat.Builder builder = new NotificationCompat.Builder(this); 

     builder.setSmallIcon(R.drawable.ic_notification) 
       .setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), 
         R.mipmap.ic_launcher)) 
       .setContentTitle("WhatsApp Reminder Service.") 
       .setContentText("Touch to configure."); 

     Intent startIntent = new Intent(getApplicationContext(), MainActivity.class); 

     PendingIntent pendingIntent = PendingIntent.getActivity(this, 965778, startIntent, 0); 

     builder.setContentIntent(pendingIntent); 

     startForeground(965778, builder.build()); 

     return START_REDELIVER_INTENT; 
} 

Необходимо создать уведомление при использовании переднего плана обслуживания. Надеюсь, это поможет.

Я вижу, вы использовали IntentService см ответ на этот вопрос Using startForeground() with an Intent Service

0

Чтобы запустить процесс на устройстве, когда пользователи не особенно взаимодействие с приложением.

шаги будут включать в себя:

1.Updating вашего Android манифест XML

2.СОЗДАНИЕ широковещательных приемников для прослушивания соответствующих событий

3.Set вверх фоновой службы для контекста, когда ваши приложение не работает

Android menifest.XML

<?xml version="1.0" encoding="utf-8"?> 

<uses-permission ... /> 

<application 
    android:name=".MyApplication" 
    ... > 

    <receiver android:name=".receivers.PeriodicTaskReceiver"> 
     <intent-filter> 
      <action android:name="com.example.app.PERIODIC_TASK_HEART_BEAT" /> 
     </intent-filter> 
    </receiver> 

    <service android:name=".services.BackgroundService" /> 

    ... 
</application> 

Теперь для приемника Broadcast

public class PeriodicTaskReceiver extends BroadcastReceiver { 

    private static final String TAG = "PeriodicTaskReceiver"; 
    private static final String INTENT_ACTION = "com.example.app.PERIODIC_TASK_HEART_BEAT"; 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     if (!Strings.isNullOrEmpty(intent.getAction())) { 
      MyApplication myApplication = (MyApplication) context.getApplicationContext(); 
      SharedPreferences sharedPreferences = myApplication.getSharedPreferences(); 

      if (intent.getAction().equals("android.intent.action.BATTERY_LOW")) { 
       sharedPreferences.edit().putBoolean(Constants.BACKGROUND_SERVICE_BATTERY_CONTROL, false).apply(); 
       stopPeriodicTaskHeartBeat(context); 
      } else if (intent.getAction().equals("android.intent.action.BATTERY_OKAY")) { 
       sharedPreferences.edit().putBoolean(Constants.BACKGROUND_SERVICE_BATTERY_CONTROL, true).apply(); 
       restartPeriodicTaskHeartBeat(context, myApplication); 
      } else if (intent.getAction().equals(INTENT_ACTION)) { 
       doPeriodicTask(context, myApplication); 
      } 
     } 
    } 

    private void doPeriodicTask(Context context, MyApplication myApplication) { 
     // Periodic task(s) go here ... 
    } 

    public void restartPeriodicTaskHeartBeat(Context context, MyApplication myApplication) { 
     SharedPreferences sharedPreferences = myApplication.getSharedPreferences(); 
     boolean isBatteryOk = sharedPreferences.getBoolean(Constants.BACKGROUND_SERVICE_BATTERY_CONTROL, true); 
     Intent alarmIntent = new Intent(context, PeriodicTaskReceiver.class); 
     boolean isAlarmUp = PendingIntent.getBroadcast(context, 0, alarmIntent, PendingIntent.FLAG_NO_CREATE) != null; 

     if (isBatteryOk && !isAlarmUp) { 
      AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
      alarmIntent.setAction(INTENT_ACTION); 
      PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0); 
      alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), AlarmManager.INTERVAL_FIFTEEN_MINUTES, pendingIntent); 
     } 
    } 

    public void stopPeriodicTaskHeartBeat(Context context) { 
     AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
     Intent alarmIntent = new Intent(context, PeriodicTaskReceiver.class); 
     alarmIntent.setAction(INTENT_ACTION); 
     PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0); 
     alarmManager.cancel(pendingIntent); 
    } 
} 

здесь com.example.app.PERIODIC_TASK_HEART_BEAT собственная трансляция приложения, созданы и отправлены из нашего restartPeriodicTaskHeartBeat метода.

вашего Alarmmanager должны иметь эту линию

alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), AlarmManager.INTERVAL_FIFTEEN_MINUTES, pendingIntent); 

Теперь для вашего класса фона услуг:

public class BackgroundService extends Service { 

    private static final String TAG = "BackgroundService"; 

    PeriodicTaskReceiver mPeriodicTaskReceiver = new PeriodicTaskReceiver(); 

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

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     MyApplication myApplication = (MyApplication) getApplicationContext(); 
     SharedPreferences sharedPreferences = myApplication.getSharedPreferences(); 
     IntentFilter batteryStatusIntentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); 
     Intent batteryStatusIntent = registerReceiver(null, batteryStatusIntentFilter); 

     if (batteryStatusIntent != null) { 
      int level = batteryStatusIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); 
      int scale = batteryStatusIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); 
      float batteryPercentage = level/(float) scale; 
      float lowBatteryPercentageLevel = 0.14f; 

      try { 
       int lowBatteryLevel = Resources.getSystem().getInteger(Resources.getSystem().getIdentifier("config_lowBatteryWarningLevel", "integer", "android")); 
       lowBatteryPercentageLevel = lowBatteryLevel/(float) scale; 
      } catch (Resources.NotFoundException e) { 
       Log.e(TAG, "Missing low battery threshold resource"); 
      } 

      sharedPreferences.edit().putBoolean(Constants.BACKGROUND_SERVICE_BATTERY_CONTROL, batteryPercentage >= lowBatteryPercentageLevel).apply(); 
     } else { 
      sharedPreferences.edit().putBoolean(Constants.BACKGROUND_SERVICE_BATTERY_CONTROL, true).apply(); 
     } 

     mPeriodicTaskReceiver.restartPeriodicTaskHeartBeat(BackgroundService.this); 
     return START_STICKY; 
    } 
    @Override 
     public void onDestroy() { 
      super.onDestroy(); 
      startSelf(); 
     } 
} 

Здесь Backgroundservice пытается найти низкий порог батареи устройства и установите наш флаг управления батареи надлежащим образом, прежде чем он пытается перезапустить приемник Broadcast.

И START_STICKY попытается воссоздать ваш сервис после его убийства и позвонить по телефону onStartCommand() с нулевым намерением.

Наконец для вашего класса приложений запустить службу фона:

public class MyApplication extends Application { 
    private static final String TAG = "MyApplication"; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     // Initialize the singletons so their instances 
     // are bound to the application process. 
     ... 
     Intent startServiceIntent = new Intent(context, BackgroundService.class); 
     startService(startServiceIntent); 
    } 
} 

Для реализации подробно см это: https://technology.jana.com/2014/10/28/periodic-background-tasks-in-android/ enter image description here

быть уверены, чтобы сделать вам обслуживание, как это в вашем Mainifest

<service 
     android:name=".service.youservice" 
     android:exported="true" 
     android:process=":ServiceProcess" /> 

, то ваша служба будет работать в другом процессе с именем ServiceProcess

, если вы хотите, чтобы ваш сервис никогда не умирает:

  1. onStartCommand() возвращает START_STICKY

  2. OnDestroy() -> называют startself

, если ничего не работает Используй startForeground() сервиса ..

+0

спасибо, я понимаю ваш код За исключением кода фоновой службы, что она делает? –

+0

@AhmedShaheen см. Отредактированный ответ – rafsanahmad007

+0

Я делаю все, что вы сказали, но все же после того, как я удалил приложение из последних, я ничего не получил с сервера –