2016-09-29 14 views
9

Tôi cần in tất cả email đến lúc 9 giờ sáng mỗi sáng. Dưới đây là những gì tôi đã thửAndroid: Cách kiểm tra email tại một thời điểm cụ thể với AlarmManager?

Phần email hoạt động tốt. Tôi có thể kết nối với email và in tất cả. Sự cố xảy ra khi tôi giới thiệu Trình quản lý báo thức. Khi tôi chạy nó, không có gì xảy ra. Nó chỉ bị treo

MainActivity.java

import android.annotation.TargetApi; 
import android.app.Activity; 
import android.app.AlarmManager; 
import android.app.PendingIntent; 
import android.app.job.JobInfo; 
import android.app.job.JobScheduler; 
import android.content.ComponentName; 
import android.content.Context; 
import android.content.Intent; 
import android.os.Build; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.Toast; 
import java.util.Calendar; 
import java.util.GregorianCalendar; 
import java.util.Properties; 
import javax.mail.*; 

public class MainActivity extends Activity { 

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

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    public void checkEmail(View view) { 
     Log.d("test", "accessing gmail"); 

     Calendar cur_cal = new GregorianCalendar(); 
     cur_cal.setTimeInMillis(System.currentTimeMillis());//set the current time and date for this calendar 

     Calendar cal = new GregorianCalendar(); 
     cal.add(Calendar.DAY_OF_YEAR, cur_cal.get(Calendar.DAY_OF_YEAR)); 
     cal.set(Calendar.HOUR_OF_DAY, 9); 
     cal.set(Calendar.MINUTE, 0); 
     cal.set(Calendar.SECOND, cur_cal.get(Calendar.SECOND)); 
     cal.set(Calendar.MILLISECOND, cur_cal.get(Calendar.MILLISECOND)); 
     cal.set(Calendar.DATE, cur_cal.get(Calendar.DATE)); 
     cal.set(Calendar.MONTH, cur_cal.get(Calendar.MONTH)); 


     // create an Intent 
     Intent intentAlarm = new Intent(this, AlarmReceiver.class); 
     PendingIntent pi = PendingIntent.getService(this, 0, intentAlarm, 0); 

     // create the object 
     AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 

     //set the alarm for 9 AM 
     alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 1000 * 5, pi); 

     Toast.makeText(this, "Alarm Scheduled for 9 AM", Toast.LENGTH_LONG).show(); 

    } 


} 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="com.example.admin.myapplication.MainActivity"> 

    <TextView 
     android:layout_width="wrap_content" 
     android:textSize="24sp" 
     android:layout_height="wrap_content" 
     android:text="Email Checker" 
     android:id="@+id/textView2" /> 

    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="New Button" 
     android:id="@+id/button" 
     android:layout_alignParentBottom="true" 
     android:layout_centerHorizontal="true" 
     android:layout_marginBottom="152dp" 
     android:onClick="checkEmail"/> 


</RelativeLayout> 

AlarmReceiver.java (UPDATED CLASS)

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.telephony.SmsManager; 
import android.util.Log; 
import android.widget.Toast; 



public class AlarmReceiver extends BroadcastReceiver 
{ 
    @Override 
    public void onReceive(Context context, Intent intent) 
    { 
     Intent i = new Intent(context, AsyncTaskActvity.class); 
    i.putExtra("foo", "bar"); 
    context.startService(i); 
     Log.d("test", "async"); 
     Toast.makeText(context, "Alarm Triggered", Toast.LENGTH_LONG).show(); 
    } 

} 

AsyncTaskActvity.java

package com.example.admin.myapplication; 

import android.os.AsyncTask; 
import android.util.Log; 
import java.util.Properties; 
import javax.mail.Folder; 
import javax.mail.Message; 
import javax.mail.Session; 
import javax.mail.Store; 

public class AsyncTaskActvity extends AsyncTask { 


    @Override 
    protected Object doInBackground(Object[] params) { 

     computerUp(); 

     return null; 


    } 

    protected boolean computerUp() { 



     try { 

      Properties props = java.lang.System.getProperties(); 
      props.setProperty("mail.store.protocol", "imaps"); 
      Session session = Session.getDefaultInstance(props, null); 
      Store store = session.getStore("imaps"); 
      store.connect("imap.gmail.com", "[email protected]", "mypassword"); 
      Session s = Session.getInstance(props); 


      Message[] msgs; 


      Folder inbox = store.getFolder("Inbox"); 
      inbox.open(Folder.READ_ONLY); 
      msgs = inbox.getMessages(); 

      for (int i = 0; i < msgs.length; i++) { 
       msgs[i].getSubject(); 
       Log.d("test", msgs[i].getSubject()); 
      } 

     } catch (Exception e) { 
      Log.e(e.getClass().getName(), e.getMessage(), e); 
     } 

     return true; 
    } 


} 

Khi tôi chạy nó, không có gì xảy ra. Tôi đang làm gì sai?

+0

vui lòng đọc câu trả lời của tôi. Bạn đã có rất nhiều lỗi. – Vyacheslav

Trả lời

5

Trước hết, nếu bạn muốn khởi động một số mã bên trong thiết bị Android của bạn phải sử dụng này:

  1. AlarmManager mà ra mắt BroadcastReceiver
  2. sử dụng WakeupBroadcastReceiver để đánh thức thiết bị của bạn.
  3. Sử dụng trạng thái tạm dừng trong thiết bị Android trong khi thực thi mã.
  4. Đừng quên nạp tiền sau khi khởi động lại thiết bị của bạn.
  5. BẠN CÓ VẤN ĐỀ KHI BẮT ĐẦU ASYNCTASK !!!
  6. Bạn đã thực hiện sai alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 1000 * 5, pi);. chuỗi này có nghĩa là: "thực thi mã của tôi sau mỗi 5 giây. Bắt đầu ngay bây giờ!". Đây không phải là thời gian 9:00;)

Vì vậy, hãy thử này:

  1. Để sạc AlarmManager tại thời điểm cụ thể:
Intent intent = new Intent(BRWakeup.INTENT_FILTER) ; 

     PendingIntent pi = PendingIntent.getBroadcast(ctx, intentalarm, intent, PendingIntent.FLAG_CANCEL_CURRENT); 
     int currentapiVersion = android.os.Build.VERSION.SDK_INT; 
     if (currentapiVersion < android.os.Build.VERSION_CODES.KITKAT){ 
      am.set(wakeup?AlarmManager.RTC_WAKEUP:AlarmManager.RTC, nexttime, pi); 
     } else if (currentapiVersion >= android.os.Build.VERSION_CODES.LOLLIPOP) 
      if (currentapiVersion < android.os.Build.VERSION_CODES.M) { 
       am.setExact(AlarmManager.RTC_WAKEUP, nexttime, pi); 
      } else { 
        am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nexttime, pi); 
      } 
     } 

nơi ctx - hiện Context lớp (Lớp cha mẹ cho ActivityService). Ví dụ: trong số Activity lớp học này là getContext() hoặc getActivity(). nexttime - thời gian để lau người nhận.Ví dụ: long nexttime = System.getCurrentTimeMillis();, AlarmManager am = (AlarmManager) ctx.getSystemService(Activity.ALARM_SERVICE);, intentalarm - là một số duy nhất để phát hiện sự kiện ra mắt này trong tương lai. Nó có thể là bất kỳ số nào bạn muốn nhưng không đổi trong ứng dụng của bạn. Ví dụ, final int intentalarm = 22344;

  1. Để khởi chạy dịch vụ từ BroadcastReceiver:
public class BRWakeup extends WakefulBroadcastReceiver { 
    public static final String INTENT_FILTER = "com.example.BRWakeup"; 
    @Override 
    public void onReceive(Context ctx, Intent intent) { 
     // TODO Auto-generated method stub 
     OWakeLocker.acquire(ctx, 0); 
     ComponentName comp = new ComponentName(ctx.getPackageName(), 
       SService.class.getName()); 
     startWakefulService(ctx, intent.setComponent(comp)); 
    } 

} 
  1. OWakeLocker là lớp của riêng tôi lưu trữ tất cả các dịch vụ được khởi chạy để tiết kiệm tuổi thọ của chúng.
public class OWakeLocker { 
    private static PowerManager.WakeLock[] wakeLocks = new PowerManager.WakeLock[1];//Services count 

    @SuppressWarnings("deprecation") 
    public static void acquire(Context ctx, int index) { 
     WakeLock wakeLock = wakeLocks[index]; 
     if (wakeLock != null) wakeLock.release(); 

     PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE); 
      wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | 
        PowerManager.ACQUIRE_CAUSES_WAKEUP | 
        PowerManager.ON_AFTER_RELEASE, _.APPNAME + Integer.toString(index)); 
     if (wakeLock != null && wakeLock.isHeld()){ 
      wakeLock.acquire(); 
     } 
    } 

    public static void release(int index) { 
     WakeLock wakeLock = wakeLocks[index]; 
     if (wakeLock != null) 
      wakeLock.release(); 
      wakeLock = null; 
    } 
} 
  1. Sử dụng dịch vụ này để thực thi mã của bạn:
public class SService extends Service { 

@Override 
    public void onCreate() { 
     OWakeLocker.acquire(this, 0); 
     super.onCreate(); 
} 
@Override 
    public void onDestroy() { 
     super.onDestroy(); 
     OWakeLocker.release(_.indexNOTS_TAT); 
    } 
@Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     //your code to start AsyncTask 

AsyncTaskActvity atask = new AsyncTaskActvity(); 
    atsk.execute(); 
} 
} 
  1. Để tính thời gian 9AM tốt, bạn phải sử dụng mã này: thời gian và dữ liệu e cho lịch này
 Calendar cal = Calendar.getInstance(); 
boolean iftoday = cal.get(Calendar.HOUR_OF_DAY) < 9; 

//to set the time as exact 
     cal.set(Calendar.HOUR_OF_DAY, 9); 
     cal.set(Calendar.MINUTE, 0); 
     cal.set(Calendar.SECOND, 0); 
     cal.set(Calendar.MILLISECOND, 0); 

     if (!iftoday) { 
      cal.add(Calendar.DATE, 1); 
     } 
     long nexttime = cal.getTimeInMillis();//this is the correct next time. 
  1. Sử dụng setExactAndAllowWhileIdle thay vì setRepeating.... Và nạp tiền AlarmManager tại SService.onDestroy() phương pháp sử dụng mã giống như trong Activity

  2. Sửa AndroidManifest.xml

<receiver android:name="com.example.BRWakeup" 
      android:exported="false"> 
      <intent-filter> 
       <action android:name="com.example.BRWakeup"/> 
      </intent-filter> 
     </receiver> 
<service android:name="com.example.SService"></service> 
+0

Cảm ơn bạn. Bạn có thể xin vui lòng gửi mã đầy đủ cho các biến này: 'am'.'intentalarm', nexttime,' ctx' thery không được khởi tạo ở bất kỳ đâu. Họ đến từ đâu từ – john

+0

Tôi đã cập nhật bài đăng của mình – Vyacheslav

3

Sử dụng dịch vụ có mục đích với Bộ thu phát sóng.

Thực hiện theo bên dưới liên kết với ví dụ:

Background Service

public class MyAlarmReceiver extends BroadcastReceiver { 
    public static final int REQUEST_CODE = 12345; 
    public static final String ACTION = "com.codepath.example.servicesdemo.alarm"; 
// Triggered by the Alarm periodically (starts the service to run task) 
    @Override 
    public void onReceive(Context context, Intent intent) { 
    Intent i = new Intent(context, MyTestService.class); 
    i.putExtra("foo", "bar"); 
    context.startService(i); 
    } 
} 
+0

Cảm ơn bạn. tôi đã thử điều này. 'Intent i = new Intent (ngữ cảnh, AsyncTaskActvity.class); i.putExtra ("foo", "bar"); context.startService (i); 'Vẫn là kết quả tương tự. Không có gì xảy ra – john

+0

vui lòng cập nhật câu hỏi của bạn với các thay đổi trong mã của bạn để tôi có thể kiểm tra, cũng cung cấp mã kê khai –

+0

Tôi đã cập nhật AlarmReceiver.java ** nhưng vẫn không hoạt động ** – john

3

Trước hết, thay đổi mã của bạn trong phương pháp checkEmail() tới:

@TargetApi(Build.VERSION_CODES.LOLLIPOP) 
public void checkEmail(View view) { 
    Log.d("test", "accessing gmail"); 
    //set the current time and date for this calendar 
    Calendar cal = new GregorianCalendar(); 
    cal.add(Calendar.DAY_OF_YEAR, 1); 
    cal.set(Calendar.HOUR_OF_DAY, 9); 
    cal.set(Calendar.MINUTE, 0); 

    // create an Intent 
    Intent intentAlarm = new Intent(this, AlarmReceiver.class); 
    PendingIntent pi = PendingIntent.getBroadcast(this, 0, intentAlarm, 0); 

    // create the object 
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 

    //set the alarm for 9 AM 
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi); 

    Toast.makeText(this, "Alarm Scheduled for 9 AM", Toast.LENGTH_LONG).show(); 
} 

Trong AlarmReceiver.java lớp (chắc chắn rằng máy thu này đã được đăng ký trong biểu hiện bằng hành động tùy chỉnh trong intent-filter tag):

@Override 
public void onReceive(Context context, Intent intent) { 
    new AsyncTaskActvity().execute(); 
    Log.d("test", "async"); 
    Toast.makeText(context, "Alarm Triggered", Toast.LENGTH_LONG).show(); 
} 

Vấn đề chính tại sao bạn nhận được lỗi là, bạn gọi startService() đến một lớp học mà không mở rộng Service , tức là AsyncTaskActvity. Bạn cần tìm sự khác biệt giữa ServiceAsyncTask.

Các vấn đề liên quan