Documente Academic
Documente Profesional
Documente Cultură
RAPORT
Lucrarea de laborator nr.2
Programarea aplicatiilor mobile
Tema: Organiser Mobile Application (DAILY PLANNER)
A efectuat:
st. gr. TI-153
A verificat:
asist. univ. C. Rusu
Chisinau 2017
Scopul lucrarii
De realizat aplicație tip Organiser pe platforma aleasă. La formarea și proiectarea aplicațiilor sunt
introduse puncte stricte, ce sunt obligatorii de respectat. La discreția personală rămâne designul aplicației
și API-ul/Framework-ul în care va fi dezvoltată lucrarea de laborator #2. Componentele și structura
fiecărei Activități va fi descrisă mai jos.
UI Components
Aplicația va conține minim 3 Activități de baza care vor fi numerotate în lucrare sub forma:
1. MainActivity (structura/componente)
Calendar View (custom or default)
Buttons (Add/Remove/Update)
Căutare (caută conform cuvintelor cheie)
2. AddtActivity
Data/Time controller
Info TextBox
Buttons și altele (la discreție conform specificului aplicației)
3. UpdateActivity - practic e una și aceeași activitate de la Add, doar ca completata deja.
Datele operaționale din interiorul aplicației vor fi stocate în fișier/e XML forma cărora rămâne la
discreția personală. (cuvinte cheie, XML Serialization).
Logical/Operational Component
Toate evenimentele și acțiunile de notificare/semnalizare (sonore/vizuale) intreprinse în Organiser
vor fi tratate într-un serviciu aparte, care logic funcțional va extrage datele din acel fișier XML.
1
Figura 1 – Pagina principala a aplicatiei
In figura 2 de mai joi este reprezentata activitatea unde utilizatorul creaza un eveniment nou.
Utilizatorul are 2 optiuni pentru evenimentul creat, el poate sa creeze evenimentul si sa seteze o anumita
ora sau data sau poate crea evenimentul fara data si ora. Iar daca utilizatorul doreste sa paraseasa
activitatea unde are loc crearea evenimentul trebuie doar sa apese butonul „X”.
In figura 3 este reprezentata activitatea unde are loc afisarea evenimentelor create anterior de catre
utilizator. Este afisat denumirea evenimentului, imaginea cu primul simbol din denumirea evenimentului si
daca a fost setata ora si data atunci ele sunt afisate mai jos de denumirea evenimentului, altfel va fi afisat
2
doar denumirea evenimentului. In toolbar-ul de sus sunt 2 optiuni, pentru cautarea unui eveniment si
afisarea calendarului cu evenimentele create iar mai jos este butonul de adaugarea a unui nou eveniment.
In figura 4 este activitatea unde are loc afisarea calendarului aplicatiei cu evenimentele create. In
dependenta de evenimentele create la care a fost setat data el va fi afisat in calendar la data respectiva. In
imaginea de mai jos se poate vedea ca pe data de 21 noiembrie au fost create 2 evenimente.
3
In figura 5 este aratat modul de functionare a butonului search. Care va afisa evenimetul daca dupa
ce vom introduce un caracter de exemplu caracterul „a” cum este aratat mai jos, atunci se vor afisa doar
acelea evenimente care contin acest caracter.
In figura 6 putem vedea notificarea care a aparut dupa un timp, ce evenimentul a fost creat si setat
data si ora ca mai apoi noi sa primim o notificare in privinta lui.In notificare putem vedea ca este afisat
numele evenimentului si ora care a fost stabilita pentru ca primim notificarea respectiva in privinta acestui
eveniment.
5
Bibliografie
1 Tutorial [Resursă electronică]. Regim de acces: https://www.youtube.com/
2 Material ajutator [Resursă electronică]. Regim de acces: https://stackoverflow.com/
3 Material ajutator [Resursă electronică]. Regim de acces: http://www.w3ii.com/ro/
6
Anexa
Codul sursa
MainActivity.java
package com.example.vicup.dailyplanner;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.view.MenuItemCompat; import
android.support.v7.app.AppCompatActivity; import
android.support.v7.widget.DefaultItemAnimator; import
android.support.v7.widget.LinearLayoutManager; import
android.support.v7.widget.RecyclerView; import
android.support.v7.widget.Toolbar;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.ArrayAdapter; import
android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONException;
7
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
8
}
}
return items;
@Override
protected void onResume() {
super.onResume();
app.send(this);
SharedPreferences sharedPreferences =
getSharedPreferences(SHARED_PREF_DATA_SET_CHANGED, MODE_PRIVATE);
if(sharedPreferences.getBoolean(ReminderActivity.EXIT, false)){
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean(ReminderActivity.EXIT,false);
editor.apply();
finish();
}
if(getSharedPreferences(THEME_PREFERENCES, MODE_PRIVATE).getBoolean(RECREATE_ACTIVITY,
false)){
SharedPreferences.Editor editor = getSharedPreferences(THEME_PREFERENCES,
MODE_PRIVATE).edit();
editor.putBoolean(RECREATE_ACTIVITY, false);
editor.apply();
recreate();
}
}
//calendar view
@Override
public boolean onCreateOptionsMenu(Menu menu)
{ getMenuInflater().inflate(R.menu.menu_main, menu);
//// Search /////
final MainActivity kr = this;
//mButtonSearch = (Button)findViewById(R.id.search);
9
searchView.setOnQueryTextListener(new
android.support.v7.widget.SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String newText)
{ return kk(newText);
}
@Override
public boolean onQueryTextChange(String newText)
{ return kk(newText);
}
private boolean kk(String c){
final String k = c;
kr.runOnUiThread(new Runnable() {
@Override
public void run() {
if (k.length() == 0){
kr.saveDate();
}
ArrayList<ToDoItem> dd = getLocallyStoredData(storeRetrieveData, k);
adapter = new BasicListAdapter(dd);
mRecyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
});
return true;
}
});
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.calendar:
Intent intent = new Intent(MainActivity.this, CalendarActivity.class);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
///////////////////
@Override
protected void onStart() {
app = (AnalyticsApplication)getApplication();
super.onStart();
SharedPreferences sharedPreferences =
getSharedPreferences(SHARED_PREF_DATA_SET_CHANGED, MODE_PRIVATE);
if(sharedPreferences.getBoolean(CHANGE_OCCURED, false)){
10
mToDoItemsArrayList = getLocallyStoredData(storeRetrieveData);
adapter = new BasicListAdapter(mToDoItemsArrayList);
mRecyclerView.setAdapter(adapter); setAlarms();
}
}
private void setAlarms(){
if(mToDoItemsArrayList!=null){
for(ToDoItem item : mToDoItemsArrayList)
{ if(item.hasReminder() && item.getToDoDate()!=null){
if(item.getToDoDate().before(new Date())){
item.setToDoDate(null);
continue;
}
Intent i = new Intent(this, TodoNotificationService.class);
i.putExtra(TodoNotificationService.TODOUUID, item.getIdentifier());
i.putExtra(TodoNotificationService.TODOTEXT, item.getToDoText());
createAlarm(i, item.getIdentifier().hashCode(),
item.getToDoDate().getTime());
}
}
}
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences sharedPreferences =
getSharedPreferences(SHARED_PREF_DATA_SET_CHANGED, MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean(CHANGE_OCCURED, false); editor.apply();
11
storeRetrieveData = new StoreRetrieveData(this, FILENAME);
mToDoItemsArrayList = getLocallyStoredData(storeRetrieveData);
adapter = new BasicListAdapter(mToDoItemsArrayList);
setAlarms();
mCoordLayout = (CoordinatorLayout)findViewById(R.id.myCoordinatorLayout);
mAddToDoItemFAB = (FloatingActionButton)findViewById(R.id.addToDoItemFAB);
mAddToDoItemFAB.setOnClickListener(new View.OnClickListener() {
@SuppressWarnings("deprecation")
@Override
public void onClick(View v) {
app.send(this, "Action", "FAB pressed");
Intent newTodo = new Intent(MainActivity.this, AddToDoActivity.class);
ToDoItem item = new ToDoItem("", false, null);
int color = ColorGenerator.MATERIAL.getRandomColor();
item.setTodoColor(color);
newTodo.putExtra(TODOITEM, item);
startActivityForResult(newTodo, REQUEST_ID_TODO_ITEM);
}
});
mRecyclerView = (RecyclerViewEmptySupport)findViewById(R.id.toDoRecyclerView);
if(theme.equals(LIGHTTHEME)){
mRecyclerView.setBackgroundColor(getResources().getColor(R.color.primary_lightest));
}
mRecyclerView.setEmptyView(findViewById(R.id.toDoEmptyView));
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
12
mAddToDoItemFAB.animate().translationY(0).setInterpolator(new
DecelerateInterpolator(2)).start();
}
@Override
public void hide() {
CoordinatorLayout.LayoutParams lp =
(CoordinatorLayout.LayoutParams)mAddToDoItemFAB.getLayoutParams();
int fabMargin = lp.bottomMargin;
mAddToDoItemFAB.animate().translationY(mAddToDoItemFAB.getHeight()+fabMargin).setInterpolator( new
AccelerateInterpolator(2.0f)).start();
}
};
mRecyclerView.addOnScrollListener(customRecyclerScrollViewListener);
ItemTouchHelper.Callback callback = new ItemTouchHelperClass(adapter);
itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(mRecyclerView);
mRecyclerView.setAdapter(adapter);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{ if(resultCode!= RESULT_CANCELED && requestCode == REQUEST_ID_TODO_ITEM){ ToDoItem
item =(ToDoItem) data.getSerializableExtra(TODOITEM);
if(item.getToDoText().length()<=0){
return;
}
boolean existed = false;
for(int i = 0; i<mToDoItemsArrayList.size();i++){
if(item.getIdentifier().equals(mToDoItemsArrayList.get(i).getIdentifier())){
mToDoItemsArrayList.set(i, item);
existed = true;
adapter.notifyDataSetChanged();
break;
}
}
if(!existed) {
addToDataStore(item);
}
13
}
}
private AlarmManager getAlarmManager(){
return (AlarmManager)getSystemService(ALARM_SERVICE);
}
private boolean doesPendingIntentExist(Intent i, int requestCode)
{ PendingIntent pi = PendingIntent.getService(this,requestCode,
i,
PendingIntent.FLAG_NO_CREATE);
return pi!=null;
}
private void createAlarm(Intent i, int requestCode, long timeInMillis){
AlarmManager am = getAlarmManager();
PendingIntent pi = PendingIntent.getService(this,requestCode, i,
PendingIntent.FLAG_UPDATE_CURRENT);
am.set(AlarmManager.RTC_WAKEUP, timeInMillis, pi);
}
private void deleteAlarm(Intent i, int requestCode){
if(doesPendingIntentExist(i, requestCode)){
PendingIntent pi = PendingIntent.getService(this, requestCode,i,
PendingIntent.FLAG_NO_CREATE);
pi.cancel();
getAlarmManager().cancel(pi);
Log.d("dailyplanner", "PI Cancelled " + doesPendingIntentExist(i, requestCode));
}
}
private void addToDataStore(ToDoItem item){
mToDoItemsArrayList.add(item);
adapter.notifyItemInserted(mToDoItemsArrayList.size() - 1);
}
public void makeUpItems(ArrayList<ToDoItem> items, int len){
for (String testString : testStrings) {
ToDoItem item = new ToDoItem(testString, false, new Date());
items.add(item);
}
}
public class BasicListAdapter extends RecyclerView.Adapter<BasicListAdapter.ViewHolder>
implements ItemTouchHelperClass.ItemTouchHelperAdapter{
private ArrayList<ToDoItem> items;
@Override
public void onItemMoved(int fromPosition, int toPosition)
{ if(fromPosition<toPosition){
for(int i=fromPosition; i<toPosition; i++){
Collections.swap(items, i, i+1);
}
}
else{
for(int i=fromPosition; i > toPosition; i--){
Collections.swap(items, i, i-1);
14
}
}
notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onItemRemoved(final int position)
{ app.send(this, "Action", "Swiped Plan Away");
mJustDeletedToDoItem = items.remove(position);
mIndexOfDeletedToDoItem = position;
Intent i = new Intent(MainActivity.this,TodoNotificationService.class);
deleteAlarm(i, mJustDeletedToDoItem.getIdentifier().hashCode());
notifyItemRemoved(position);
String toShow = "Plan";
Snackbar.make(mCoordLayout, "Deleted "+toShow,Snackbar.LENGTH_SHORT)
.setAction("UNDO", new View.OnClickListener()
{ @Override
public void onClick(View v) {
app.send(this, "Action", "UNDO Pressed");
items.add(mIndexOfDeletedToDoItem, mJustDeletedToDoItem);
if(mJustDeletedToDoItem.getToDoDate()!=null &&
mJustDeletedToDoItem.hasReminder()){
Intent i = new Intent(MainActivity.this,
TodoNotificationService.class);
i.putExtra(TodoNotificationService.TODOTEXT,
mJustDeletedToDoItem.getToDoText());
i.putExtra(TodoNotificationService.TODOUUID,
mJustDeletedToDoItem.getIdentifier());
createAlarm(i,
mJustDeletedToDoItem.getIdentifier().hashCode(),
mJustDeletedToDoItem.getToDoDate().getTime());
}
notifyItemInserted(mIndexOfDeletedToDoItem);
}
}).show();
}
@Override
public BasicListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View v =
LayoutInflater.from(parent.getContext()).inflate(R.layout.list_circle_try, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(final BasicListAdapter.ViewHolder holder, final
int position) {
15
ToDoItem item = items.get(position);
SharedPreferences sharedPreferences = getSharedPreferences(THEME_PREFERENCES,
MODE_PRIVATE);
int bgColor;
int todoTextColor;
if(sharedPreferences.getString(THEME_SAVED, LIGHTTHEME).equals(LIGHTTHEME))
{ bgColor = Color.WHITE;
todoTextColor = getResources().getColor(R.color.secondary_text);
}
else{
bgColor = Color.DKGRAY;
todoTextColor = Color.WHITE;
}
holder.linearLayout.setBackgroundColor(bgColor);
16
@Override
public int getItemCount() {
return items.size();
}
BasicListAdapter(ArrayList<ToDoItem> items){
this.items = items;
}
View mView;
LinearLayout linearLayout;
TextView mToDoTextview;
ImageView mColorImageView;
TextView mTimeTextView;
}
}
17
@Override
protected void onPause() {
super.onPause();
try {
storeRetrieveData.saveToFile(mToDoItemsArrayList);
} catch (JSONException | IOException e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mRecyclerView.removeOnScrollListener(customRecyclerScrollViewListener);
}
}
22