アプリを作っています。場所 - タスクのリマインダーとして。ユーザーが特定の場所に到達すると、その場所に関連するタスクが存在する場合、ユーザーはそのタスクの残りを取得します。
アプリの半分以上を完了しました。ユーザーがその場所にいるときにタスクを表示できますが、手動です。ユーザーはアプリを開いて手動で確認する必要があります。
Notifications
私の質問は、ユーザーが特定の場所に到達したときにそのタスクをポップアップする方法です。ここはBroadcast Receiver
必須ですか?そして、それをService
これは私のコードです。リストに場所のタスクを表示するためだけのものです。この NotificationManger の使用方法では、現在の場所が更新されていないため、サービスも必要だと思います...!
public class ViewTasksActivity extends ListActivity implements LocationListener {
protected static final long LOCATION_FILTER_DISTANCE = 1000;
private Button addButton;
private Button removeButton;
private TaskManagerApplication app;
private TaskListAdapter adapter;
private LocationManager locationManager;
private Location latestLocation;
private TextView locationText;
private ToggleButton localTasksToggle;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setUpViews();
app=(TaskManagerApplication)getApplication();
adapter=new TaskListAdapter(app.getCurrentTasks(),this);
setListAdapter(adapter);
setUpLocation();
LocationManager locManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000L,500.0f, this);
Location location = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
latestLocation=location;
String locationString=String.format(" @%f, %f ,%s",
location.getLatitude(),
location.getLongitude(),
location.getProvider());
locationText.setText(locationString);
Toast.makeText(getApplicationContext(),locationString, Toast.LENGTH_LONG).show();
}
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER , 60,5,this);
locationManager.removeUpdates(this);
adapter.forceReload();
}
@Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
adapter.toggleTaskCompleteAtPosition(position);
Task t=adapter.getItem(position);
app.saveTask(t);
}
protected void removeCompletedTasks() {
Long[] ids=adapter.removeCompletedTasks();
app.deleteTasks(ids);
}
private void setUpLocation() {
locationManager=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER , 60,5,this);
}
private void setUpViews() {
// TODO Auto-generated method stub
addButton=(Button)findViewById(R.id.add_button);
removeButton=(Button)findViewById(R.id.remove_button);
locationText=(TextView)findViewById(R.id.location_text);
localTasksToggle=(ToggleButton)findViewById(R.id.show_local_task_toggle);
addButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i=new Intent(ViewTasksActivity.this,AddTaskActivity.class);
startActivity(i);
}
});
removeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
removeCompletedTasks();
}
});
localTasksToggle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showLocalTasks(localTasksToggle.isChecked());
}
private void showLocalTasks(boolean checked) {
if(checked){
adapter.filterTasksByLocation( latestLocation,LOCATION_FILTER_DISTANCE);
}else
{
adapter.removeLocationFilter();
}
}
});
}
public void onLocationChanged(Location location) {}
/* latestLocation=location;
String locationString=String.format(" @ %f,%f +/-% fm ",
location.getLatitude(),
location.getLongitude(),
location.getAccuracy());
locationText.setText(locationString);
}
以下の別のアクティビティ:
public class TaskListAdapter extends BaseAdapter {
private ArrayList<Task> tasks;
private Context context;
private ArrayList<Task> filterTasks;
private ArrayList<Task> unfilteredTasks;
public TaskListAdapter(ArrayList<Task> tasks, Context context) {
this.tasks = tasks;
this.unfilteredTasks=tasks;
this.context = context;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return tasks.size();
}
@Override
public Task getItem(int position) {
// TODO Auto-generated method stub
return (null==tasks)?null:tasks.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TaskListItem tli;
if(null==convertView){
tli=(TaskListItem)View.inflate(context, R.layout.task_list_item,null);
}else
{
tli=(TaskListItem)convertView;
}
tli.setTask(tasks.get(position));
return tli;
}
public void forceReload() {
notifyDataSetChanged();
}
public void toggleTaskCompleteAtPosition(int position) {
Task t=tasks.get(position);
t.toggleComplete();
notifyDataSetChanged();
}
public Long[] removeCompletedTasks() {
ArrayList<Task> completedTasks=new ArrayList<Task>();
ArrayList<Long> completedIds=new ArrayList<Long>();
for(Task task : tasks){
if(task.isComplete()){
completedIds.add(task.getId());
completedTasks.add(task);
}
}
tasks.removeAll(completedTasks);
notifyDataSetChanged();
return completedIds.toArray(new Long[]{});
}
public void filterTasksByLocation(Location latestLocation, long locationFilterDistance) {
filterTasks=new ArrayList<Task>();
for(Task task:tasks){
if(task.hasLocation() && taskIsWithinGeofence(task,latestLocation,locationFilterDistance)){
filterTasks.add(task);//chking all tasks with location tasks
Toast.makeText(context, task.getName(), Toast.LENGTH_LONG).show();//displaying name of the tasks(as per location)
}
}
tasks=filterTasks;
notifyDataSetChanged();
}
private boolean taskIsWithinGeofence(Task task, Location latestLocation,
long locationFilterDistance) {
float[] distanceArray=new float[1];
Location.distanceBetween(
task.getLatitude(),
task.getLongitude(),
latestLocation.getLatitude(),
latestLocation.getLongitude(),
distanceArray);
return (distanceArray[0]<locationFilterDistance);
}
public void removeLocationFilter() {
tasks=unfilteredTasks;
notifyDataSetChanged();
}
}
また問題は、アプリがバックグラウンドで実行されていないことです。場所は、アプリを起動したときにのみ更新されます。ちょっと助けてくれてありがとう...