18

現在、「To Do タスク リスト」のようなアプリを開発中です。アプリケーションに NotificationService と SchedularService を正常に実装しました。また、タスクに設定された時間にアラート(通知)を受け取ります。以下は私のクエリです。

  1. このコードを使用すると、再起動後にアラームが削除されますか? はいの場合、これを克服する方法。
  2. タスクの優先機能を保持しています。しかし、ユーザーが優先度「高」を選択した場合、たとえば30分前、15分前、および設定された時間に3回通知を受け取るようなメカニズムが必要です。これを達成する方法は?
  3. 通知が発生したときに電話のバイブレーション機能を設定したい。これを達成する方法は?
  4. そして、NotifyService.java の非推奨のメソッドとコンストラクターに対して何ができるかを知りたいです。Thesse は API レベル 11:Notification notification = new Notification(icon, text, time);およびで廃止されましたnotification.setLatestEventInfo(this, title, text, contentIntent);。developer.android.com では、代わりに使用することを提案していますNotification.Builder。では、アプリをすべての API レベルと互換性を持たせる方法。

アラームをスケジュールするためのスニペット コードは次のとおりです。

...
scheduleClient.setAlarmForNotification(c, tmp_task_id);
...

クラス ScheduleClient.java は次のとおりです。

public class ScheduleClient {

    private ScheduleService mBoundService;
    private Context mContext;
    private boolean mIsBound;

    public ScheduleClient(Context context)
    {
        mContext = context;
    }

    public void doBindService()
    {   
        mContext.bindService(new Intent(mContext, ScheduleService.class), mConnection, Context.BIND_AUTO_CREATE);
        mIsBound = true;
    }

    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {

            mBoundService = ((ScheduleService.ServiceBinder) service).getService();
        }

        public void onServiceDisconnected(ComponentName className) {

            mBoundService = null;
        }
    };

    public void setAlarmForNotification(Calendar c, int tmp_task_id){

        mBoundService.setAlarm(c, tmp_task_id);
    }

    public void doUnbindService() {
        if (mIsBound)
        {           
            mContext.unbindService(mConnection);
            mIsBound = false;
        }
    }
}

ScheduleService.java は次のとおりです。

public class ScheduleService extends Service {

    int task_id;

    public class ServiceBinder extends Binder {

        ScheduleService getService() {

            return ScheduleService.this;
        }
    }

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

        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {

        return mBinder;
    }

    private final IBinder mBinder = new ServiceBinder();

    public void setAlarm(Calendar c, int tmp_task_id) {

        new AlarmTask(this, c, tmp_task_id).run();
    }
}

AlarmTask.java は次のとおりです。

public class AlarmTask implements Runnable{

    private final Calendar date;
    private final AlarmManager am;
    private final Context context;
    int task_id;

    public AlarmTask(Context context, Calendar date, int tmp_task_id) {
        this.context = context;
        this.am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        this.date = date;

        task_id = tmp_task_id;
    }

    @Override
    public void run() {

        Intent intent = new Intent(context, NotifyService.class);
        intent.putExtra(NotifyService.INTENT_NOTIFY, true);
        intent.putExtra("task_id", task_id);
        PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);

        am.set(AlarmManager.RTC, date.getTimeInMillis(), pendingIntent);
    }
}

NotifyService.java は次のとおりです。

public class NotifyService extends Service {

    public class ServiceBinder extends Binder
    {   
        NotifyService getService()
        {
            return NotifyService.this;
        }
    }

    int task_id;
    private static final int NOTIFICATION = 123;
    public static final String INTENT_NOTIFY = "com.todotaskmanager.service.INTENT_NOTIFY";
    private NotificationManager mNM;
    SQLiteDatabase database;

    @Override
    public void onCreate() {

        mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    }

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

        String tmp_task_brief = null;
        task_id = intent.getIntExtra("task_id", 0);

        loadDatabase();
        Cursor cursor = database.query("task_info", new String[]{"task_brief"}, "task_id=?", new String[]{task_id+""}, null, null, null);
        while(cursor.moveToNext())
        {
            tmp_task_brief = cursor.getString(0);
        }
        cursor.close();

        if(intent.getBooleanExtra(INTENT_NOTIFY, false))
            showNotification(tmp_task_brief);

        return START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {

        return mBinder;
    }

    private final IBinder mBinder = new ServiceBinder();

    private void showNotification(String tmp_task_brief) {

        CharSequence title = "To Do Task Notification!!";
        int icon = R.drawable.e7ca62cff1c58b6709941e51825e738f;
        CharSequence text = tmp_task_brief;     
        long time = System.currentTimeMillis();

        Notification notification = new Notification(icon, text, time);

        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, TaskDetails.class), 0);

        notification.setLatestEventInfo(this, title, text, contentIntent);

        notification.flags |= Notification.FLAG_AUTO_CANCEL;

        mNM.notify(NOTIFICATION, notification);

        stopSelf();
    }

    void loadDatabase()
    {
        database = openOrCreateDatabase("ToDoDatabase.db",
                SQLiteDatabase.OPEN_READWRITE, null);
    }
}
4

1 に答える 1

36

このコードを使用すると、再起動後にアラームが削除されますか? はいの場合、これを克服する方法。

はい、アラームは削除されます。これを克服するには、次のように BroadcastReceiver という Android のコンポーネントを使用する必要があります。

まず、マニフェストで許可が必要です。

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

また、マニフェストでサービスを定義し、boot-completed アクションをリッスンします。

<receiver
    android:name=".receiver.StartMyServiceAtBootReceiver"
    android:enabled="true"
    android:exported="true"
    android:label="StartMyServiceAtBootReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

次に、BOOT_COMPLETED アクションを取得してサービスを開始するレシーバーを定義する必要があります。

public class StartMyServiceAtBootReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
            Intent serviceIntent = new Intent("com.myapp.NotifyService");
            context.startService(serviceIntent);
        }
    }
}

これで、電話の起動時にサービスが実行されているはずです。

2 振動について

AndroidManifest.xml ファイルで権限を次のように定義する必要があります。

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

振動のコードは次のとおりです。

// Get instance of Vibrator from current Context
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

// Vibrate for 300 milliseconds
v.vibrate(300);
于 2013-05-14T02:21:12.467 に答える