Выполнить задачу (строку кода) в определенное время дня

Я пытаюсь включить / отключить мобильные данные в определенное время суток. Это то, что я до сих пор:

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

        Calendar objCal = Calendar.getInstance();
    objCal.set(Calendar.HOUR_OF_DAY, 11);
    objCal.set(Calendar.MINUTE, 0);
    objCal.set(Calendar.SECOND, 0);
    //
    // Intent intent = new Intent(this, MainActivity.class);
    // intent.setAction("com.sang.mobiledata.ACTION");
    //
     PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(
     this, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
     AlarmManager am = (AlarmManager)
     this.getSystemService(Context.ALARM_SERVICE);
     am.setRepeating(AlarmManager.RTC_WAKEUP, objCal.getTimeInMillis(),
     AlarmManager.INTERVAL_DAY, pi);

В принципе, я хотел бы отключить соединение для передачи данных, скажем, в 10 вечера. Я знаю, что это будет достигнуто этой линией:

objNetwork.setMobileDataEnabled(getBaseContext(), false);

и снова включите его, скажем, в 6 утра

objNetwork.setMobileDataEnabled(getBaseContext(), true);

Я просто не знаю, как (и где) дать это условие.

РЕДАКТИРОВАТЬ:

public class Network {

public void setMobileDataEnabled(Context context, boolean enabled) {

    try {
        ConnectivityManager conman = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);

        Method setMobileDataEnabledMethod = ConnectivityManager.class
                .getDeclaredMethod("setMobileDataEnabled", boolean.class);

        setMobileDataEnabledMethod.setAccessible(true);
        setMobileDataEnabledMethod.invoke(conman, enabled);
    } catch (Exception e) {
        e.printStackTrace();
    }

}

РЕДАКТИРОВАТЬ 2 (полный код):

ConnBroadCastReceiver.java

public class ConnBroadcastReceiver extends BroadcastReceiver {

private static final String CONN_ACTION = "com.sang.mobiledata.IntentAction.RECEIVE_CONN_UPDATE";
Network objNetwork = new Network();
@Override
public void onReceive(Context context, Intent intent) {
    if(CONN_ACTION.equals(intent.getAction())) {
        boolean enableConn = intent.getBooleanExtra("FLAG_KEY", false);
        objNetwork.setMobileDataEnabled(context, enableConn);
    }
 }

}

MainActivity.java

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    triggerEnable(true, 6);
    triggerEnable(false, 22);
}

private void triggerEnable(boolean enableData, int hourInDay) {
    Calendar calendar = Calendar.getInstance();
    if (enableData) {
        calendar.set(Calendar.HOUR_OF_DAY, hourInDay);
    } else {
        calendar.set(Calendar.HOUR_OF_DAY, hourInDay);
    }
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    Intent broadcastIntent = new Intent("com.sang.mobiledata.IntentAction.RECEIVE_CONN_UPDATE");
    broadcastIntent.putExtra("FLAG_KEY", enableData);
    PendingIntent pi = PendingIntent.getBroadcast(this, 0, broadcastIntent,
            PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
    am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY, pi);
}

Network.java

 public class Network {

public void setMobileDataEnabled(Context context, boolean enabled) {

    try {
        ConnectivityManager conman = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);

        Method setMobileDataEnabledMethod = ConnectivityManager.class
                .getDeclaredMethod("setMobileDataEnabled", boolean.class);

        setMobileDataEnabledMethod.setAccessible(true);
          setMobileDataEnabledMethod.invoke(conman, enabled);
    } catch (Exception e) {
        e.printStackTrace();
     }

}

manifest.xml

 <application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <receiver
        android:name="com.sang.mobiledata.ConnBroadcastReceiver"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.sang.mobiledata.IntentAction.RECEIVE_CONN_UPDATE" />
        </intent-filter>
    </receiver>

2 ответа

Решение

Я никогда не пытался переключить соединение для передачи данных. Предполагается, что вышеприведенное сработает, если вы предоставите надлежащие разрешения (если предполагается, что они есть), а код выше не использует отражения, как я видел, что другие люди стреляют себе в ногу...

Однако, если вы намереваетесь открыть действие приложения в определенное время, я бы сказал, что это плохая практика, по крайней мере, с точки зрения взаимодействия с пользователем. Вместо этого вы можете отправить широковещательное сообщение через PendingIntent.getBroadcast(...),

Что, как говорится:

  1. Создайте намерение с помощью собственного действия, добавьте внутри него логический флаг, который имеет смысл (true для включения подключения, false в противном случае).
  2. Передайте это намерение вашему PendingIntent.getBroadcast
  3. Создать BroadcastReceiver в своем классе зарегистрируйте его в манифесте и правильно обработайте это действие. Что-то вроде:

Класс BroadcastReceiver:

public class ConnBroadcastReceiver extends BroadcastReceiver {
    private static final String CONN_ACTION = "my_package_name.IntentAction.RECEIVE_CONN_UPDATE";

    @Override
    public void onReceive(Context context, Intent intent) {
        if(CONN_ACTION.equals(intent.getAction())) {
            boolean enableConn = intent.getBooleanExtra("FLAG_KEY", false);
            objNetwork.setMobileDataEnabled(context, enableConn);
        }
    }
}

зарегистрируйте его в манифесте:

<receiver
    android:name="my_package_name.ConnBroadcastReceiver"
    android:exported="false" >
        <intent-filter>
            <action android:name="my_package_name.IntentAction.RECEIVE_CONN_UPDATE" />
        </intent-filter>
</receiver>

и запустите трансляцию из приведенного выше кода:

Intent broadcastIntent = new Intent("my_package_name.IntentAction.RECEIVE_CONN_UPDATE");
broadcastIntent.putExtra("FLAG_KEY", enableData);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, objCal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);

РЕДАКТИРОВАТЬ выше onCreate может быть переписан для:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    triggerEnable(true, 6);
    triggerEnable(false, 22);
}

private void triggerEnable(boolean enableData, int hourInDay) {
    Calendar calendar = Calendar.getInstance();
    if (enableData) {
        calendar.set(Calendar.HOUR_OF_DAY, hourInDay);
    } else {
        calendar.set(Calendar.HOUR_OF_DAY, hourInDay);
    }
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    Intent broadcastIntent = new Intent("my_package_name.IntentAction.RECEIVE_CONN_UPDATE");
    broadcastIntent.putExtra("FLAG_KEY", enableData);
    PendingIntent pi = PendingIntent.getBroadcast(this, 0, broadcastIntent,
            PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
    am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY, pi);
}

Вы можете установить два будильника, один на 22:00, а другой на 6:00, а затем, когда сработают тревоги, система запустит службы, которые позволят тебе выполнять свои собственные работы.

   PendingIntent pi = PendingIntent.getService(this, 0, new Intent(
     this, YourOwnerService.class), PendingIntent.FLAG_UPDATE_CURRENT);
Другие вопросы по тегам