안 드 로 이 드 서 비 스 는 순환 정시 알림 기능 을 실현 합 니 다.

사람 은 매일 8 잔 의 물 을 마셔 야 건강 을 유지 할 수 있 습 니 다.그래서 힘 든 프로그래머 는 항상 코드 한 번 에 시간 을 잊 어 버 립 니 다.그래서 저 는 갑자기 apk 를 개발 하면 고정된 간격 을 실현 할 수 있 을 까 하 는 생각 이 들 었 습 니 다.시간 에 맞 춰 저 에 게 물 을 마셔 야 한다 고 일 깨 워 주 었 습 니 다.
apk 기본 기능:
1)간격 을 설정 할 수 있 습 니 다.2)apk 응용 프로그램 이 중 단 된 상태 에서 도 정시 알림 3)지정 한 알 람 을 재생 할 수 있 습 니 다.4)알 람 을 즉시 종료 할 수 있 습 니 다.
효과 그림:
간격 설정

시간 이 되면 전역 AlertDialog 알림 이 튀 어 나 와 알 람 을 시작 합 니 다.

앱 이 종료 되 더 라 도 알림 이 가능 합 니 다.

끝 알림

쓸데없는 말 은 그만 하고 코드 를 바로 입력 하 세 요.
레이아웃 레이아웃:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="bai.cslg.servicebestpractice.MainActivity"
  android:baselineAligned="false"
  android:orientation="vertical">


  <LinearLayout
    android:paddingTop="20dp"
    android:layout_width="match_parent"
    android:layout_height="70dp">
    <TextView
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="5"
      android:padding="10dp"
      android:gravity="center_vertical"
      android:text="         :"
      android:textSize="20sp"/>
    <EditText
      android:id="@+id/time"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"/>
    <TextView
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="2"
      android:gravity="center_vertical"
      android:text=" "
      android:textSize="20sp"/>
  </LinearLayout>

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
  <Button
    android:id="@+id/start_serice"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:text="  "/>
    <Button
      android:id="@+id/stop_serice"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:text="  "/>
  </LinearLayout>
</LinearLayout>

MainActivity 코드:

/*
*         ,    BindService,  StartService  
*/
package bai.cslg.servicebestpractice;

import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

  private Context mContext = MainActivity.this;

  private Button startService;
  private Button stopService;
  private EditText time;

  public static int TIME; //      

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startService = (Button) findViewById(R.id.start_serice);
    stopService = (Button) findViewById(R.id.stop_serice);
    time = (EditText) findViewById(R.id.time);

    startService.setOnClickListener(this);
    stopService.setOnClickListener(this);

  }

  @Override
  public void onClick(View view) {
    switch (view.getId()){
      case R.id.start_serice:
        Intent startIntent = new Intent(this,LongRunningService.class);
        TIME = Integer.parseInt(time.getText().toString().trim());
        //  Intent        Service
        startIntent.putExtra("Time",TIME);
        Toast.makeText(MainActivity.this,"    ",Toast.LENGTH_SHORT).show();
        startService(startIntent);
        break;
      case R.id.stop_serice:
        Intent stopIntent = new Intent(this,LongRunningService.class);
        Toast.makeText(MainActivity.this,"    ",Toast.LENGTH_SHORT).show();
        stopService(stopIntent);
        break;
    }
  }
}

서비스 코드:

package bai.cslg.servicebestpractice;

import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.Service;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.WindowManager;



import java.io.File;
import java.io.IOException;
import java.util.Date;

/**
 * Created by baiqihui on 2016/9/21.
 */
public class LongRunningService extends Service {

  public int anHour; //      

  public int number = 0; //  alertdialog    

  private MediaPlayer mediaPlayer = new MediaPlayer();

  AlarmManager manager;
  PendingIntent pi;


  private Handler mHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
      super.handleMessage(msg);
      switch (msg.what){
        case 1:
          if (!mediaPlayer.isPlaying()){
            mediaPlayer.start();
          }
          AlertDialog.Builder builder = new AlertDialog.Builder(LongRunningService.this);
          builder.setTitle("  ");
          builder.setMessage("    " + (number-1));
          builder.setCancelable(false);
          builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
              mediaPlayer.reset();
              initMediaPlayer();
            }
          });
          final AlertDialog dialog = builder.create();
          dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
          dialog.show();
      }
    }
  };

  @Nullable
  @Override
  public IBinder onBind(Intent intent) {
    return null;
  }

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

  }

  private void initMediaPlayer() {
    File file = new File("/storage/emulated/0/naoling","music.mp3");
    try {
      mediaPlayer.setDataSource(file.getPath());
      mediaPlayer.prepare();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    if (number!=0) {
      new Thread(new Runnable() {
        @Override
        public void run() {
          Log.e("bai", "executed at " + new Date().toString());
          mHandler.sendEmptyMessage(1);
        }
      }).start();
    }
    manager = (AlarmManager) getSystemService(ALARM_SERVICE);
    int time = intent.getIntExtra("Time",2);
    anHour = time*60*1000;
    Log.e("bai","Time:"+time+"anhour:"+anHour);
    long triggerAtTime = SystemClock.elapsedRealtime()+(anHour);
    Intent i = new Intent(this,AlarmReceiver.class);
    pi = PendingIntent.getBroadcast(this,0,i,0);
    manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,pi);
    number++;
    return super.onStartCommand(intent, flags, startId);
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    mediaPlayer.release();
    manager.cancel(pi);
  }
}
AlarmReceiver 코드:

package bai.cslg.servicebestpractice;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

/**
 * Created by baiqihui on 2016/9/21.
 */
public class AlarmReceiver extends BroadcastReceiver {
  @Override
  public void onReceive(Context context, Intent intent) {
      Intent i = new Intent(context, LongRunningService.class);
      context.startService(i);
  }
}
1)apk 응용 프로그램 이 정 지 된 상황 에서 도 정시 알림 을 할 수 있 습 니 다.여 기 는 startService 를 사용 하면 서비스 가 메모리 에 상주 하고 Activity 가 죽 더 라 도 실행 할 수 있 습 니 다.
2)간격 알림.여기 서 채택 한 것 은 안 드 로 이 드 의 알 람 메커니즘 이다.
 Android 의 정시 작업 은 일반적으로 두 가지 실현 방식 이 있 는데 하 나 는 자바 API 에서 제공 하 는 Timer 류 를 사용 하 는 것 이 고 하 나 는 Android 를 사용 하 는 Alarm 메커니즘 이다.이 두 가지 상황 은 대부분 상황 에서 비슷 한 효 과 를 실현 할 수 있 지만 Timer 류 는 뚜렷 한 짧 은 판 을 가지 고 있어 서 장기 적 으로 배경 에서 운행 해 야 하 는 정시 작업 에 적합 하지 않다.배 터 리 를 더욱 오래 쓸 수 있 도록 모든 휴대 전 화 는 자신의 휴면 전략 을 가지 고 있 으 며,안 드 로 이 드 휴대 전 화 는 장시간 작 동 하지 않 은 상태 에서 자동 으로 CPU 를 수면 상태 로 진입 시 켜 타이머 의 정시 작업 이 정상적으로 작 동 하지 못 할 수 있다 는 것 을 잘 알 고 있다.알 람 체 제 는 이러한 상황 이 존재 하지 않 습 니 다.CPU 를 깨 우 는 기능 을 가지 고 있 습 니 다.즉,정시 작업 을 수행 해 야 할 때마다 CPU 가 정상적으로 작 동 할 수 있 도록 보장 할 수 있 습 니 다.여기 서 CPU 를 깨 우 는 것 과 화면 을 깨 우 는 것 은 전혀 개념 이 아니 라 는 점 을 주의해 야 한다.
Service 코드 에서 알 수 있 듯 이 onCreate()에서 미디어 플레이어 에 대한 초기 화(미디어 플레이어 가 한 번 만 초기 화 되 어야 하기 때 문)를 완 료 했 습 니 다.onStartCommand()에서 새로운 스 레 드 를 열 었 습 니 다.스 레 드 에서 handler 를 통 해 빈 메 시 지 를 보 내 고 handler 의 handle Message()방법 에서 AlertDialog 생 성 및 알 람 재생 을 완 료 했 습 니 다.여기 서 만 든 것 은 전역 적 인 AlertDialog 입 니 다.처음 퀘 스 트 를 시작 할 때 AlertDialog 를 새로 만 들 필요 가 없 기 때 문 입 니 다.
onStartCommand()에 서 는 알 람 관리자 의 초기 화 와 시간 설정 도 실 행 했 습 니 다.알 람 관리자 의 세 번 째 매개 변수 인 PendingIntent 가 라디오 를 실행 할 수 있 기 때문에 라디오 수신 자 를 써 야 합 니 다.
AlarmManager 의 취소:manager.cancel(PendingIntent pi);대응 하 는 PendingIntent 를 취소 하면 됩 니 다.
AlarmReceiver:간단 합 니 다.방송 을 받 은 후에 서 비 스 를 시작 하면 됩 니 다.이것 은 상세 한 리스트 와 하나의 순환 이다.서비스 가 열 리 면 정시 에 방송 을 보 내 고 방송 이 받 은 후에 서 비 스 를 시작 할 것 이다.
시간 이 제한 되 어 있 기 때문에 코드 가 완선 되 지 않 은 부분 이 많 을 것 입 니 다.잘 부탁드립니다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기