Итак, у меня есть класс службы задач, который запускает асинтезу, а затем запускает уведомление, если условие выполнено. В методе sendnotification, где создается Intent, существует исключение нулевого указателя, контекст имеет все нулевые значения. Я не думаю, что правильно передаю контекст из асинтезы BloodLevelParse? Не уверен, что еще я могу попробовать. Вот класс:Передача контекста из asynctask?
public class TaskService extends IntentService {
private ArrayList<BloodLevels> BloodLevelList;
private String bloodLevel;
private String bloodType;
private Integer bloodLevelDays;
private MyProfileActivity myProfileActivity;
private BloodLevelParse bloodLevelParse;
public TaskService() {
super("TaskService");
}
@Override
protected void onHandleIntent(Intent intent) {
// Pass through the blood type
Bundle bundle = intent.getExtras();
bloodType = bundle.getString("currentBloodType2");
// Only perform check if there is an internet connection
if (CheckNetwork.isInternetAvailable(TaskService.this)) {
// Check the current blood level for the given blood type
new BloodLevelParse(this).execute(bloodType);
} else {
Toast.makeText(
TaskService.this,
"Unable to perform daily blood level check, no internet connection.",
Toast.LENGTH_LONG).show();
}
}
private void sendNotification(Context context) {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Blood Level Notification")
.setContentText(bloodLevel);
Intent resultIntent = new Intent(this, MyProfileActivity.class);
// Because clicking the notification opens a new ("special") activity,
// there's no need to create an artificial back stack.
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0,
resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
// Sets an ID for the notification
int mNotificationId = 001;
// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(mNotificationId, mBuilder.build());
}
public class BloodLevelParse extends
AsyncTask<String, Void, ArrayList<BloodLevels>> {
private Context myCtx;
public BloodLevelParse(Context ctx){
// Now set context
this.myCtx = ctx;
}
protected ArrayList<BloodLevels> doInBackground(String... params) {
String bloodType = params[0];
try {
// HTTP PROTOCOL
Document doc = Jsoup
.connect(
"http://www.giveblood.ie/Current_Blood_Supply/")
.timeout(5000)
.userAgent(
"Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
.cookie("auth", "token").get();
// EXTRACT SPECIFIC ELEMENTS FROM THE HTML
Elements bloodsupplylines1 = doc.select("td.bloodsupplyline");
Elements bloodsupplylines2 = bloodsupplylines1
.select("img[src~=(?i)\\.(png|jpe?g|gif)]");
// CREATE LIST AND POPULATE IT WITH ELEMENTS RETRIEVE FROM HTML
List<String> BloodLevelRawList = new ArrayList<String>();
for (Element bloodsupplyline : bloodsupplylines2) {
BloodLevelRawList.add(new String(bloodsupplyline
.attr("alt")));
}
BloodLevelList = new ArrayList<BloodLevels>();
for (int i = 0; i < BloodLevelRawList.size(); i += 2) {
// Only add to BloodLevelList if it is the blood type
// selected
if (BloodLevelRawList.get(i).equals(bloodType)) {
BloodLevelList.add(new BloodLevels(BloodLevelRawList
.get(i), BloodLevelRawList.get(i + 1)));
}
}
}
catch (IOException ioex) {
ioex.printStackTrace();
}
return BloodLevelList;
}
@Override
protected void onPostExecute(ArrayList<BloodLevels> BloodLevelList) {
String bloodLevelReplace = BloodLevelList.get(0).getBloodLevel()
.replaceAll("Blood supply", "");
bloodLevel = ("Current blood levels for "
+ BloodLevelList.get(0).getBloodType() + " is" + bloodLevelReplace);
// Get the number of days from the blood level string
Scanner in = new Scanner(bloodLevel).useDelimiter("[^0-9]+");
int bloodLevelDays = in.nextInt();
// Send notification if no. of days blood level supply goes below 5
if (bloodLevelDays < 5) {
TaskService taskService = new TaskService();
taskService.sendNotification(myCtx);
}
}
}
}
EDIT: В соответствии с ответом tyczj, я не нуждался в AsyncTask, глупый меня. Вот рабочая версия:
public class TaskService extends IntentService {
private ArrayList<BloodLevels> BloodLevelList;
private String bloodLevel;
private String bloodType;
private Integer bloodLevelDays;
public TaskService() {
super("TaskService");
}
@Override
protected void onHandleIntent(Intent intent) {
// Pass through the blood type from AlarmReceiver
Bundle bundle = intent.getExtras();
bloodType = bundle.getString("currentBloodType2");
// Only perform check if there is an internet connection
if (CheckNetwork.isInternetAvailable(TaskService.this)) {
try {
// HTTP PROTOCOL
Document doc = Jsoup
.connect(
"http://www.giveblood.ie/Current_Blood_Supply/")
.timeout(5000)
.userAgent(
"Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
.cookie("auth", "token").get();
// EXTRACT SPECIFIC ELEMENTS FROM THE HTML
Elements bloodsupplylines1 = doc.select("td.bloodsupplyline");
Elements bloodsupplylines2 = bloodsupplylines1
.select("img[src~=(?i)\\.(png|jpe?g|gif)]");
// CREATE LIST AND POPULATE IT WITH ELEMENTS RETRIEVE FROM HTML
List<String> BloodLevelRawList = new ArrayList<String>();
for (Element bloodsupplyline : bloodsupplylines2) {
BloodLevelRawList.add(new String(bloodsupplyline
.attr("alt")));
}
BloodLevelList = new ArrayList<BloodLevels>();
for (int i = 0; i < BloodLevelRawList.size(); i += 2) {
// Only add to BloodLevelList if it is the blood type
// selected
if (BloodLevelRawList.get(i).equals(bloodType)) {
BloodLevelList.add(new BloodLevels(BloodLevelRawList
.get(i), BloodLevelRawList.get(i + 1)));
}
}
}
catch (IOException ioex) {
ioex.printStackTrace();
}
String bloodLevelReplace = BloodLevelList.get(0).getBloodLevel()
.replaceAll("Blood supply", "");
bloodLevel = ("Current blood levels for "
+ BloodLevelList.get(0).getBloodType() + " is" + bloodLevelReplace);
// Get the number of days from the blood level string
Scanner in = new Scanner(bloodLevel).useDelimiter("[^0-9]+");
int bloodLevelDays = in.nextInt();
// Send notification if no. of days blood level supply goes below 5
if (bloodLevelDays < 5) {
this.sendNotification(this);
}
} else {
Toast.makeText(
TaskService.this,
"Unable to perform daily blood level check, no internet connection.",
Toast.LENGTH_LONG).show();
}
}
private void sendNotification(Context context) {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Blood Level Notification")
.setContentText(bloodLevel);
Intent resultIntent = new Intent(this, MyProfileActivity.class);
// Because clicking the notification opens a new ("special") activity,
// there's no need to create an artificial back stack.
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0,
resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
// Sets an ID for the notification
int mNotificationId = 001;
// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(mNotificationId, mBuilder.build());
}
}
Я попытался изменить его TaskService.this и я все еще получаю исключения нулевого указателя на намерение. Теперь, когда вы говорите, что асинтекс кажется довольно избыточным, я использовал его только потому, что когда я когда-либо удалял данные с веб-сайтов, я делаю это так? –
В какой строке вы получаете нуль? также удалите asynctask и просто создайте обычный метод. asynctask должен быть выполнен в основном потоке – tyczj
Хорошо, я попробую удалить асинтезу и затем отчитаться. –