ترکیب BroadcastReceiver و JobService برای دریافت اطلاعات از اینترنت در پس زمینه
سلام؛
من نیاز دارم در پس زمینه، طی دوره زمانی مشخص و با اطلاع از اتصال به شبکه اینترنت، یک سری اطلاعات رو از سورس دریافت کنم. مشکلی که من دارم، نا آشنا بودن با این تکنولوژی ها و تازه کار بودن من در جاوا و اندروید هست.
BroadcastReceiver همونطور که می دونید، برای آگاهی از بعضی رویدادها در سیستم هست و من از این برای اطلاع از متصل بودن به نت استفاده کردم، به محض اینکه نت (Mobile Data/WiFi) متصل باشه، کلاس زیر شروع به کار می کنه:
public class NetworkChangeReceiver extends BroadcastReceiver {
private Context mContext;
private JobScheduler mJobScheduler;
@Override public void onReceive(final Context context, final Intent intent) {
try {
boolean isVisible = AppController.isActivityVisible();// Check if Log.i("Activity is Visible ", "Is activity visible : " + isVisible);
// If it is visible then trigger the task else do nothing
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager
.getActiveNetworkInfo();
// Check internet connection and accrding to state change the // text of activity by calling method if (networkInfo != null && networkInfo.isConnected()) {
mContext = context;
mJobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SER VICE);
JobInfo.Builder builder = new JobInfo.Builder(1,
new ComponentName(MainActivity.PACKAGE_NAME, Job.class.getName()));
builder.setPeriodic(3000);
builder.build();
if (mJobScheduler.schedule(builder.build()) == JobScheduler.RESULT_FAILURE) {
//If something goes wrong Log.i("mJobScheduler", "If something goes wrong ");
}
} else {
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
مزیت اینه که وقت نت قطع شد، می تونم پس زمینه رو هم متوقف کنم تا مشکلی پیش نیاد. اما این کلاس JobService من هست که برای تست هست:
public class Job extends JobService {
private static final String TAG = "SyncService";
@Override
public boolean onStartJob(JobParameters params) {
// fake work
Log.i(TAG, "on start job: " + params.getJobId());
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
return true;
}
}
من در اینجا شیئی از Job.Class ساختم و اون رو شروع هم کردم، اما این کلاس عکس العملی نداره و اجرا نمیشه (کلاس NetworkChangeReceiver به خوبی کار می کند):
if (networkInfo != null && networkInfo.isConnected()) {
mContext = context;
mJobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SER VICE);
JobInfo.Builder builder = new JobInfo.Builder(1,
new ComponentName(MainActivity.PACKAGE_NAME, Job.class.getName()));
builder.setPeriodic(3000);
builder.build();
if (mJobScheduler.schedule(builder.build()) == JobScheduler.RESULT_FAILURE) {
//If something goes wrong
Log.i("mJobScheduler", "If something goes wrong ");
}
} else {
}
حالا سوال من این هست:
1. چطور کلاس Job رو صدا بزنم؟
2. چطور زمانبندی ایجاد کنم؟ مثلا هر ساعت یکبار اجرا شود.
با تشکر
نقل قول: ترکیب BroadcastReceiver و JobService برای دریافت اطلاعات از اینترنت در پس زمینه
سلام؛
اگر با سرویس ها یا Intent Service هم کسی راه حلی برای این کار داره، ممنون میشم به اشتراک بگذاره.
نقل قول: ترکیب BroadcastReceiver و JobService برای دریافت اطلاعات از اینترنت در پس زمینه
سلام مجدد؛
خب دوستان چون با Job نتونستم کارم رو پیش ببرم (هر چند گویا خیلی خوبه)، دست به دامان سرویس شدم. کدها به زیر تغییر کرده:
کلاس NetworkChangeReceiver
public class NetworkChangeReceiver extends BroadcastReceiver {
private Context mContext;
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onReceive(final Context context, final Intent intent) {
try {
boolean isVisible = AppController.isActivityVisible();// Check if
Log.i("Activity is Visible ", "Is activity visible : " + isVisible);
// If it is visible then trigger the task else do nothing
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager
.getActiveNetworkInfo();
// Check internet connection and accrding to state change the
// text of activity by calling method
if (networkInfo != null && networkInfo.isConnected()) {
Intent intent2 = new Intent(context, MyService.class);
context.startService(intent2);
} else {
Intent intent2 = new Intent(context, MyService.class);
context.stopService(intent2);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
و سرویس:
public class MyService extends Service {
AlarmManager alarm_manager;
PendingIntent pi;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TODO do something useful
NextUpdate(intent);
return Service.START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
alarm_manager.cancel(pi);
stopSelf();
}
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
private void NextUpdate(Intent intent) {
alarm_manager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Calendar cur_cal = Calendar.getInstance();
pi = PendingIntent.getService(this, 0, new Intent(this, MyService.class), 0);
alarm_manager.setRepeating(AlarmManager.RTC_WAKEUP , cur_cal.getTimeInMillis(), 6000, pi);
ConnectivityManager connectivityManager = (ConnectivityManager) this
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager
.getActiveNetworkInfo();
Toast.makeText(this,"i dont have net", Toast.LENGTH_LONG).show();
}
}
اما مشکلات:
اگر سرویس رو در حالی که برنامه باز هست اجرا کنم، بعد از بسته شدن برنامه هم به فعالیت خودش ادامه میده. اما با قطع/وصل شدن ارتباط دیتا وقتی که برنامه بسته هست تغییری در روند سرویس به واسطه کلاس NetworkChangeReceiver ایجاد نمیشه (هم سرویس و هم این کلاس رجیستر شدن در منیفست).
حالا مشکل از چی هست؟!