بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]
پرسش و پاسخ

سِت , غیر فعال و حذف کردن  AlarmManager برای چندین زمان ( حل شد )

مدیریت گفتگو
amirfallahi 11 سال پیش
آخرین تغییر: 11 سال پیش

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

اول اینکه شاید هر یک ساعت آلارم لازم بشه. شاید هر دو ساعت و.... الی آخر ( تا هر ۱۲ ساعت )

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

برای ست کردن آلارم بصورت داینامیک میخوام توی کلاس G بنویسمش و طبق اصولش از طریق برادکست رسیور  آلارم رو برای ساعت های دلخواهم ست کنم.

مشکل اولم اینه که نمیدونم باید طبق زمان هایی که بدست آوردم یکی یکی آلارم ست کنم ( مثلا از ساعت ۲ تا ۹ یک ساعت درمیون ) یا به آلارمم بگم هر دو ساعت تکرار شه ( که اینجوری باز نمیدونم چجوری بهش بگم فقط تا ۹ ) 

مشکل دومم اینه که نمیدونم حالا که آلارم ها ست شدن ( مثلا برا ساعت ۲ سه تا آلارم با سه تا موضوع مختلف ست شده که باید به کاربر تو اون ساعت یه نوتیفیکیشن نشون بدن هرکدومشون ) چجوری مثلا یکیشونو حذف کنم یا غیر فعال کنم. چون تا اونجایی که تو انجمن سرچ کردم همه از این کد استفاده کرده بودن :

Intent intent =newIntent(this,AlarmReceive.class);
PendingIntent sender =PendingIntent.getBroadcast(this,0, intent,0);
AlarmManager alarmManager =(AlarmManager) getSystemService(ALARM_SERVICE);

alarmManager.cancel(sender);

که اگه اشتباه نکنم این تموم آلارمایی که من ست کردم رو نابود میکنه با خاک یکسان میکنه ( چون همشونو از طریق همین اینتنت ست کردم دیگه ... )

 

اگه امکانش باشه که برای هر آلار یه موضوع یا کلید یا id تعریف کرد و وقتی بخوایم حذف کنیم طبق اون کلید یا id آلارم رو حذف کنیم دیگه مشکل حل میشه. درسته ؟

 

دوستان خواهش میکنم زودتر جواب بدید اگر میدونید. من تا ۲۹ بهمن بیشتر وقت ندارم ... :(

نظرات

پاسخ‌ها 4

CodeMaster 11 سال پیش

برای مشکل اولتون به نظرم بهتره که همون یکی یکی آلارم ها رو ست کنید

برای مشکل دومتون اگه منظورتون اینه که آلارم رو سر یک تایم مشخصی منقرض کنید از این روش میتونید استفاده کنید:

 if (System.currentTimeMillis() - 60*60*1000 > alarmTime){
G.alarmManager.cancel(pendingIntent);
}

در واقع تو کد اومدیم گفتیم که اگه تایم حال حاضر سیستم - 1 ساعت بزرگتر از زمان ست شده برای آلارم بود آلارم مورد نظر رو حذف کن و همچنین اگه آلارم هاتون رو به همون روشی که استاد گفتند توی BroadCastReceiver بزارید هیچوقت با خاک یکسان نمیشن! مگه اینکه کدتون اونو بترکونه

همچنین برای آلارم نمیشه id تعریف کرد. کلا به نظرم بخش آلارم منیجر خیلی توسط توسعه دهندگان اندروید ناقص توسعه داده شده و کلی دردسر داره

نظرات

amirfallahi 11 سال پیش
سلام. مرسی از جواب. برای مشکل اول درسته این کار رو میکنم با یه حلقه for. برای مشکل دوم نه منظورم این بود که هر زمان که کاربر کلید حذف آلارم رو بزنه آلارم حذف بشه که خب با قرار دادن ID برای pendingIntent مشکل حل میشه. و دقیقا همون آلارمی که ست شده رو با همون ID میتونیم هرجا که خواستیم حذف کنیم. ( پایین جوابشو میذارم بعد از جواب گرفتن و مطمئن شدن )
Hajhosseini 11 سال پیش

امیر جان باید برای pendingIntent یک ID تعریف کنی و اون رو فعال و غیر فعال کنی.شما همه ی آیدی هارو 0 دادی و زمانی که میخوای یکی رو غیر فعال کنی همه غیر فعال میشن چون 0 اند.

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

نظرات

amirfallahi 11 سال پیش
خب بذار ببینم درست فهمیدم یانه. داخل استک دیدم اینجوری گفته بودن پس این ۱۰۰۱ همون ID که باید براش تعیین کنمه. و از طریق همین ID میشه یه آلارم رو فعال کرد یا اینکه غیر فعال یا حذفش کرد. فقط باید int باشه دیگه؟ پس اگه برابر با id ای که داخل دیتابیس ذخیره میشه بذارمش فکر کنم بشه روش کنترل داشت. درسته؟ چون تموم آلارم ها داخل یه جدول ذخیره میشن. PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//used unique ID as 1001 پس با این اوصاف جواب سوال اولم هم میشه اینکه من یه متد مینویسم داخل کلاس G و برای ورودیش تعیین میکنم که زمان + یه Idبهم بده و اونا رو داخل آلارم منیجیر ست میکنم. و همچنین یه متد دیگه هم مینویسم که همون ورودی ها رو داشته باشه و ایندفعه بجای ست کردن آلارم رو حذف کنه . و هرجای برنامم که خواستم استفاده میکنم. برای تکرار هر روزش هم بجای set از setRepeat استفاده میکنم و مقدار تکرارشو برابر با AlarmManager.INTERVAL_DAY قرار بدم. درسته؟ میرم سراغش ببینم چی میشه. واقعا ممنونتم علی. خیلی کمکم کردی از روز اول این پروژه. ایشالله که بتونم جبران کنم محبتاتو
Hajhosseini 11 سال پیش
کاملا درسته امیر جان، فقط نیازی نیست همه ی متد هاتون رو در کلاس G بنویسید. یک کلاس به نام دلخواهتون بسازید که کار ایجاد و حذف آلارم هارو انجام بده، اینکه همه متدهاتون رو توی کلاس G تعریف کنید کار درستی نیست.
amirfallahi 11 سال پیش
آره درست میگین.چشم همین کارو میکنم. فکر میکنم روی سرعت RUN شدن تاثیر میذاره چون اولین کلاسی که اجرا میشه فکر کنم همین کلاس باشه. درسته؟ بازم مرسی :)
Hajhosseini 11 سال پیش
کاملا درسته. و البته شما باید جوری برنامه تون رو بنویسید که از هر کلاسی، در زمان مناسب استفاده کنید. اینکه تمامی کدها رو در یک اکتیویتی، یک فرگمنت یا حتی یک کلاس بنویسید کار اشتباهیه. حتی از متغیر هاتون هم نباید در همه جا استفاده کنید، استفاده از متغیر های استاتیک به جز مواقع خاص اصلا پیشنهاد نمیشه.
amirfallahi 11 سال پیش
نکته ی خیلی جالب و مفیدی بود. واقعا خیلی وقتا به این نکات توجه نمیکنیم و باعث میشه برنامه کند بشه . یا به مشکلات دیگه بخوریم من تاجایی که تونستم این موارد رو رعایت کردم توی این پروژه که انشاالله قراره نهایی بشه و دیگه در حد یه تکلیف نیست. سعی میکنم بازم مرتب تر بنویسم که هم خودم بتونم بیشتر توسعه بدم هم اگه نیاز شد کدی رو اینجا قرار بدم برای استفاده دیگران یا حتی رفع عیب زیاد پیچیده نباشه و باعث گیج شدن نشه :) بازم مرسی از لطفت و وقتی که میذاری
amirfallahi 11 سال پیش

من آلارم ها رو تونستم با این کد ست کنم و جواب هم میده:

 public static void setalarm(String username , String pillname){

        Calendar calendar = Calendar.getInstance();
        Calendar c = Calendar.getInstance();

        calendar.set(Calendar.MONTH, c.get(Calendar.MONTH));
        calendar.set(Calendar.YEAR, c.get(Calendar.YEAR));
        calendar.set(Calendar.DAY_OF_MONTH, c.get(Calendar.DAY_OF_MONTH));

        int pID = getid(username , pillname);
        if(pID != -1){

            Intent myIntent =new Intent(G.context ,ServiceAlarm.class);
           // Intent myIntent =new Intent(G.context ,ActivityAddPills.class);
            PendingIntent pendingIntent = PendingIntent.getService(G.context, pID , myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
           // PendingIntent pendingIntent = PendingIntent.getActivity(G.context, pID , myIntent, PendingIntent.FLAG_UPDATE_CURRENT);

            Cursor times = G.remindersdatabase.rawQuery("SELECT * FROM reminders WHERE reminders_pillname = '"+pillname+"' " , null);

            if(times != null) {
                try {
                    if (times.getCount() > 0) {

                        for (int i = 0; i < times.getCount(); i++) {

                            times.moveToNext();

                            String User = times.getString(times.getColumnIndex("reminders_username"));

                            if(username.equals(User)){

                                int setHours = times.getInt(times.getColumnIndex("reminders_hour"));
                                int setMinutes = times.getInt(times.getColumnIndex("reminders_minute"));

                                calendar.set(Calendar.HOUR_OF_DAY, setHours);
                                calendar.set(Calendar.MINUTE, setMinutes);
                                calendar.set(Calendar.SECOND, 00);
                                calendar.set(Calendar.AM_PM, Calendar.PM);

                                G.alarmManager.setRepeating(android.app.AlarmManager.RTC_WAKEUP , 
calendar.getTimeInMillis() , android.app.AlarmManager.INTERVAL_DAY , pendingIntent); } } } } finally { times.close(); } } } }

همون طور که مشخصه یه کلاس به شکل زیر دارم:

 public class ServiceAlarm extends IntentService {
    public ServiceAlarm(){
        super("ServiceAlarm");
        // TODO Auto-generated constructor stub
    }



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

        Intent mainIntent = new Intent(this, ActivityShowInfo.class);

        NotificationManager notificationManager
                = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);

        android.app.Notification noti = new NotificationCompat.Builder(this)
                .setAutoCancel(true)
                .setContentIntent(PendingIntent.getActivity(this, 0, mainIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT))
                .setContentTitle("Title")
                .setContentText("It's been so Long!!!")
                .setSubText("Please return back to App")
                .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                .setVibrate(new long[] {1000,1000,1000,1000})
                .setSmallIcon(R.drawable.ic_launcher)
                .setTicker("Important Notification")
                .setWhen(System.currentTimeMillis())
                .build();

        notificationManager.notify(0, noti);

    }

    @Override
    protected void onHandleIntent(Intent intent){

        Toast.makeText(getApplicationContext() , "alarm" , Toast.LENGTH_LONG).show();

    }


}

متاسفانه نه توست کار میکنه نه نوتیف. توست رو برای تست گذاشتم. 

 

نظرات

amirfallahi 11 سال پیش
خب دوستان این مشکلم حل شد کدش رو پایین میذارم برای آیندگان :D
amirfallahi 11 سال پیش

خب مشکل حل شد.

اول اینکه کلاس بالا رو از :

 publicclassServiceAlarmextendsIntentService

به:

 public class ServiceAlarm extends Service

و متد onHandleIntent که بی مصرف بود رو باید حذف میکردم و بجاش متد زیر رو میذاشتم که کلاس کامل بشه:

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

بعدش هم این کد رو به منیفست اضافه کردم ( که اصل مشکل هم همین بود ):

  <service android:name=".ServiceAlarm"
            android:enabled="true" />

 

حالا یه سوال دیگه دارم دوستان. راهی هست که مطمئن باشیم برناممون توی همه ورژنا نوتیفیکیشن دلخواهمون رو اجرا میکنه؟

کد های نوتیفیکیشن بالا که نوشتم ظاهرا فقط برای api 11 به بالا کار میکنه. درسته؟

 

نظرات

Hajhosseini 11 سال پیش
چند روش برای ارسال نوتیفیکیشن وجود داره، توی انجمن سرچ کنید، فکر کنم خودم چند ماه پیش یکی از روش هارو کامل درج کرده بودم.
f-Dehghan 11 سال پیش
api11 به بالا چیه؟ من توی یک گد موندم میگه api14 به بالا جواب میده این یعنی چی؟
CodeMaster 11 سال پیش
api 14 همون ورژن 4.0 (Ice Cream Sandwich) اندروید هستش
Hajhosseini 11 سال پیش
api 11 اندروید 3 هست که نامش HonyCamp هست. زمانی که شما از یکسری ماژول ها استفاده میکنید که api بالاتر لازم داره، باید minimum sdk رو به همون api تغییر بدید

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