commit 0a593484b4a0bf3b6ee69ea1b584862198b98fdd Author: Reynaldo Reyes Date: Sun Mar 13 22:59:33 2016 -0430 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..afbdab3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..47da7fc --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +Attendance Scanner Application \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..217af47 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..e206d70 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..325b0a4 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..fc2d64b --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..06c50d7 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml new file mode 100644 index 0000000..922003b --- /dev/null +++ b/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..f3710d7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/AttendanceScannerApplication.iml b/AttendanceScannerApplication.iml new file mode 100644 index 0000000..28b2f74 --- /dev/null +++ b/AttendanceScannerApplication.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/app.iml b/app/app.iml new file mode 100644 index 0000000..67fb37b --- /dev/null +++ b/app/app.iml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..860f62e --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,27 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 21 + buildToolsVersion "21.1.2" + + defaultConfig { + applicationId "com.example.masa.attendancescannerapplication" + minSdkVersion 8 + targetSdkVersion 10 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.android.support:appcompat-v7:21.0.3' + + +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..c707bc6 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in C:\Users\Masa\AppData\Local\Android\android-studio1\sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/androidTest/java/com/example/masa/massiveattendancescannerapplication/ApplicationTest.java b/app/src/androidTest/java/com/example/masa/massiveattendancescannerapplication/ApplicationTest.java new file mode 100644 index 0000000..e9be797 --- /dev/null +++ b/app/src/androidTest/java/com/example/masa/massiveattendancescannerapplication/ApplicationTest.java @@ -0,0 +1,13 @@ +package com.example.masa.massiveattendancescannerapplication; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..27d542a --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/com/example/masa/massiveattendancescannerapplication/CourseActivity.java b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/CourseActivity.java new file mode 100644 index 0000000..a62d52b --- /dev/null +++ b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/CourseActivity.java @@ -0,0 +1,159 @@ +package com.example.masa.massiveattendancescannerapplication; + + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.apache.http.NameValuePair; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.app.ListActivity; +import android.app.ProgressDialog; +import android.content.Intent; +import android.os.AsyncTask; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.SimpleAdapter; +import android.widget.TextView; + +import com.example.masa.massiveattendancescannerapplication.Services.JSONParser; +import com.example.masa.massiveattendancescannerapplication.Services.ServiceHandler; + +public class CourseActivity extends ListActivity { + + private ProgressDialog pDialog; + JSONParser jsonParser = new JSONParser(); + ArrayList> courseList; + JSONArray course = null; + private static final String URL = "http://192.168.0.101:3000/courses"; + // ALL JSON node names + private static final String TAG_ID = "_id"; + private static final String TAG_NAME = "name"; + private static final String TAG_CODE = "code"; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.course_activity); + + + courseList = new ArrayList>(); + new LoadCourses().execute(); + + ListView lv = getListView(); + + /** + * Listview item click listener + * SectionActivity will be lauched by passing album id + * */ + lv.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView arg0, View view, int arg2, + long arg3) { + // on selecting a single album + // SectionActivity will be launched to show tracks inside the album + Intent i = new Intent(getApplicationContext(), SectionActivity.class); + + // send album id to tracklist activity to get list of songs under that album + String course_id = ((TextView) view.findViewById(R.id.course_id)).getText().toString(); + i.putExtra("course_id", course_id); + + startActivity(i); + } + }); + } + + /** + * Background Async Task to Load all Courses by making http request + * */ + class LoadCourses extends AsyncTask { + + /** + * Before starting background thread Show Progress Dialog + * */ + @Override + protected void onPreExecute() { + super.onPreExecute(); + pDialog = new ProgressDialog(CourseActivity.this); + pDialog.setMessage("Cargando Materias ..."); + pDialog.setIndeterminate(false); + pDialog.setCancelable(false); + pDialog.show(); + } + + /** + * getting Courses JSON + * */ + protected String doInBackground(String... args) { + + List params = new ArrayList(); + ServiceHandler sh = new ServiceHandler(); + String JSONString = null; + try { + JSONString = sh.getServiceCall(URL); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + course = new JSONArray(JSONString); + + // looping through All courses + for (int i = 0; i < course.length(); i++) { + JSONObject c = course.getJSONObject(i); + + // Storing each json item values in variable + String id = c.getString(TAG_ID); + String name = c.getString(TAG_NAME); + String code = c.getString(TAG_CODE); + + // creating new HashMap + HashMap map = new HashMap(); + + // adding each child node to HashMap key => value + map.put(TAG_ID, id); + map.put(TAG_NAME, name); + map.put(TAG_CODE, code); + + // adding HashList to ArrayList + courseList.add(map); + } + + } catch (JSONException e) { + e.printStackTrace(); + } + + return null; + } + + /** + * After completing background task Dismiss the progress dialog + * **/ + protected void onPostExecute(String file_url) { + // dismiss the dialog after getting all courses + pDialog.dismiss(); + // updating UI from Background Thread + runOnUiThread(new Runnable() { + public void run() { + /** + * Updating parsed JSON data into ListView + * */ + ListAdapter adapter = new SimpleAdapter( + CourseActivity.this, courseList, + R.layout.list_item_courses, new String[] { TAG_ID, + TAG_NAME, TAG_CODE }, new int[] { + R.id.course_id, R.id.course_name, R.id.course_code }); + setListAdapter(adapter); + } + }); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Data/Course.java b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Data/Course.java new file mode 100644 index 0000000..30fe742 --- /dev/null +++ b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Data/Course.java @@ -0,0 +1,41 @@ +package com.example.masa.massiveattendancescannerapplication.Data; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +public class Course{ + + public String name; + public String code; + public List
section; + + public Course (String _name, String _code, List
_section){ + name = _name; + code = _code; + section = _section; + } + + public static Course createFromJSON(JSONObject json) throws JSONException { + + List
qSections = new ArrayList<>(); + String name = json.getString("name"); + String code = json.getString("code"); + + + if (json.has("Sections")){ + JSONArray sections = json.getJSONArray("Sections"); + + for (int k = 0; k < sections.length(); k++) + { + qSections.add(Section.createFromJSON(sections.getJSONObject(k))); + } + } + return new Course(name, code,qSections); + } + +} + diff --git a/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Data/Section.java b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Data/Section.java new file mode 100644 index 0000000..ef231dd --- /dev/null +++ b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Data/Section.java @@ -0,0 +1,41 @@ +package com.example.masa.massiveattendancescannerapplication.Data; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +public class Section { + + public String name; + public String semester; + public List student; + + public Section (String _name, String _semester, List _student){ + name = _name; + semester = _semester; + student = _student; + } + + public static Section createFromJSON(JSONObject json) throws JSONException { + + String name = json.getString("name"); + String semester = json.getString("semester"); + List qStudents = new ArrayList(); + + + if (json.has("Students")){ + JSONArray students = json.getJSONArray("Students"); + + for (int k = 0; k < students.length(); k++) + { + qStudents.add(Student.createFromJSON(students.getJSONObject(k))); + } + } + return new Section(name, semester, qStudents); + } + + +} diff --git a/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Data/Student.java b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Data/Student.java new file mode 100644 index 0000000..b9bf79f --- /dev/null +++ b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Data/Student.java @@ -0,0 +1,30 @@ +package com.example.masa.massiveattendancescannerapplication.Data; + +import org.json.JSONException; +import org.json.JSONObject; + +public class Student { + + public String id; + public String name; + public String lastname; + public String btAddress; + + public Student (String _id, String _name, String _lastname, String _btAddress){ + id = _id; + name = _name; + lastname = _lastname; + btAddress = _btAddress; + } + + public static Student createFromJSON(JSONObject json) throws JSONException { + + String id = json.getString("id"); + String name = json.getString("name"); + String lastname = json.getString("lastname"); + String btAddress = json.getString("btAddress"); + + return new Student(id, name, lastname, btAddress); + } + +} diff --git a/app/src/main/java/com/example/masa/massiveattendancescannerapplication/MainActivity.java b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/MainActivity.java new file mode 100644 index 0000000..563bdf9 --- /dev/null +++ b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/MainActivity.java @@ -0,0 +1,62 @@ +package com.example.masa.massiveattendancescannerapplication; + +import android.support.v7.app.ActionBarActivity; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.content.Intent; +import android.bluetooth.BluetoothAdapter; + + +public class MainActivity extends ActionBarActivity { + + public static final int REQUEST_ENABLE_BT = 1; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + } + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + if (id == R.id.action_settings) { + return true; + } + return super.onOptionsItemSelected(item); + } + + //Called when the user clicks on Scan + public void scanPhones (View view) { + + BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if (mBluetoothAdapter == null) { + // Device does not support Bluetooth + } + + if (!mBluetoothAdapter.isEnabled()) { + Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); + startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); + } + Intent intent = new Intent(this, ScanActivity.class); + startActivity(intent); + } + //Called when the user clicks on Listar Materias + public void adminScreen (View view) { + Intent intent = new Intent(this, CourseActivity.class); + startActivity(intent); + } +} diff --git a/app/src/main/java/com/example/masa/massiveattendancescannerapplication/ScanActivity.java b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/ScanActivity.java new file mode 100644 index 0000000..fbdd3d4 --- /dev/null +++ b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/ScanActivity.java @@ -0,0 +1,111 @@ +package com.example.masa.massiveattendancescannerapplication; + + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +public class ScanActivity extends Activity { + + private static final int REQUEST_ENABLE_BT = 1; + + ListView listDevicesFound; + Button btnScanDevice; + TextView stateBluetooth; + BluetoothAdapter bluetoothAdapter; + + ArrayAdapter btArrayAdapter; + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_scan); + + btnScanDevice = (Button)findViewById(R.id.scandevice); + + stateBluetooth = (TextView)findViewById(R.id.bluetoothstate); + bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + + listDevicesFound = (ListView)findViewById(R.id.devicesfound); + btArrayAdapter = new ArrayAdapter(ScanActivity.this, android.R.layout.simple_list_item_1); + listDevicesFound.setAdapter(btArrayAdapter); + + CheckBlueToothState(); + + btnScanDevice.setOnClickListener(btnScanDeviceOnClickListener); + + registerReceiver(ActionFoundReceiver, + new IntentFilter(BluetoothDevice.ACTION_FOUND)); + } + + @Override + protected void onDestroy() { + // TODO Auto-generated method stub + super.onDestroy(); + unregisterReceiver(ActionFoundReceiver); + } + + private void CheckBlueToothState(){ + if (bluetoothAdapter == null){ + stateBluetooth.setText("Bluetooth NOT supported"); + }else{ + if (bluetoothAdapter.isEnabled()){ + if(bluetoothAdapter.isDiscovering()){ + stateBluetooth.setText("Bluetooth is currently in device discovery process."); + }else{ + stateBluetooth.setText("Bluetooth is Enabled."); + btnScanDevice.setEnabled(true); + } + }else{ + stateBluetooth.setText("Bluetooth is NOT Enabled!"); + Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); + startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); + } + } + } + + private Button.OnClickListener btnScanDeviceOnClickListener + = new Button.OnClickListener(){ + + @Override + public void onClick(View arg0) { + // TODO Auto-generated method stub + btArrayAdapter.clear(); + bluetoothAdapter.startDiscovery(); + }}; + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // TODO Auto-generated method stub + if(requestCode == REQUEST_ENABLE_BT){ + CheckBlueToothState(); + } + } + + private final BroadcastReceiver ActionFoundReceiver = new BroadcastReceiver(){ + + @Override + public void onReceive(Context context, Intent intent) { + // TODO Auto-generated method stub + String action = intent.getAction(); + if(BluetoothDevice.ACTION_FOUND.equals(action)) { + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + Toast.makeText(getApplicationContext(), "FOUND THEM!", Toast.LENGTH_SHORT).show(); + btArrayAdapter.add(device.getName() + "\n" + device.getAddress()); + btArrayAdapter.notifyDataSetChanged(); + } + }}; + +} diff --git a/app/src/main/java/com/example/masa/massiveattendancescannerapplication/SectionActivity.java b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/SectionActivity.java new file mode 100644 index 0000000..3e2bfc3 --- /dev/null +++ b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/SectionActivity.java @@ -0,0 +1,161 @@ +package com.example.masa.massiveattendancescannerapplication; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.apache.http.NameValuePair; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.app.ListActivity; +import android.app.ProgressDialog; +import android.content.Intent; +import android.os.AsyncTask; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.SimpleAdapter; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.masa.massiveattendancescannerapplication.Services.JSONParser; +import com.example.masa.massiveattendancescannerapplication.Services.ServiceHandler; + +public class SectionActivity extends ListActivity { + + private ProgressDialog pDialog; + JSONParser jsonParser = new JSONParser(); + ArrayList> sectionList; + JSONArray courses = null; + String course_id, course_name; + private static final String URL = "http://192.168.0.101:3000/sections"; + private static final String TAG_ID = "_id"; + private static final String TAG_NAME = "name"; + private static final String TAG_SEMESTER = "semester"; + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.section_activity); + + Intent i = getIntent(); + course_id = i.getStringExtra("course_id"); + sectionList = new ArrayList>(); + new LoadSections().execute(); + ListView lv = getListView(); + + /** + * Listview on item click listener + * StudentActivity will be lauched by passing album id, song id + * */ + lv.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView arg0, View view, int arg2, + long arg3) { + // On selecting single track get song information + Intent i = new Intent(getApplicationContext(), StudentActivity.class); + + // to get song information + // both album id and song is needed + String course_id = ((TextView) view.findViewById(R.id.course_id)).getText().toString(); + String section_id = ((TextView) view.findViewById(R.id.section_id)).getText().toString(); + + i.putExtra("course_id", course_id); + i.putExtra("section_id", section_id); + + startActivity(i); + } + }); + + } + + class LoadSections extends AsyncTask { + + /** + * Before starting background thread Show Progress Dialog + * */ + @Override + protected void onPreExecute() { + super.onPreExecute(); + pDialog = new ProgressDialog(SectionActivity.this); + pDialog.setMessage("Cargando Secciones ..."); + pDialog.setIndeterminate(false); + pDialog.setCancelable(false); + pDialog.show(); + } + + + protected String doInBackground(String... args) { + // Building Parameters + List params = new ArrayList(); + ServiceHandler sh = new ServiceHandler(); + String JSONString = null; + try { + JSONString = sh.getServiceCall(URL); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + JSONArray sections = new JSONArray(JSONString); + + for (int i = 0; i < sections.length(); i++) { + JSONObject c = sections.getJSONObject(i); + + String section_id = c.getString(TAG_ID); + String section_no = String.valueOf(i + 1); + String name = c.getString(TAG_NAME); + String semester = c.getString(TAG_SEMESTER); + + // creating new HashMap + HashMap map = new HashMap(); + + map.put("course_id", course_id); + map.put(TAG_ID, section_id); + map.put("section_no", section_no + "."); + map.put(TAG_NAME, name); + map.put(TAG_SEMESTER, semester); + + // adding HashList to ArrayList + sectionList.add(map); + } + + } catch (JSONException e) { + e.printStackTrace(); + } + + return null; + } + + /** + * After completing background task Dismiss the progress dialog + * **/ + protected void onPostExecute(String file_url) { + // dismiss the dialog after getting all tracks + pDialog.dismiss(); + // updating UI from Background Thread + runOnUiThread(new Runnable() { + public void run() { + /** + * Updating parsed JSON data into ListView + * */ + ListAdapter adapter = new SimpleAdapter( + SectionActivity.this, sectionList, + R.layout.list_item_sections, new String[] { "course_id", TAG_ID, "track_no", + TAG_NAME, TAG_SEMESTER }, new int[] { + R.id.course_id, R.id.section_id, R.id.section_no, R.id.section_name, R.id.section_semester }); + setListAdapter(adapter); + setTitle(course_name); + } + }); + + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Services/CourseAdapter.java b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Services/CourseAdapter.java new file mode 100644 index 0000000..f09766e --- /dev/null +++ b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Services/CourseAdapter.java @@ -0,0 +1,37 @@ +package com.example.masa.massiveattendancescannerapplication.Services; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; + +import com.example.masa.massiveattendancescannerapplication.Data.Course; +import com.example.masa.massiveattendancescannerapplication.R; + +import java.util.ArrayList; + +public class CourseAdapter extends ArrayAdapter { + public CourseAdapter(Context context, ArrayList courses) { + super(context, 0, courses); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + // Get the data item for this position + Course course = getItem(position); + // Check if an existing view is being reused, otherwise inflate the view + if (convertView == null) { + convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_course, parent, false); + } + // Lookup view for data population + TextView Name = (TextView) convertView.findViewById(R.id.Name); + TextView Code = (TextView) convertView.findViewById(R.id.Code); + // Populate the data into the template view using the data object + Name.setText(course.name); + Code.setText(course.code); + // Return the completed view to render on screen + return convertView; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Services/FileReader.java b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Services/FileReader.java new file mode 100644 index 0000000..7921067 --- /dev/null +++ b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Services/FileReader.java @@ -0,0 +1,98 @@ +package com.example.masa.massiveattendancescannerapplication.Services; + +import android.content.Context; +import android.os.Environment; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +/** + *

+ * Function that parses a file to get a URL direction. The text files must be placed inside the + * \Android\data\com.smartmatic.sitesurvey\files\ folder to be able to read them. + *

+ * + * @author Reynaldo + */ +public class FileReader { + + static String response; + private static final String professors = "professors.txt"; + private static final String courses = "courses.txt"; + private static final String sections = "sections.txt"; + private static final String students = "students.txt"; + + /** + *

+ * This function returns the URL direction parsed from the .txt file contained in the phone. + *

+ * @param context Application Context. + * @param method Method representing POST of GET methods. + * @return String containing the URL. + */ + public static String getUrl(Context context, int method) { + try { + return parse(getConfigFile(context,method)); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + + /** + *

+ * This function handles the type of method of connecting (POST and GET) returning the URL + * direction for each type. + *

+ * @param context Application Context. + * @param method Method representing POST of GET methods. + * @return BufferedReader containing the information inside the file. + */ + private static BufferedReader getConfigFile(Context context,int method) { + if(isExternalStorageReadable()){ + // Get the directory for the app's private files + File file = null; + try { + if(method == 1) file = new File(context.getExternalFilesDir(null), professors); + if(method == 2) file = new File(context.getExternalFilesDir(null), courses); + if(method == 3) file = new File(context.getExternalFilesDir(null), sections); + if(method == 4) file = new File(context.getExternalFilesDir(null), students); + + if (file!=null) { + java.io.FileReader fr = new java.io.FileReader(file); + return new BufferedReader(fr); + }else{ + return null; + } + + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + return null; + } + + // Checks if external storage is available to at least read + private static boolean isExternalStorageReadable() { + String state = Environment.getExternalStorageState(); + return Environment.MEDIA_MOUNTED.equals(state) || + Environment.MEDIA_MOUNTED_READ_ONLY.equals(state); + } + + private static String parse(BufferedReader reader) throws IOException { + try { + String line = reader.readLine(); + while(line != null){ + response = line; + line = reader.readLine(); + } + return response; + } finally { + reader.close(); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Services/JSONParser.java b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Services/JSONParser.java new file mode 100644 index 0000000..916a24c --- /dev/null +++ b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Services/JSONParser.java @@ -0,0 +1,70 @@ +package com.example.masa.massiveattendancescannerapplication.Services; + +import com.example.masa.massiveattendancescannerapplication.Data.Course; +import com.example.masa.massiveattendancescannerapplication.Data.Section; + +import java.io.IOException; +import java.util.*; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +/**

+ * This class parses a JSON Object which is received from the Main Activity. + * The methods in this class are private except for GetQuestionary(),which is the main call for + * this class to parse,fill the questions objects and return an ArrayList consisting of several + * question objects that later are used to construct the survey. + *

+ * @author Reynaldo + */ + +public class JSONParser { + + public static ArrayList getCourses(String JSONString) { + + try { + return parse(JSONString); + } catch (JSONException e) { + e.printStackTrace(); + } + return null; + } + + private static ArrayList parse(String JSONString) throws JSONException { + try { + JSONArray json = new JSONArray(JSONString); + return readFile(json); + } catch (JSONException | IOException e) { + e.printStackTrace(); + } + return null; + } + + /**

+ * This function receives a JSON object and parses trough all the elements until a Course + * tag is reached. The JSON object contains various nested JSON Arrays that represent + * different levels of the survey info, such as Courses, Sections, and Students, + * these arrays must be parsed in order to reach the courses that are needed to construct + * the list. Once the Course tag is reached, the function calls + * readCourses(JSON Object). + *

+ * + * @param json a JsonObject containing Courses info. + * @return an ArrayList containing various course objects. + * @throws JSONException if JSON object is empty or null. + */ + + private static ArrayList readFile(JSONArray json) throws IOException, JSONException { + + //final String DATA = "Courses"; + ArrayList qCourses = new ArrayList<>(); + //if (json.has(DATA)) { + //JSONArray courses = json.getJSONArray(DATA); + for (int h = 0; h < json.length(); h++) { + qCourses.add(Course.createFromJSON(json.getJSONObject(h))); + } + //} + return qCourses; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Services/ServiceHandler.java b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Services/ServiceHandler.java new file mode 100644 index 0000000..38cc5c2 --- /dev/null +++ b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/Services/ServiceHandler.java @@ -0,0 +1,111 @@ +package com.example.masa.massiveattendancescannerapplication.Services; +import android.util.Log; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.json.JSONArray; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; + +/** + *

+ * This class creates a URL connection to a host, and GETs or POSTs a JSON object containing + * survey information. + *

+ * @author Reynaldo + */ + +@SuppressWarnings("ALL") +public class ServiceHandler { + + static String response; + public ServiceHandler() { + } + /** + *

+ * This function receives a URL direction and a method of connection, connects to a host + * through the url and receives a JSON Object. + *

+ * @param url url to establish a connection. + * @return a String response containing the JSON Object. + * @throws IOException if the InputStream is null. + * @author Reynaldo + */ + public String getServiceCall(String url) throws IOException { + response = ""; + try { + URL urlUp = new URL(url); + URLConnection conn = urlUp.openConnection(); + InputStream is = conn.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); + String data = ""; + + while ((data = reader.readLine()) != null) { + response += data; + } + + } catch (IOException e) { + e.printStackTrace(); + } + return response; + } + + /** + *

+ * This function receives a URL direction and a JSON object, connects to a host + * through the url and sends the JSON Object. + *

+ * @param url url to establish a connection. + * @return a boolean in case of successful POST. + * @throws IOException if the InputStream is null. + * @author Reynaldo + */ + + public boolean postServiceCall(String url, JSONArray jsonArray) throws IOException { + int inputStream; + response=""; + try { + HttpClient httpclient = new DefaultHttpClient(); + HttpPost httpPost = new HttpPost(url); + + String json = jsonArray.toString(); + StringEntity se = new StringEntity(json); + httpPost.setEntity(se); + httpPost.setHeader("Accept", "application/json"); + httpPost.setHeader("Content-type", "application/json"); + HttpResponse httpResponse = httpclient.execute(httpPost); + inputStream = httpResponse.getStatusLine().getStatusCode(); + if (inputStream == 200){ + return true; + }else { + return false; + } + + + } catch (Exception e) { + Log.d("InputStream", e.getLocalizedMessage()); + } + return false; + } + + private static String convertInputStreamToString(InputStream inputStream) throws IOException{ + BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream)); + String line = ""; + String result = ""; + while((line = bufferedReader.readLine()) != null) + result += line; + + inputStream.close(); + return result; + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/masa/massiveattendancescannerapplication/StudentActivity.java b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/StudentActivity.java new file mode 100644 index 0000000..19e4dcc --- /dev/null +++ b/app/src/main/java/com/example/masa/massiveattendancescannerapplication/StudentActivity.java @@ -0,0 +1,125 @@ +package com.example.masa.massiveattendancescannerapplication; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import android.app.ListActivity; +import android.app.ProgressDialog; +import android.content.Intent; +import android.os.AsyncTask; +import android.os.Bundle; +import android.util.Log; + +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.SimpleAdapter; + +import com.example.masa.massiveattendancescannerapplication.Services.ServiceHandler; + + +public class StudentActivity extends ListActivity { + + private ProgressDialog pDialog; + ArrayList> studentList; + private static final String URL = "http://192.168.0.101:3000/sections"; + private static final String TAG_ID = "_id"; + private static final String TAG_NO = "id"; + private static final String TAG_NAME = "name"; + private static final String TAG_LASTNAME = "lastname"; + private static final String TAG_STUDENTS = "students"; + JSONArray students = null; + String section_id = null; + String section_name = null; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.student_activity); + Intent i = getIntent(); + section_id = i.getStringExtra("section_id"); + studentList = new ArrayList<>(); + new LoadStudents().execute(); + + ListView lv = getListView(); + } + + class LoadStudents extends AsyncTask { + + @Override + protected void onPreExecute() { + super.onPreExecute(); + pDialog = new ProgressDialog(StudentActivity.this); + pDialog.setMessage("Cargando Alumnos ..."); + pDialog.setIndeterminate(false); + pDialog.setCancelable(false); + pDialog.show(); + } + + protected String doInBackground(String... args) { + + Bundle b = getIntent().getExtras(); + String section_id = b.getString("section_id"); + ServiceHandler sh = new ServiceHandler(); + String JSONString = null; + try { + JSONString = sh.getServiceCall(URL); + } catch (IOException e) { + e.printStackTrace(); + } + + Log.d("Section JSON: ", JSONString); + + try { + JSONArray sections = new JSONArray(JSONString); + + for (int i = 0; i < sections.length(); i++) { + JSONObject c = sections.getJSONObject(i); + String section = c.getString(TAG_ID); + assert section != null; + if (section.equals(section_id)){ + section_name = c.getString(TAG_NAME); + students = c.getJSONArray(TAG_STUDENTS); + for (int x = 0; x < students.length(); x++) { + JSONObject s = students.getJSONObject(x); + String student_id = String.valueOf(x + 1); + String student_no = s.getString(TAG_NO); + String name = s.getString(TAG_NAME); + String lastname = s.getString(TAG_LASTNAME); + + HashMap map = new HashMap(); + map.put("student_id", student_id); + map.put(TAG_ID, student_id); + map.put("student_no", student_no); + map.put(TAG_NAME, name); + map.put(TAG_LASTNAME, lastname); + + studentList.add(map); + } + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + return null; + } + + protected void onPostExecute(String file_url) { + + pDialog.dismiss(); + runOnUiThread(new Runnable() { + public void run() { + ListAdapter adapter = new SimpleAdapter( + StudentActivity.this, studentList, + R.layout.list_item_students, new String[] { "section_id", TAG_ID, TAG_NO, + TAG_NAME, TAG_LASTNAME }, new int[] { + R.id.section_id, R.id.student_id, R.id.student_no, R.id.student_name, R.id.student_lastname }); + setListAdapter(adapter); + + setTitle(section_name); + } + }); + } + } +} diff --git a/app/src/main/res/drawable-hdpi/ic_launcher.png b/app/src/main/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000..96a442e Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_launcher.png b/app/src/main/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000..359047d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_launcher.png b/app/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000..71c6d76 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/app/src/main/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..4df1894 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..4c94d85 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,29 @@ + + + + +