آموزش های این وب سایت به صورت رایگان در دسترس است. اطلاعات بیشتر
بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]

آلارم منیجر (حل نشده) (خیلی مهم)

amir Alu  11 سال پیش  11 سال پیش
+4 0

سلام دوستان عزیز

من مدتی هست که شدیدا درگیر کارکردن با آلارم منیجر هستم، و متاسفانه شدیدا گیج شدم داخلش و تا الان دو بار تاپیک زدم ولی متاثفانه به جوابی نرسیدم. گفتم یک بار دیگه سوال خودم را خیلی واضحتر بپرسم به امید این که جواب سوالم پیدا کنم.

اول از همه سناریویی که میخوام پیاده سازی کنم رو کامل توضیح میدم.

من در حال ساختن یک برنامه یادآور هستم که ابتدا تاریخ گوشی را گرفته و به شمسی تبدیل میکنه و وقتی یک مورد ثبت میشود تاریخ شمسی وارد دیتا بیس میشود.

من میخوام هر روز برنامه چی کنه که آیا امروز موردی وجود دارد که تاریخش با تاریخ امروز یکی باشد یا نه؟ خوب حالا اگر وجود داشت یک پیغام ناتیفیکشن ظاهر شود که کاربر از این موضوع مطلع شود.

اولین مورد مهم این هست که من نمیخوام تک تک مورد های ثبت شده آلارم داشته باشن، مثلا اگر در یک روز 100 مورد ثبت شده وجود داشته باشد برنامه فقط یک بار چک کند و پیام دهد. این کل کاری هست که من میخوام انجام دهم، 

خوب حالا کد های برنامه را اینجا میزارم بعد سوال مطرح میکنم.

کلاس MainActivity:

 public class MainActivity extends ActionBarActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		Intent intentAlarm=new Intent(MainActivity.this,AlarmReceiver.class);
		PendingIntent pendingIntent=PendingIntent.getBroadcast(MainActivity.this, 0, intentAlarm, 0);
		
		AlarmManager manager=(AlarmManager) getSystemService(Context.ALARM_SERVICE);
		int interval=1000*60*60*2;
		
		Calendar calendar =Calendar.getInstance();
		Calendar c =Calendar.getInstance();
		calendar.set(Calendar.YEAR, c.get(Calendar.YEAR));
		calendar.set(Calendar.MONTH, c.get(Calendar.MONTH));
		calendar.set(Calendar.DAY_OF_MONTH, c.get(Calendar.DAY_OF_MONTH));
		calendar.set(Calendar.HOUR_OF_DAY, 9);
		calendar.set(Calendar.MINUTE, 30);
		calendar.set(Calendar.SECOND, 0);
		manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), interval, pendingIntent);
		
	}

کلاس AlarmReceiver:

 public class AlarmReceiver extends BroadcastReceiver {
	
	

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		Toast.makeText(context, "I'm running", Toast.LENGTH_LONG).show();
		
		Intent service = new Intent(context,MyAlarmService.class);
		context.startService(service);
	}

کلاس DeviceBootReceiver:

 public class DeviceBootReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		
		if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")){
			Intent intentAlarm=new Intent(context,AlarmReceiver.class);
			PendingIntent pendingIntent=PendingIntent.getBroadcast(context, 0, intentAlarm, 0);
			
			AlarmManager manager=(AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
			int interval=1000*60*60*2;
			
			Calendar calendar =Calendar.getInstance();
			Calendar c =Calendar.getInstance();
			calendar.set(Calendar.YEAR, c.get(Calendar.YEAR));
			calendar.set(Calendar.MONTH, c.get(Calendar.MONTH));
			calendar.set(Calendar.DAY_OF_MONTH, c.get(Calendar.DAY_OF_MONTH));
			calendar.set(Calendar.HOUR_OF_DAY, 9);
			calendar.set(Calendar.MINUTE, 30);
			calendar.set(Calendar.SECOND, 0);
			manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), interval, pendingIntent);
		}
	}

کلاس MyAlarmService:

 public class MyAlarmService extends Service {
	
	private NotificationManager notificationManager;

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
	}
	
	@Override
	@Deprecated
	public void onStart(Intent intent, int startId) {
		// TODO Auto-generated method stub
		super.onStart(intent, startId);
		
			notificationManager = (NotificationManager) this.getApplicationContext().getSystemService(this.getApplicationContext().NOTIFICATION_SERVICE);
	        Intent intent1 = new Intent(this.getApplicationContext(), MainActivity.class);

	        Notification notification = new Notification(R.drawable.ic_launcher, "message!", System.currentTimeMillis());
	        intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);

	        PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this.getApplicationContext(), 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
	        notification.flags |= Notification.FLAG_AUTO_CANCEL;
	        notification.setLatestEventInfo(this.getApplicationContext(), "AlarmManagerDemo", "This a test message!", pendingNotificationIntent);

	        Toast.makeText(this, "salaaaaaaaaaaaaaam", Toast.LENGTH_LONG).show();

	        MakeSomeSound();
	        notificationManager.notify(0, notification);
		
	}
	
	public void MakeSomeSound() {
        try {
            Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
            r.play();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
	
	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
	}

}

دسترسی ها در manifest:

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />
    
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <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>
        <service android:name=".MyAlarmService"
          android:enabled="true" />
        <receiver android:name=".AlarmReceiver">
	      <intent-filter>
	           <action android:name="android.intent.action.BOOT_COMPLETED"/>
	           <action android:name="android.intent.action.QUICKBOOT_POWERON" />
	      </intent-filter>
        </receiver>
        
        <receiver android:name=".DeviceBootReceiver"
            android:enabled="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            </intent-filter>
        </receiver>
        
    </application>

</manifest>

خوب حالا برسیم سر مشکلاتی که من دارم.

اول این که این کد اجرا میشه و ناتیفیکیشن هم میاره ولی نه سر ساعتی که من مشخص کردم، یه جورایی حالت تصادفی به خودش گرفته، گاهی سر ساعت اجرا میشه گاهی تا برنامه باز میکنیم اجرا میشه و گاهی هم اصلا اجرا نمیشه. من تمام سایت ها گشتم ولی اکثرا مثل همین کد نوشته بودن و مشکلی نداشتن ولی اینجا برنامه بد اجرا میشه.

الان بنظر شما مشکل این کد کجاست که سر ساعت اجرا نمیشه؟؟ 

مشکل دومی که دارم این هست که میخوام شرط اجرای ناتیفکشن این باشه که موردی ثبت شده در دیتابیس برای تاریخ روز وجود داشته باشه، این شرط کجا باید چک بشه؟ داخل Activity یا Broadcast یا Service ؟؟؟

کد زیر را ببینین:

 Cursor cursor=G.database.rawQuery("SELECT * FROM value1 WHERE date2 LIKE '%"+dateFarsi2+"%' AND done='false'", null);
if(cursor.getCount!=0){
//اینجا مثلا بگیم ناتیفیکشن اجرا بشه
}

یک شرطی مثل شرط بالا کجا باید بررسی بشه و قرارش بدم؟؟

 

 

 

 

+1 0
سلام دوست عزیز کدها رو نخوندم چون تازه شروع کردم به آموزش . چند مطلب کوتاه می نویسم شاید کمکتون کنه . 1- گفتید زمان بندی درست رعایت نمیشه و ناتیفیکیشن سر ساعت مشخص نمیاد و سر ساعت دلخواه خودش میاد : شاید شما توی محاسبه زمان اجرا اشتباهی دارید . 2- یک پیشنهاد برای طراحی برنامه : با یک کوئری Notification مربوط به نزدیکترین زمان به الآن رو بدست بیارید ، فاصله زمانی تا الآن رو حساب کنید و سیستم رو به اندازه اون زمان به حالت Sleep قرار بدید و بعد از پایان به صورت خودکار بیدار بشه و Notification مورد نظر رو اجرا کنه . اگر این فرآیند رو بذارید بایستی بعد از پایان اجرای هر Notification و بعد از ثبت هر زمان بندی جدید اجرا بشه . اینطوری از منابع کمتری هم استفاده میشه . (11 سال پیش)
+2 0
ممنون از شما دوست عزیز. ولی زمانبندی درست تنظیم شده است. توضیح بعدی نیز حتما رغایت خواهد شد مرسی، ولی متاسفانه فعلا مشکل من اجرا شد غیر معمول برنامه هست. یه چیز جالبی که الان متوجه شدم اینه که برنامه گاهی دهید سر ساعت اجرا میشود مثلا اگر ساعت 10 صبح مد نظر باشه اجرا میشه دقیق همن ساعت ولی از بعد اون هر بار که برنامه باز میشه با اجرای برنامه ناتیفیکشن به صدا در میاد و ظاهر میشه ولی قبل ساعت 10 این مشکل وجود نداره. (11 سال پیش)
0 0
(11 سال پیش)
0 0
(11 سال پیش)
0 0
نمی دونم چرا هر چی نوشتم اضافه نشد . توی کوئری که با اون Cursor مقداردهی میشه نوشته شده +dateFarsi2+ که قبل و بعدش با علامت % نوشته شده . با این اوصاف هر فیلد date2 که مقدارش دربرگیرنده dateFarsi2 باشه (قبل یا بعد dateFarsi2 هر مقداری باشه یا نباشه مهم نیست) Cursor مقداردهی میشه و جواب if درست هست و ناتیفیکیشن اجرا میشه . (احتمالا مشکل از همین مورد باشه) . ضمنا بررسی کنید جای درستی مقدار done رو true می کنید یا نه ؟ به نظر میاد که بایستی حتما بعد از اجرای ناتیفیکیشن این مقدار تغییر کنه . (11 سال پیش)
0 0
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), interval, pendingIntent); توی این خط شما گفتید ساعت که 9:30 شد هر دو ساعت آلارم رو تکرار کنه .اگردر هر روز یک بار میخواهید چک کنید آلارمی هست یا نه باید بگید سر ساعت 00:00 و هر 24 ساعت آلارم رو تکرار کنه. جواب سوال اوله .تست کنید ببینید جواب میده؟ (11 سال پیش)
0 0
داداش دمت گرم با این سوالت یه مشکل بزرگ من حل شد ... مرسی (11 سال پیش)
 برای این سوال 2 پاسخ وجود دارد.
پاسخ به سوال 
arshadtehrani  11 سال پیش
0 0

سلام دوست عزیز، تکه کد زیر را تغییر دهید.

مشکل شما حل خواهد شد

به جای این کد

Calendar
calendar =Calendar.getInstance();
Calendar c =Calendar.getInstance();
			calendar.set(Calendar.YEAR, c.get(Calendar.YEAR));
			calendar.set(Calendar.MONTH, c.get(Calendar.MONTH));
			calendar.set(Calendar.DAY_OF_MONTH, c.get(Calendar.DAY_OF_MONTH));
			calendar.set(Calendar.HOUR_OF_DAY,9);
			calendar.set(Calendar.MINUTE,30);
			calendar.set(Calendar.SECOND,0);

بنویسید
Calendar calendar =Calendar.getInstance();
			calendar.set(Calendar.HOUR_OF_DAY,9);
			calendar.set(Calendar.MINUTE,30);
			calendar.set(Calendar.SECOND,0);
0 0
اگر روش ایشون جواب نداد بگید من کدی که استفاده کردم رو بذارم (11 سال پیش)
0 0
جواب آقای دهقانم حتما تست کنید، ممکنه جواب بده اما من کلا از یه راه دیگه رفتم که شاید منطقی نباشه. هرکدوم از کدها کار کرد اطلاع بدید لطفا، مرسی (11 سال پیش)
0 0
واقعا ممنونم که جواب دادین. ولی مشکل من هنوز حل نشده حتی با این تغییر (11 سال پیش)
0 0
امیر جان من دقیقا مشکل تورو داشتم. مجبور شدم از یک کار شاید غیر اصولی استفاده کنم. البته فکر می کنم راهی که آقای دهقان گفت عملی باشه. اینترول رو به 1000*60*60*24 تغییر بده ببین بازهم این مشکل رو داری؟ (11 سال پیش)
پاسخ به سوال 
محسن علیزاده  11 سال پیش
+1 0

به صورت منطقی باید کد زیر هر 24 ساعت یک بار فراخوانی بشه و سر ساعت 9:30 آلارم بده:

 AlarmManager manager=(AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
int interval=1000*60*60*24;
Calendar calendar =Calendar.getInstance();Calendar c =Calendar.getInstance(); calendar.set(Calendar.YEAR, c.get(Calendar.YEAR)); calendar.set(Calendar.MONTH, c.get(Calendar.MONTH)); calendar.set(Calendar.DAY_OF_MONTH, c.get(Calendar.DAY_OF_MONTH)); calendar.set(Calendar.HOUR_OF_DAY,9); calendar.set(Calendar.MINUTE,30); calendar.set(Calendar.SECOND,0); manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), interval, pendingIntent);

اما خب من هم مشکل مشابه شمارو داشتم که اومدم در رسیورم این کد رو نوشتم:

 int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
int min = Calendar.getInstance().get(Calendar.MINUTE);

if(hour == 9 && min == 30){
Toast.makeText(context, "I'm running", Toast.LENGTH_SHORT).show();
}

بازهم تاکید می کنم، ممکنه این کد منطقی نباشه، اما کاری که من میخواستم رو دقیقا انجام میده...

موفق باشید.

+1 0
محسن جان برای منم دقیقا این کد کار کرد. ولی خوب عجیبه به نظر من باید راه های بهتر هم باشه. (11 سال پیش)

پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .