アプリがサービスを使用せずに AlarmManager を使用してアラームを実行することは可能ですか? AlarmManager は、デバイスをスリープ モードから復帰させ、onReceive でコードを実行する必要があります。私がここに投稿したほとんどすべてのコード サンプルは、サービスが使用されていることを示しています。しかし、Android のドキュメントには、サービスの必要性については言及されていません。
質問する
1522 次
3 に答える
1
これが実際の例です。
activity_alarm_manager.xml ファイルのコード
<linearlayout android:layout_height="match_parent"
android:layout_width="match_parent" android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<button android:id="@+id/btStart" android:layout_height="wrap_content"
android:layout_width="match_parent" android:onclick="startRepeatingTimer"
android:padding="@dimen/padding_medium" android:text="@string/btStart"
tools:context=".WidgetAlarmManagerActivity"/>
<button android:id="@+id/btCancel" android:layout_height="wrap_content"
android:layout_width="match_parent" android:onclick="cancelRepeatingTimer"
android:padding="@dimen/padding_medium" android:text="@string/btCancel"
tools:context=".WidgetAlarmManagerActivity"/>
<button android:id="@+id/btOneTime" android:layout_height="wrap_content"
android:layout_width="match_parent" android:onclick="onetimeTimer"
android:padding="@dimen/padding_medium" android:text="@string/btOneTime"
tools:context=".WidgetAlarmManagerActivity"/>
</linearlayout>
BroadcastReceiverのコード、
public class AlarmManagerBroadcastReceiver extends BroadcastReceiver {
final public static String ONE_TIME = "onetime";
@Override
public void onReceive(Context context, Intent intent) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "YOUR TAG");
//Acquire the lock
wl.acquire();
//You can do the processing here.
Bundle extras = intent.getExtras();
StringBuilder msgStr = new StringBuilder();
if(extras != null && extras.getBoolean(ONE_TIME, Boolean.FALSE)){
//Make sure this intent has been sent by the one-time timer button.
msgStr.append("One time Timer : ");
}
Format formatter = new SimpleDateFormat("hh:mm:ss a");
msgStr.append(formatter.format(new Date()));
Toast.makeText(context, msgStr, Toast.LENGTH_LONG).show();
//Release the lock
wl.release();
}
public void SetAlarm(Context context)
{
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
intent.putExtra(ONE_TIME, Boolean.FALSE);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
//After after 5 seconds
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 5 , pi);
}
public void CancelAlarm(Context context)
{
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
public void setOnetimeTimer(Context context){
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
intent.putExtra(ONE_TIME, Boolean.TRUE);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pi);
}
}
AndroidManifest.xml のコード
<manifest android:versioncode="1" android:versionname="1.0"
package="com.rakesh.alarmmanagerexample"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk android:minsdkversion="10" android:targetsdkversion="15"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application android:icon="@drawable/ic_launcher"
android:label="@string/app_name" android:theme="@style/AppTheme">
<activity android:label="@string/title_activity_alarm_manager"
android:name="com.rakesh.alarmmanagerexample.AlarmManagerActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.rakesh.alarmmanagerexample.AlarmManagerBroadcastReceiver">
</receiver>
</application>
</manifest>
AlarmManagerActivity.java ファイルのコード
public class AlarmManagerActivity extends Activity {
private AlarmManagerBroadcastReceiver alarm;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm_manager);
alarm = new AlarmManagerBroadcastReceiver();
}
@Override
protected void onStart() {
super.onStart();
}
public void startRepeatingTimer(View view) {
Context context = this.getApplicationContext();
if(alarm != null){
alarm.SetAlarm(context);
}else{
Toast.makeText(context, "Alarm is null", Toast.LENGTH_SHORT).show();
}
}
public void cancelRepeatingTimer(View view){
Context context = this.getApplicationContext();
if(alarm != null){
alarm.CancelAlarm(context);
}else{
Toast.makeText(context, "Alarm is null", Toast.LENGTH_SHORT).show();
}
}
public void onetimeTimer(View view){
Context context = this.getApplicationContext();
if(alarm != null){
alarm.setOnetimeTimer(context);
}else{
Toast.makeText(context, "Alarm is null", Toast.LENGTH_SHORT).show();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_widget_alarm_manager, menu);
return true;
}
}
Githubからの参照リンク
于 2013-04-20T10:45:52.107 に答える
0
Activity
渡すことで定期的なイベントを設定することは問題ではないと思いますが、Context
どのコンテキストが渡されるかは問題ではないようです。
渡された は、 4.2.2 のソースを参照してfromおよび from をcontext
取得する場合にのみ使用されます。PendingIntent
PendingIntent.getBroadcast
/**
* Retrieve a PendingIntent that will perform a broadcast, like calling
* {@link Context#sendBroadcast(Intent) Context.sendBroadcast()}.
*
* @param context The Context in which this PendingIntent should perform
* the broadcast.
* @param requestCode Private request code for the sender (currently
* not used).
* @param intent The Intent to be broadcast.
* @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
* {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
* or any of the flags as supported by
* {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
* of the intent that can be supplied when the actual send happens.
*
* @return Returns an existing or new PendingIntent matching the given
* parameters. May return null only if {@link #FLAG_NO_CREATE} has been
* supplied.
*/
public static PendingIntent getBroadcast(Context context, int requestCode,
Intent intent, int flags) {
return getBroadcastAsUser(context, requestCode, intent, flags,
new UserHandle(UserHandle.myUserId()));
}
/**
* @hide
* Note that UserHandle.CURRENT will be interpreted at the time the
* broadcast is sent, not when the pending intent is created.
*/
public static PendingIntent getBroadcastAsUser(Context context, int requestCode,
Intent intent, int flags, UserHandle userHandle) {
String packageName = context.getPackageName();
String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
context.getContentResolver()) : null;
try {
intent.setAllowFds(false);
IIntentSender target =
ActivityManagerNative.getDefault().getIntentSender(
ActivityManager.INTENT_SENDER_BROADCAST, packageName,
null, null, requestCode, new Intent[] { intent },
resolvedType != null ? new String[] { resolvedType } : null,
flags, null, userHandle.getIdentifier());
return target != null ? new PendingIntent(target) : null;
} catch (RemoteException e) {
}
return null;
}
渡さcontext
れた は、パッケージ名と解決された型を取得するためにのみ使用され、PendingIntent
問題やリークを引き起こす可能性のある に格納されていないことがわかります。
于 2013-04-20T11:16:08.427 に答える