【问题标题】:Execute a task (line of code) at a particular time of the day在一天中的特定时间执行任务(代码行)
【发布时间】:2013-11-25 15:16:48
【问题描述】:

我正在尝试在一天中的特定时间启用/禁用移动数据。这是我目前所拥有的:

  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);
}

网络.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>

【问题讨论】:

    标签: android scheduled-tasks data-connections


    【解决方案1】:

    我从未尝试过切换数据连接 - 假设如果您提供适当的权限(如果有的话)以上将起作用,并且上面的代码没有使用反射,因为我看到其他人正在拍摄自己脚...

    但是,如果您打算在特定时间打开应用程序活动,那么至少从用户体验的角度来看,我会说这是一种不好的做法。您可以通过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);
            }
        }
    }
    

    在 Manifest 中注册它:

    <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);
    

    EDIT以上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);
    }
    

    【讨论】:

    • 虽然你说的一切听起来都很完美而且很棒,但我真的不知道该怎么做......另外,请看我的编辑,因为我不太确定它是否使用反射.
    • 是的,它利用了反射。这通常是一个坏主意(通常重复),因为出于特定原因,应用程序不应调用私有 API。在这种情况下:应用程序正在启用数据连接,用户将从中付款。所以你的应用程序基本上是从他的口袋里偷钱。 :) 但是,如果您仍然打算这样做,即使我非常不同意,我也会尝试扩大答案。只是因为我们生活在同一个坐标:)
    • 不能有道德的 rt nw :)...我会继续这个...谢谢..等待你的编辑...
    • 我在两天前就开始了 android 编程。如果我要在这段代码中添加任何内容,我认为您的努力将是徒劳的……我仍然会尝试这个……
    • 和启动服务是另一种选择,只是不要使用活动。
    【解决方案2】:

    您可以设置两个闹钟,一个晚上10点,一个早上6点,然后当闹钟触发时,系统会启动服务让您做自己的工作。

       PendingIntent pi = PendingIntent.getService(this, 0, new Intent(
         this, YourOwnerService.class), PendingIntent.FLAG_UPDATE_CURRENT);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-15
      • 2018-05-17
      • 2013-04-18
      • 1970-01-01
      • 2012-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多