Showing posts with label AlarmManager. Show all posts
Showing posts with label AlarmManager. Show all posts

Wednesday, June 24, 2015

AlarmManager trigger BroadcastReceiver, then start another activity to generate Ringtone

This example show how to choice date/time with DatePicker and TimePicker, then set AlarmManager to trigger BroadcastReceiver on specified date/time, then start another activity to generate Ringtone using RingtoneManager.




com.example.androidringtone.MainActivity.java
package com.example.androidringtone;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

import java.util.Calendar;

public class MainActivity extends ActionBarActivity {

    DatePicker datePicker;
    TimePicker timePicker;

    RadioButton optAlarm, optNotification, optRingtone;
    RadioButton optRingTonePicker;
    Button btnStart;
    TextView info;

    Ringtone ringTone;

    Uri uriAlarm, uriNotification, uriRingtone;

    final static int RQS_RINGTONEPICKER = 1;

    final static int RQS_1 = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        datePicker = (DatePicker)findViewById(R.id.datepicker);
        timePicker = (TimePicker)findViewById(R.id.timepicker);

        optAlarm = (RadioButton)findViewById(R.id.optAlarm);
        optNotification = (RadioButton)findViewById(R.id.optNotification);
        optRingtone = (RadioButton)findViewById(R.id.optRingtone);
        optRingTonePicker = (RadioButton)findViewById(R.id.optPicker);
        btnStart = (Button)findViewById(R.id.start);
        info = (TextView)findViewById(R.id.info);

        uriAlarm = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
        uriNotification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        uriRingtone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
        optAlarm.setText("uriAlarm: " + uriAlarm);
        optNotification.setText("uriNotification: " + uriNotification);
        optRingtone.setText("uriRingtone: " + uriRingtone);

        btnStart.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                if (optAlarm.isChecked()) {
                    setAlarm(uriAlarm);
                } else if (optNotification.isChecked()) {
                    setAlarm(uriNotification);
                } else if (optRingtone.isChecked()) {
                    setAlarm(uriRingtone);
                } else if (optRingTonePicker.isChecked()) {
                    startRingTonePicker();
                }

            }
        });

    }

    private void startRingTonePicker(){
        Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
        startActivityForResult(intent, RQS_RINGTONEPICKER);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == RQS_RINGTONEPICKER && resultCode == RESULT_OK){
            Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
            setAlarm(uri);
        }
    }

    private void setAlarm(Uri passuri){

        Calendar cal = Calendar.getInstance();
        cal.set(datePicker.getYear(),
                datePicker.getMonth(),
                datePicker.getDayOfMonth(),
                timePicker.getCurrentHour(),
                timePicker.getCurrentMinute(),
                00);

        String passString = passuri.toString();
        info.setText("\n\n***\n"
                + "Alarm is set@ " + cal.getTime() + "\n"
                + "***\n"
                + "Uri: " + passString);

        Intent intent = new Intent(getBaseContext(), AlarmReceiver.class);
        intent.putExtra("KEY_TONE_URL", passString);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(
                getBaseContext(),
                RQS_1,
                intent,
                PendingIntent.FLAG_CANCEL_CURRENT);

        AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
    }
}


layout/activity_main.xml
<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"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:paddingTop="10dp"
    android:paddingBottom="10dp"
    android:orientation="horizontal"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">

        <DatePicker
            android:id="@+id/datepicker"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"/>
        <TimePicker
            android:id="@+id/timepicker"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:autoLink="web"
            android:text="http://android-er.blogspot.com/"
            android:textStyle="bold" />

        <RadioGroup
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >

            <RadioButton
                android:id="@+id/optAlarm"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Alarm"
                android:checked="true" />

            <RadioButton
                android:id="@+id/optNotification"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Notification" />

            <RadioButton
                android:id="@+id/optRingtone"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Ringtone" />

            <RadioButton
                android:id="@+id/optPicker"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="ACTION_RINGTONE_PICKER" />

        </RadioGroup>

        <Button
            android:id="@+id/start"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Start"/>

        <TextView
            android:id="@+id/info"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </LinearLayout>

</LinearLayout>


com.example.androidringtone.AlarmReceiver.java
package com.example.androidringtone;

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

public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.

        String uriString = intent.getStringExtra("KEY_TONE_URL");

        Toast.makeText(context,
                "Alarm received!\n"
                + "uriString: " + uriString,
                Toast.LENGTH_LONG).show();

        Intent secIntent = new Intent(context, SecondActivity.class);
        secIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        secIntent.putExtra("SEC_RINGTONE_URI", uriString);
        context.startActivity(secIntent);

    }
}


com.example.androidringtone.SecondActivity.java
package com.example.androidringtone;

import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;


public class SecondActivity extends ActionBarActivity {

    TextView secInfo;
    Button btnStop;

    Ringtone ringTone;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        secInfo = (TextView)findViewById(R.id.secinfo);
        btnStop = (Button)findViewById(R.id.stop);

        String stringUri = getIntent().getStringExtra("SEC_RINGTONE_URI");
        Uri uri = Uri.parse(stringUri);
        secInfo.setText("uri: " + uri + "\n");

        ringTone = RingtoneManager
                .getRingtone(getApplicationContext(), uri);

        secInfo.append(ringTone.getTitle(SecondActivity.this));

        ringTone.play();

        btnStop.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                if(ringTone != null){
                    ringTone.stop();
                    ringTone = null;
                }
            }
        });

    }

}


layout/activity_second.xml
<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"
    android:padding="20dp"
    android:orientation="vertical"
    tools:context="com.example.androidringtone.SecondActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/secinfo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/stop"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Stop"/>

</LinearLayout>


Modify src/main/AndroidManifest.xml to add receiver of ".AlarmReceiver" and activity of ".SecondActivity".
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.androidringtone" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".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>

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

        <activity
            android:name=".SecondActivity"
            android:label="@string/title_activity_second" >
        </activity>
    </application>

</manifest>



download filesDownload the files (Android Studio Format).

download filesDownload the APK.

Thursday, April 30, 2015

Example of using AlarmManager to trigger BroadcastReceiver / alarmManager.set() and setExact()

A simple example of using AlarmManager to trigger a BroadcastReceiver to be called in 10 seconds later.


Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.

reference: http://developer.android.com/reference/android/app/AlarmManager.html

This example also show how to determine calling set() or setExact() depends on Build.VERSION.SDK_INT. But no demo how in-exact with calling set(), because  alarms scheduled in the near future will not be deferred as long as alarms scheduled far in the future.

AlarmReceiver.java
package com.example.androidalarm;

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

public class AlarmReceiver extends BroadcastReceiver {

 @Override
 public void onReceive(Context context, Intent intent) {
  
  Toast.makeText(context, 
   "AlarmReceiver.onReceive()", 
   Toast.LENGTH_LONG).show();
 }

}

activity_main.xml
<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"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.androidalarm.MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <Chronometer
        android:id="@+id/chronometer"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal" />

    <Button
        android:id="@+id/setnocheck"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Set Alarm 10 sec later - alarmManager.set()" />
    
    <Button
        android:id="@+id/setwithversioncheck"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Set Alarm 10 sec later - with SDK Version check" />

</LinearLayout>

MainActivity.java
package com.example.androidalarm;

import java.util.Calendar;
import android.support.v7.app.ActionBarActivity;
import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.Toast;


public class MainActivity extends ActionBarActivity {
 
 Chronometer chronometer;
 Button btnSetNoCheck, btnSetWithVerCheck;
 final static int RQS_1 = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        chronometer = (Chronometer)findViewById(R.id.chronometer);
        btnSetNoCheck = (Button)findViewById(R.id.setnocheck);
        btnSetNoCheck.setOnClickListener(onClickListener);
        btnSetWithVerCheck = (Button)findViewById(R.id.setwithversioncheck);
        btnSetWithVerCheck.setOnClickListener(onClickListener);
    }
    
    @SuppressLint("NewApi") 
    OnClickListener onClickListener = new OnClickListener(){

  @Override
  public void onClick(View v) {
   chronometer.setBase(SystemClock.elapsedRealtime());
      chronometer.start();
      
      //10 seconds later
      Calendar cal = Calendar.getInstance();
      cal.add(Calendar.SECOND, 10);
      
      Intent intent = new Intent(getBaseContext(), AlarmReceiver.class);
      PendingIntent pendingIntent = 
       PendingIntent.getBroadcast(getBaseContext(), 
         RQS_1, intent, PendingIntent.FLAG_ONE_SHOT);
      AlarmManager alarmManager = 
       (AlarmManager)getSystemService(Context.ALARM_SERVICE);
      
      if(v==btnSetNoCheck){
       alarmManager.set(AlarmManager.RTC_WAKEUP, 
        cal.getTimeInMillis(), pendingIntent);
       Toast.makeText(getBaseContext(), 
        "call alarmManager.set()", 
        Toast.LENGTH_LONG).show();
      }else{
       if(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
       {
        alarmManager.set(AlarmManager.RTC_WAKEUP, 
         cal.getTimeInMillis(), pendingIntent);
        Toast.makeText(getBaseContext(), 
         "call alarmManager.set()", 
         Toast.LENGTH_LONG).show();
       }else{
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, 
         cal.getTimeInMillis(), pendingIntent);
        Toast.makeText(getBaseContext(), 
         "call alarmManager.setExact()", 
         Toast.LENGTH_LONG).show();
       }
      }
      
  }
     
    };

}

Need to modify AndroidManifest.xml to add <receiver android:name=".AlarmReceiver" android:process=":remote" />
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.androidalarm"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="22" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".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>
        <receiver android:name=".AlarmReceiver" android:process=":remote" />
    </application>

</manifest>


download filesDownload the files.