The app crashes when I write mNavigationView.setNavigationItemSelectedListener(this); in the code
and if it is not added it removes the functionality of the item in the navigation bar. Which method I should run in a background thread to reduce the effect on the main thread.
import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.SwipeRefreshLayout;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.eggheadgames.aboutbox.AboutConfig;
import com.eggheadgames.aboutbox.IAnalytic;
import com.eggheadgames.aboutbox.IDialog;
import com.eggheadgames.aboutbox.activity.AboutActivity;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class EarthquakeActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener, SwipeRefreshLayout.OnRefreshListener, LoaderManager.LoaderCallbacks<List<Earthquake>>, NavigationView.OnNavigationItemSelectedListener {
public static final String MyPrefs = "MyPrefs";
private DrawerLayout mdrawerlayout;
private ActionBarDrawerToggle mToogle;
/** URL for earthquake data from the USGS dataset */
private static final String USGS_REQUEST_URL = "https://earthquake.usgs.gov/fdsnws/event/1/query";
/**
* Constant value for the earthquake loader ID. We can choose any integer.
* This really only comes into play if you're using multiple loaders.
*/
private static final int EARTHQUAKE_LOADER_ID = 1;
/** Adapter for the list of earthquakes */
private EarthquakeAdapter mAdapter;
/** TextView that is displayed when the list is empty */
private TextView mEmptyStateTextView;
SwipeRefreshLayout swipe;
private static final String LOG_TAG = EarthquakeActivity.class.getSimpleName();
private ListView earthquakeListView;
private static final String TWITTER_USER_NAME = "vaibhav_khulbe";
private static final String WEB_HOME_PAGE = "https://about.me/vaibhav_khulbe";
private static final String APP_PUBLISHER = "https://play.google.com/store/apps/developer?id=Vaibhav%20Khulbe&hl=en";
private static final String EMAIL_ADDRESS = "khulbevaibhavdev#gmail.com";
private static final String EMAIL_SUBJECT = "Quake Info app acknowledgements and/or issues";
private static final String EMAIL_BODY = "Please explain your experience with this app here...This may include bugs" +
" or issues you may be facing or what you liked about the app along with improvements. :) (MAKE SURE to clear out these lines before sending the mail to us)";
Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.earthquake_activity);
mdrawerlayout=(DrawerLayout)findViewById(R.id.drawer);
mToogle=new ActionBarDrawerToggle(this,mdrawerlayout,R.string.open,R.string.close);
mdrawerlayout.addDrawerListener(mToogle);
mToogle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
NavigationView mNavigationView=(NavigationView)findViewById(R.id.navigation_view);
mNavigationView.setNavigationItemSelectedListener(this);
swipe = findViewById(R.id.swiperefresh);
swipe.setOnRefreshListener(this);
swipe.setColorSchemeColors(getResources().getColor(R.color.colorAccent));
/* Start the intro only once */
SharedPreferences sp = getSharedPreferences(MyPrefs, Context.MODE_PRIVATE);
if (!sp.getBoolean("first", false)) {
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("first", true);
editor.apply();
Intent intent = new Intent(this, IntroActivity.class);
startActivity(intent);
}
//Call and launch About activity
initAboutActivity();
// Find a reference to the {#link ListView} in the layout
earthquakeListView = (ListView) findViewById(R.id.list);
mEmptyStateTextView = (TextView) findViewById(R.id.empty_view);
earthquakeListView.setEmptyView(mEmptyStateTextView);
// Create a new adapter that takes an empty list of earthquakes as input
mAdapter = new EarthquakeAdapter(this, new ArrayList<Earthquake>());
// Set the adapter on the {#link ListView}
// so the list can be populated in the user interface
earthquakeListView.setAdapter(mAdapter);
// Obtain a reference to the SharedPreferences file for this app
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
// And register to be notified of preference changes
// So we know when the user has adjusted the query settings
prefs.registerOnSharedPreferenceChangeListener(this);
// Set an item click listener on the ListView, which sends an intent to a web browser
// to open a website with more information about the selected earthquake.
earthquakeListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
// Find the current earthquake that was clicked on
Earthquake currentEarthquake = mAdapter.getItem(position);
// Convert the String URL into a URI object (to pass into the Intent constructor)
Uri earthquakeUri = Uri.parse(currentEarthquake.getUrl());
// Create a new intent to view the earthquake URI
Intent websiteIntent = new Intent(Intent.ACTION_VIEW, earthquakeUri);
// Send the intent to launch a new activity
startActivity(websiteIntent);
}
});
getSupportLoaderManager().initLoader(EARTHQUAKE_LOADER_ID, null, this);
}
/*Code to launch About activity */
public void initAboutActivity()
{
/* Create About activity */
AboutConfig aboutConfig = AboutConfig.getInstance();
aboutConfig.appName = getString(R.string.app_name);
aboutConfig.appIcon = R.mipmap.ic_launcher;
aboutConfig.version = "1.0.0";
aboutConfig.author = "Vaibhav Khulbe";
aboutConfig.aboutLabelTitle = "About";
aboutConfig.packageName = getApplicationContext().getPackageName();
aboutConfig.appPublisher = APP_PUBLISHER;
aboutConfig.twitterUserName = TWITTER_USER_NAME;
aboutConfig.webHomePage = WEB_HOME_PAGE;
aboutConfig.dialog = new IDialog() {
#Override
public void open(AppCompatActivity appCompatActivity, String url, String tag) {
// handle custom implementations of WebView. It will be called when user click to web items. (Example: "Privacy", "Acknowledgments" and "About")
}
};
aboutConfig.analytics = new IAnalytic() {
#Override
public void logUiEvent(String s, String s1) {
// handle log events.
}
#Override
public void logException(Exception e, boolean b) {
// handle exception events.
}
};
// set it only if aboutConfig.analytics is defined.
aboutConfig.logUiEventName = "Log";
// Contact Support email details
aboutConfig.emailAddress = EMAIL_ADDRESS;
aboutConfig.emailSubject = EMAIL_SUBJECT;
aboutConfig.emailBody = EMAIL_BODY;
aboutConfig.shareMessage = getString(R.string.share_message);
aboutConfig.sharingTitle = getString(R.string.sharing_title);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if (key.equals(getString(R.string.settings_min_magnitude_key)) ||
key.equals(getString(R.string.settings_order_by_key))){
// Clear the ListView as a new query will be kicked off
mAdapter.clear();
// Hide the empty state text view as the loading indicator will be displayed
mEmptyStateTextView.setVisibility(View.GONE);
// Show the loading indicator while new data is being fetched
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.VISIBLE);
// Restart the loader to requery the USGS as the query settings have been updated
getSupportLoaderManager().restartLoader(EARTHQUAKE_LOADER_ID, null, this);
}
}
#Override
public Loader<List<Earthquake>> onCreateLoader(int i, Bundle bundle) {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
String minMagnitude = sharedPrefs.getString(
getString(R.string.settings_min_magnitude_key),
getString(R.string.settings_min_magnitude_default));
String orderBy = sharedPrefs.getString(
getString(R.string.settings_order_by_key),
getString(R.string.settings_order_by_default)
);
String region = sharedPrefs.getString(
getString(R.string.settings_narrow_by_region_key),
getString(R.string.settings_narrow_by_region_default)
);
String radius = sharedPrefs.getString(
getString(R.string.settings_maximum_radius_key),
getString(R.string.settings_maximum_radius_default)
);
List<Country> countries = new ArrayList<>();
try {
countries = Utils.generateCountryList(this);
} catch (IOException e) {
e.printStackTrace();
}
Double latitude = 0.0;
Double longitude = 0.0;
for (Country country : countries) {
if(country.getName().equalsIgnoreCase(region)){
latitude = country.getLatitude();
longitude = country.getLongitude();
}
}
Uri baseUri = Uri.parse(USGS_REQUEST_URL);
Uri.Builder uriBuilder = baseUri.buildUpon();
uriBuilder.appendQueryParameter("format", "geojson");
uriBuilder.appendQueryParameter("limit", "100");
uriBuilder.appendQueryParameter("minmag", minMagnitude);
uriBuilder.appendQueryParameter("orderby", orderBy);
if(latitude != 0.0 && longitude != 0.0){
uriBuilder.appendQueryParameter("latitude", String.valueOf(latitude.intValue()));
uriBuilder.appendQueryParameter("longitude", String.valueOf(longitude.intValue()));
uriBuilder.appendQueryParameter("maxradius", radius);
}
String url = uriBuilder.toString();
return new EarthquakeLoader(this, url);
}
#Override
public void onLoadFinished(Loader<List<Earthquake>> loader, List<Earthquake> earthquakes) {
swipe.setRefreshing(false);
// Hide loading indicator because the data has been loaded
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
if (earthquakes != null && !earthquakes.isEmpty()) {
this.showResults(earthquakes);
} else {
this.hideResults();
}
}
#Override
public void onLoaderReset(Loader<List<Earthquake>> loader) {
// Loader reset, so we can clear out our existing data.
mAdapter.clear();
}
/**
* method to show results
*/
private void showResults(List<Earthquake> earthquakeList) {
mAdapter.clear();
earthquakeListView.setVisibility(View.VISIBLE);
mEmptyStateTextView.setVisibility(View.GONE);
mAdapter.setNotifyOnChange(false);
mAdapter.setNotifyOnChange(true);
mAdapter.addAll(earthquakeList);
}
/**
* method to hide results also checks internet connection
*/
private void hideResults() {
earthquakeListView.setVisibility(View.GONE);
mEmptyStateTextView.setVisibility(View.VISIBLE);
// Get a reference to the ConnectivityManager to check state of network connectivity
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
// Get details on the currently active default data network
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
mEmptyStateTextView.setText(R.string.no_earthquakes);
Log.e(LOG_TAG, "no earthquakes data");
} else {
mEmptyStateTextView.setText(R.string.no_internet_connection);
Log.e(LOG_TAG, "no internet");
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mToogle.onOptionsItemSelected(item)){
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onRefresh() {
getSupportLoaderManager().restartLoader(EARTHQUAKE_LOADER_ID, null, this);
Toast.makeText(this, R.string.list_refreshed, Toast.LENGTH_SHORT).show();
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
Intent settingsIntent = new Intent(this, SettingsActivity.class);
startActivity(settingsIntent);
return true;
}
if (id == R.id.action_about) {
Intent actionIntent = new Intent(this, AboutActivity.class);
startActivity(actionIntent);
return true;
}
if (id == R.id.action_did_you_feel_it){
Intent feelItIntent = new Intent(this, DidYouFeel.class);
startActivity(feelItIntent);
return true;
}
if (id == R.id.action_more_apps){
Uri uri = Uri.parse( "https://play.google.com/store/apps/developer?id=Vaibhav+Khulbe" );
startActivity( new Intent( Intent.ACTION_VIEW, uri ) );
}
if (id == R.id.fork_project){
Uri uri = Uri.parse( "https://github.com/Kvaibhav01/Quake-Info" );
startActivity( new Intent( Intent.ACTION_VIEW, uri ) );
}
if (id == R.id.notification){
Intent notificationIntent = new Intent(this, EarthquakeNotification.class);
startActivity(notificationIntent);
}
return true;
}
}
I think it can be done by running the method in a background thread but I am not sure how to do that. Thanks for helping
you can use sample code like this:
((MainActivity)context).runOnUiThread(new Runnable() {
public void run() {
//run another thread
}
});
or if you are familiar with RxJava you can use it.
consider that most of the time you should perform a function that you will call it after the click, not the click method.
Related
I am using sqlite for database. When i add data in ListView. Data added correctly. But when i close app then updated list lost data which i added before. With code Statically added data shows but using app when create reminder then data added successfully in ListView. But when i restart app new data lost after restart app I mean creating reminder delete automatically after restart app.
Even I delete reminders which added by code after restart app all deleted reminders showing in ListView again. But Dynamically added data not show.
Please help me to solve this problem.
Here is my Activity code
RemindersActivity.java
package com.example.remindersapp;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.TargetApi;
import android.app.AlarmManager;
import android.app.Dialog;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import java.util.Calendar;
import java.util.Date;
public class RemindersActivity extends AppCompatActivity {
private ListView mlistView;
private RemindersDbAdapter remindersDbAdapter;
private ReminderSimpleCursorAdapter reminderSimpleCursorAdapter;
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reminders);
ActionBar actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setIcon(R.mipmap.ic_launcher_reminder);
mlistView = (ListView) findViewById(R.id.reminder_listView);
// mlistView.setDivider(null);
remindersDbAdapter = new RemindersDbAdapter(this);
remindersDbAdapter.open();
if (savedInstanceState == null) {
//clear all data
remindersDbAdapter.deleteAllReminders();
//add some data
insertSomeReminders();
}
Cursor cursor = remindersDbAdapter.fetchAllReminders();
//from columns defined in the db
String[] from = new String[]{remindersDbAdapter.COL_CONTENT};
//to the ids of views in the layout
int[] to = new int[]{R.id.row_text};
reminderSimpleCursorAdapter = new ReminderSimpleCursorAdapter(
RemindersActivity.this,
//the layout of the row
R.layout.reminders_row,
cursor,
//from columns defined in the db
from,
//to the ids of views in the layout
to,
//flag - not used
0);
// ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
// this,
// R.layout.reminders_row,
// R.id.row_text,
// new String[]{"fisrt record", "second record", "third record"
// , "fourth record", "fifth record"});
mlistView.setAdapter(reminderSimpleCursorAdapter);
//Adapter is a
//special Java class defined as part of the Android SDK that functions as the Controller in
//the Model-View-Controller relationship
//when we click an individual item in the listview
mlistView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int masterposition, long id) {
AlertDialog.Builder builder = new AlertDialog.Builder(RemindersActivity.this);
ListView modeListView = new ListView(RemindersActivity.this);
String[] modes = new String[]{"Edit Reminder", "Delete Reminder", "Scheduled Reminder"};
ArrayAdapter<String> modeAdapter = new ArrayAdapter<>(RemindersActivity.this,
android.R.layout.simple_list_item_1, android.R.id.text1, modes);
modeListView.setAdapter(modeAdapter);
builder.setView(modeListView);
final Dialog dialog = builder.create();
dialog.show();
modeListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//edit reminder
// if (position == 0) {
// Toast.makeText(RemindersActivity.this, "edit" + masterposition, Toast.LENGTH_SHORT).show();
// } else {
// Toast.makeText(RemindersActivity.this, "delete" + masterposition, Toast.LENGTH_SHORT).show();
// }
// dialog.dismiss();
int nId = getIdFromPosition(masterposition);
final Reminder reminder = remindersDbAdapter.fetchReminderById(nId);
if (position == 0) {
fireCustomDialog(reminder);
//delete reminder
} else if (position == 1) {
remindersDbAdapter.deleteReminderById(getIdFromPosition(masterposition));
reminderSimpleCursorAdapter.changeCursor(remindersDbAdapter.fetchAllReminders());
}
else {
// final Date today = new Date();
// new TimePickerDialog(RemindersActivity.this,null,today.getHours(),today.getMinutes(),
// false).show();
TimePickerDialog.OnTimeSetListener listener = new TimePickerDialog.OnTimeSetListener() {
#Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
// Date alarm = new Date(today.getYear(), today.getMonth(), today.getDate(), hourOfDay, minute);
// scheduleReminder(alarm.getTime(), reminder.getmContent());
//This creates a listener for the time picker dialog box. Inside this listener, you use today’s
//date as the base time for your alarm. You then include the hour and minute chosen from
//the dialog box to create the alarm date variable for your reminder. You use both the alarm
//time and the reminder’s content in a new scheduleReminder() method
//Fix the deprecation warnings
final Calendar alarmTime = Calendar.getInstance();
alarmTime.set(Calendar.HOUR, hourOfDay);
alarmTime.set(Calendar.MINUTE, minute);
scheduleReminder(alarmTime.getTimeInMillis(), reminder.getmContent());
}
};
final Calendar today = Calendar.getInstance();
// new TimePickerDialog(RemindersActivity.this, null,
// today.get(Calendar.HOUR), today.get(Calendar.MINUTE), false).show();
//the following change to connect the
//listener that invokes the BroadcastReceiver to the TimePickerDialog
new TimePickerDialog(RemindersActivity.this, listener,
today.get(Calendar.HOUR), today.get(Calendar.MINUTE), false).show();
}
dialog.dismiss();
}
});
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mlistView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mlistView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
//The preceding logic defines a MultiChoiceModeListener and attaches it to the ListView.
//Whenever you long-press an item in the ListView, the runtime invokes the onCreateActionMode()
//method on the MultiChoiceModeListener. If the method returns with the boolean true value,
//multichoice action mode is entered.
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.cam_menu, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_delete_reminder:
for (int nC = reminderSimpleCursorAdapter.getCount() - 1; nC >= 0; nC--) {
if (mlistView.isItemChecked(nC)) {
remindersDbAdapter.deleteReminderById(getIdFromPosition(nC));
}
}
mode.finish();
reminderSimpleCursorAdapter.changeCursor(remindersDbAdapter.fetchAllReminders());
return true;
}
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
});
}
}
private void scheduleReminder(long time, String getmContent) {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(this, ReminderAlarmReceiver.class);
alarmIntent.putExtra(ReminderAlarmReceiver.REMINDER_TEXT, getmContent);
PendingIntent broadcast = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, time, broadcast);
}
private int getIdFromPosition(int nC) {
return (int) reminderSimpleCursorAdapter.getItemId(nC);
}
private void insertSomeReminders() {
remindersDbAdapter.createReminder("Learn android Development", true);
remindersDbAdapter.createReminder("data Mining Assignment", false);
remindersDbAdapter.createReminder("Networking Assignment", false);
remindersDbAdapter.createReminder("English Assignment", true);
// //There are several calls to the createReminder() method, each taking a String value
//with the reminder text and a boolean value flagging the reminder as important. We set
//a few values to true to provide a good visual effect.
}
private void fireCustomDialog(final Reminder reminder) {
// custom dialog
Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_custom);
TextView titleView = (TextView) dialog.findViewById(R.id.custom_title);
final EditText editCustom = (EditText) dialog.findViewById(R.id.custom_edit_reminder);
Button commitButton = (Button) dialog.findViewById(R.id.custom_button_commit);
final CheckBox checkBox = (CheckBox) dialog.findViewById(R.id.custom_check_box);
// checkBox.setChecked(true);
LinearLayout rootLayout = (LinearLayout) dialog.findViewById(R.id.custom_root_layout);
final boolean isEditOperation = (reminder != null);
//this is for an edit
if (isEditOperation) {
titleView.setText("Edit Reminder");
checkBox.setChecked(reminder.getImportant() == 1);
editCustom.setText(reminder.getmContent());
rootLayout.setBackgroundColor(getResources().getColor(R.color.check_box));
}
commitButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String reminderText = editCustom.getText().toString();
if (isEditOperation) {
Reminder reminderEdit = new Reminder(reminder.getmId(),
reminderText, checkBox.isChecked() ? 1 : 0);
remindersDbAdapter.updateReminder(reminderEdit);
} else {
remindersDbAdapter.createReminder(reminderText, checkBox.isChecked());
}
reminderSimpleCursorAdapter.changeCursor(remindersDbAdapter.fetchAllReminders());
dialog.dismiss();
}
});
Button buttonCancel = (Button) dialog.findViewById(R.id.custom_button_cancel);
buttonCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.reminder_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_new:
//create new reminder
Log.d(getLocalClassName(), "create new reminder");
fireCustomDialog(null);
return true;
case R.id.action_exit:
finish();
return true;
case R.id.action_about:
fireAboutDialog();
return true;
default:
return false;
}
}
private void fireAboutDialog() {
final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_about);
dialog.show();
}
}
RemindersDbAdapter.java
package com.example.remindersapp;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class RemindersDbAdapter {
//these are the column names
public static final String COL_ID = "_id";
public static final String COL_CONTENT = "content" ;
public static final String COL_IMPORTANT = "important";
//these are the corresponding indices
private static final int INDEX_ID = 0;
private static final int INDEX_CONTENT = INDEX_ID + 1;
private static final int INDEX_IMPORTANT = INDEX_ID + 2;
//used for logging
private static final String TAG = "RemindersDbAdapter";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
private static final String DATABASE_NAME = "dba_reminder";
private static final String TABLE_NAME = "table_reminder";
private static final int DATABASE_VERSION = 3;
private final Context mCtx;
////SQL statement used to create the database
private static final String DATABSE_CREATE = "CREATE TABLE if not exists " + TABLE_NAME + " ( " +
COL_ID + " INTEGER PRIMARY KEY autoincrement, " +
COL_CONTENT + " TEXT, " +
COL_IMPORTANT + " INTEGER );";
public RemindersDbAdapter(Context Ctx) {
//The constructor saves an instance of Context, which is passed to DatabaseHelper
this.mCtx = Ctx;
}
//The open()
//method initializes the helper and uses it to get an instance of the database,
public void open() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
}
//the close()
//method uses the helper to close the database.
public void close() throws SQLException {
if (mDbHelper != null) {
mDbHelper.close();
}
}
//CREATE
//note that the id will be created for you automatically
public void createReminder(String name, boolean important) {
ContentValues values = new ContentValues();
values.put(COL_CONTENT, name);
values.put(COL_IMPORTANT, important ? 1 : 0);
mDb.insert(TABLE_NAME, null, values);
}
////overloaded to take a reminder
public long createReminder(Reminder reminder) {
ContentValues values = new ContentValues();
values.put(COL_CONTENT, reminder.getmContent()); //Contact name
values.put(COL_IMPORTANT, reminder.getImportant()); //Contact phone number
//// Inserting Row
return mDb.insert(TABLE_NAME, null, values);
}
//READ
public Reminder fetchReminderById(int id) {
Cursor cursor = mDb.query(TABLE_NAME,
new String[]{COL_ID, COL_CONTENT, COL_IMPORTANT},
COL_ID + " =? ",
new String[]{String.valueOf(id)},
null, null, null, null);
if (cursor != null)
cursor.moveToFirst();
return new Reminder(
cursor.getInt(INDEX_ID),
cursor.getString(INDEX_CONTENT),
cursor.getInt(INDEX_IMPORTANT));
}
public Cursor fetchAllReminders() {
Cursor mcursor = mDb.query(TABLE_NAME, new String[]{COL_ID, COL_CONTENT, COL_IMPORTANT},
null, null, null, null, null);
if (mcursor != null) {
mcursor.moveToFirst();
}
return mcursor;
}
//UPDATE
public void updateReminder(Reminder reminder) {
ContentValues values = new ContentValues();
values.put(COL_CONTENT, reminder.getmContent());
values.put(COL_IMPORTANT, reminder.getImportant());
mDb.update(TABLE_NAME, values, COL_ID + " =? ", new String[]{String.valueOf(reminder.getmId())});
}
//DELETE
public void deleteReminderById(int id){
mDb.delete(TABLE_NAME,COL_ID + "=?", new String[]{String.valueOf(id)});
}
public void deleteAllReminders(){
mDb.delete(TABLE_NAME,null,null);
}
//sqlite open helper
private static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
Log.w(TAG, DATABSE_CREATE);
db.execSQL(DATABSE_CREATE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + "to " + newVersion + ",which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
#Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
onCreate(db);
}
}
}
ReminderSimpleCursorAdapter.java
package com.example.remindersapp;
import android.content.Context;
import android.database.Cursor;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SimpleCursorAdapter;
import androidx.recyclerview.widget.RecyclerView;
public class ReminderSimpleCursorAdapter extends SimpleCursorAdapter {
public ReminderSimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int i) {
super(context, layout, c, from, to,i);
}
////to use a viewholder, you must override the following two methods and define a ViewHolder class
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return super.newView(context, cursor, parent);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
super.bindView(view, context, cursor);
ViewHolder holder=(ViewHolder)view.getTag();
if (holder == null){
holder=new ViewHolder();
holder.colImp=cursor.getColumnIndexOrThrow(RemindersDbAdapter.COL_IMPORTANT);
holder.listTab=view.findViewById(R.id.row_tab);
view.setTag(holder);
}
if (cursor.getInt(holder.colImp) > 0){
holder.listTab.setBackgroundColor(context.getResources().getColor(R.color.false_result));
}else {
holder.listTab.setBackgroundColor(context.getResources().getColor(R.color.txt_color));
}
}
//Here you see an example of the ViewHolder pattern. This is a well-known Android pattern
//in which a small ViewHolder object is attached as a tag on each view. This object adds
//decoration for View objects in the list by using values from the data source, which in this
//example is the Cursor. The ViewHolder is defined as a static inner class with two instance
//variables, one for the index of the Important table column and one for the row_tab view you
//defined in the layout.
static class ViewHolder{
//store the column index
int colImp;
//store the view
View listTab;
}
}
I have a custom ListView with BaseAdapter. In this custom ListView when a user clicks on any particular text, it speaks the text but the problem is that when any user clicks on the back button how to stop this text from the BaseAdapter. I know how to stop from an Activity but don't know how to stop from BaseAdapter when the user presses back button. Here is my code:
package bible.swordof.God;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Vibrator;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.zip.Inflater;
import es.dmoral.toasty.Toasty;
import petrov.kristiyan.colorpicker.ColorPicker;
import static android.content.Context.MODE_PRIVATE;
public class BaseAdopter extends BaseAdapter implements TextToSpeech.OnInitListener{
public BaseAdopter(Context context, List<String> versenumber, List<String> verseid, List<String> verselist, List<String> refernce) {
this.context = context;
this.versenumber = versenumber;
this.verseid = verseid;
this.verselist = verselist;
this.refernce = refernce;
}
ALLVERSE allverse;
ArrayList<String> colors;
private Context context;
private List<String> versenumber;
private List<String>verseid;
private List<String> verselist;
private List<String> refernce;
TextToSpeech textToSpeech;
private DatabaseHelper mDBHelper;
private SQLiteDatabase mDb;
#Override
public int getCount() {
return versenumber.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View view=inflater.inflate(R.layout.versedisplayrow,parent,false);
textToSpeech = new TextToSpeech(context, this);
final TextView verseno;
final TextView verselistview;
ImageView share;
ToggleButton addfavoruite;
ImageView speakverse;
final LinearLayout linearLayout;
verseno=(TextView)view.findViewById(R.id.versenumber);
verseno.setText(versenumber.get(position));
verselistview=(TextView)view.findViewById(R.id.verse);
verselistview.setText(verselist.get(position));
addfavoruite=(ToggleButton)view.findViewById(R.id.adbookmark);
linearLayout=(LinearLayout)view.findViewById(R.id.layout);
share=(ImageView)view.findViewById(R.id.share);
speakverse=(ImageView)view.findViewById(R.id.speak);
if(DefaultSettings.nightmode(context)){
linearLayout.setBackgroundColor(Color.parseColor("#363437"));
verselistview.setTextColor(Color.parseColor("#ffffff"));
verseno.setTextColor(Color.parseColor("#ffffff"));
}
speakverse.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
singleverse(verselist.get(position).toString());
}
});
int a=position+1;
colors=new ArrayList<>();
colors.add("#e0e0eb");
colors.add("#ccffff");
colors.add("#ffe6ff");
colors.add("#ffffcc");
colors.add("#ccffcc");
colors.add("#e6f2ff");
SharedPreferences sharedPreferences=context.getSharedPreferences("DATA",MODE_PRIVATE);
int getverse=sharedPreferences.getInt("versenumber",1);
if(a==getverse){
if(DefaultSettings.highlight(context)){
DefaultSettings.color(context);
linearLayout.setBackgroundColor(DefaultSettings.colorpicked);
}
}
if(Checkisfavourite("favourite","id",verseid.get(position)))
{
if(verseid.get(position).equals(verseid.get(position))){
addfavoruite.setChecked(true);
}else {
addfavoruite.setChecked(false);
}
}
addfavoruite.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
mDBHelper = new DatabaseHelper(context);
mDb = mDBHelper.getWritableDatabase();
ContentValues contentValues=new ContentValues();
contentValues.put("id",verseid.get(position));
contentValues.put("bookname",refernce.get(position));
contentValues.put("versenumber",versenumber.get(position));
contentValues.put("verse",verselist.get(position));
long check=mDb.insert("favourite",null,contentValues);
Toasty.success(context, "Added in favouite", Toast.LENGTH_SHORT, true).show();
}
else {
mDBHelper = new DatabaseHelper(context);
mDb = mDBHelper.getWritableDatabase();
long delete= mDb.delete("favourite","id=?",new String[]{verseid.get(position)});
Toasty.error(context, "Remove in favouite", Toast.LENGTH_SHORT, true).show();
}
}
});
share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toasty.info(context, "Sharing a verse.", Toast.LENGTH_SHORT, true).show();
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, refernce.get(position) + ":" + versenumber.get(position) + '\n' + verselist.get(position) +
+'\n' +'\n' +'\n' +"https://play.google.com/store/apps/details?id=bible.swordof.God");
sendIntent.setType("text/plain");
context.startActivity(sendIntent);
}
});
/* linearLayout.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
//Toasty.success(activity, "PICK COLOR", Toast.LENGTH_SHORT, true).show();
Vibrator vibe = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
vibe.vibrate(100);
mDBHelper = new DatabaseHelper(context);
mDb = mDBHelper.getWritableDatabase();
ContentValues contentValues=new ContentValues();
contentValues.put("verseid",colors.get(position));
final long check=mDb.insert("highlight",null,contentValues);
//id get
//postion
//Toast.makeText(activity, ""+getItemId(position), Toast.LENGTH_SHORT).show();
ColorPicker colorPicker = new ColorPicker(context);
colorPicker.setColors(colors).setColumns(4).setTitle("HIGHLIGHT VERSE").setRoundColorButton(true).setOnChooseColorListener(new ColorPicker.OnChooseColorListener() {
#Override
public void onChooseColor(int position, int color) {
linearLayout.setBackgroundColor(Color.parseColor(colors.get(position)));
}
#Override
public void onCancel() {
}
}).show();
return false;
}
});
*/
return view;
}
public boolean Checkisfavourite(String TableName, String dbfield, String fieldValue) {
mDBHelper = new DatabaseHelper(context);
mDb = mDBHelper.getReadableDatabase();
String Query = "Select * from " + TableName + " where " + dbfield + " = " + fieldValue;
Cursor cursor = mDb.rawQuery(Query, null);
if(cursor.getCount() <= 0){
cursor.close();
// Toast.makeText(activity, "false", Toast.LENGTH_SHORT).show();
return false;
}else {
// Toast.makeText(activity, "TRUE", Toast.LENGTH_SHORT).show();
}
cursor.close();
return true;
}
public boolean colorcheck(String TableName, String dbfield, String fieldValue) {
mDBHelper = new DatabaseHelper(context);
mDb = mDBHelper.getReadableDatabase();
String Query = "Select * from " + TableName + " where " + dbfield + " = " + fieldValue;
Cursor cursor = mDb.rawQuery(Query, null);
if(cursor.getCount() <= 0){
cursor.close();
// Toast.makeText(activity, "false", Toast.LENGTH_SHORT).show();
return false;
}else {
// Toast.makeText(activity, "TRUE", Toast.LENGTH_SHORT).show();
}
cursor.close();
return true;
}
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int result = textToSpeech.setLanguage(Locale.US);
// tts.setPitch(5); // set pitch level
// tts.setSpeechRate(2); // set speech speed rate
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS", "Language is not supported");
} else {
}
} else {
Log.e("TTS", "Initilization Failed");
}
}
private void singleverse(String text) {
DefaultSettings.speed(context);
textToSpeech.setPitch(DefaultSettings.pitchvalue);
textToSpeech.setSpeechRate(DefaultSettings.speedvalue);
textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null);
}
public void stop(){
if (textToSpeech != null) {
textToSpeech.stop();
textToSpeech.shutdown();
}
}
}
The main problem is that your TextToSpeech object belongs to your BaseAdapter when it should belong to the parent activity.
Instead of housing it in the adapter and calling speak on it every time the user clicks an item, I would instead house it in the parent activity and use an "interface callback" that sends a message to the parent when the user clicks an item, sending back the string to speak. This callback relationship works the exact same way as the TextToSpeech.OnInitListener callback that you're already using.
Once the TTS belongs to the parent activity, you can use the activity lifecycle functions to control the shutdown of the TTS like normal.
If you study and understand the following, you should be able to merge it into your code and get a working solution:
Make these changes to your custom BaseAdapter:
// Remove the TextToSpeech object from this class.
public class MyBaseAdapter {
// add this interface definition to your adapter
public interface SpeechClickSubscriber {
void stringNeedsToBeSpoken(String verse);
}
// add this property (the subscriber)
private SpeechClickSubscriber speechClickSubscriber;
// *add* this functionality to your adapter's existing constructor
MyBaseAdapter(SpeechClickSubscriber parent) {
speechClickSubscriber = parent;
}
//...
// change this section of code in your getView() method
speakverse.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick (View v){
// change this...
// singleverse(verselist.get(position).toString());
// to this:
speechClickSubscriber.stringNeedsToBeSpoken(verselist.get(position).toString());
}
});
// ...
}
Make these changes to your MainActivity (or whatever your parent activity is):
// add the SpeechClickSubscriber implementation
public class MainActivity extends AppCompatActivity implements MyBaseAdapter.SpeechClickSubscriber, TextToSpeech.OnInitListener {
MyBaseAdapter adapter;
TextToSpeech textToSpeech;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// using app context is better and less error prone.
textToSpeech = new TextToSpeech(getApplicationContext(), this);
}
// *add* this method to this activity (this is the answer to your question)
#Override
protected void onStop() {
super.onStop();
stopTTS();
}
// use this method as your "onStart()" method...
// this will help prevent any user input processing until the tts is initialized.
private void start_Activity_Because_TTS_Has_Initialized() {
adapter = new MyBaseAdapter(this);
}
// *MOVE* this method from your base adapter to this (parent) activity:
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int result = textToSpeech.setLanguage(Locale.US);
// tts.setPitch(5); // set pitch level
// tts.setSpeechRate(2); // set speech speed rate
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS", "Language is not supported");
} else {
}
} else {
Log.e("TTS", "Initilization Failed");
}
}
// *move* and *rename* this method from your adapter to the parent activity:
// from:
/*
private void singleverse(String text) {
DefaultSettings.speed(context);
textToSpeech.setPitch(DefaultSettings.pitchvalue);
textToSpeech.setSpeechRate(DefaultSettings.speedvalue);
textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null);
} */
// to:
#Override
public void stringNeedsToBeSpoken(String verse) {
Log.i("XXX","stringNeedsToBeSpoken() was called because the user clicked an item.");
Log.i("XXX","This method is being called because this activity subscribes to the callback we created and added to our base adapter.");
//DefaultSettings.speed(context); // <----------------- I don't know what this does.
// I'm assuming that DefaultSettings is a static class you have made.
textToSpeech.setPitch(DefaultSettings.pitchvalue);
textToSpeech.setSpeechRate(DefaultSettings.speedvalue);
textToSpeech.speak(verse, TextToSpeech.QUEUE_FLUSH, null);
}
public void stopTTS(){
if (textToSpeech != null) {
textToSpeech.stop();
textToSpeech.shutdown();
}
}
}
I am creating an app for my university that is supposed to push a notification when entering or exiting a geofence in android studio. The problem is that i can not think any way to code for sending a notification when exiting the geofence but the notification when entering a geofence works fine. here is my code thanks in advance
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GeofenceController.getInstance().init(this);
NamedGeofense geofence = new NamedGeofense();
geofence.name ="abbott";
geofence.latitude =38.037847; //your lati and longii :)
geofence.longitude =23.70083;
geofence.radius =100;
GeofenceController.getInstance().addGeofence(geofence);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
NamedGeofence class
package com.example.adeeb.webviewfordigitalwaiter;
import com.google.android.gms.location.Geofence;
import java.util.UUID;
public class NamedGeofense {
public String id;
public String name;
public double latitude;
public double longitude;
public float radius;
// end region
// region Public
public Geofence geofence() {
id = UUID.randomUUID().toString();
// UUID is universal unique identifer. ref for you
// : https://docs.oracle.com/javase/7/docs/api/java/util/UUID.html
return new Geofence.Builder()
.setRequestId(id)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
.setCircularRegion(latitude, longitude, radius)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.build();
}
}
Geofence Controller class
package com.example.adeeb.webviewfordigitalwaiter;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingRequest;
import com.google.android.gms.location.LocationServices;
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class GeofenceController {
// region Properties
private final String TAG = GeofenceController.class.getName();
private Context context;
private GoogleApiClient googleApiClient;
private Gson gson;
private SharedPreferences prefs;
private GeofenceControllerListener listener;
private List<NamedGeofense> namedGeofences;
private Geofence geofenceToAdd;
private NamedGeofense namedGeofenceToAdd;
// endregion
// region Shared Instance
private static GeofenceController INSTANCE;
public static GeofenceController getInstance() {
if (INSTANCE == null) {
INSTANCE = new GeofenceController();
}
return INSTANCE;
}
// endregion
// region Public
//we call this from main activity (in main activity we mde an instance of geofence controller
// using static method getInstance() (like this GeofenceController.getInstance().init(this);)
public void init(Context context) {
this.context = context.getApplicationContext();
gson = new Gson();
// namedGeofences is arraylist of my defined class name (namedGeofences)
// i will discuss namedGeofences class .. wait a moment.. :P
namedGeofences = new ArrayList<>();
prefs = this.context.getSharedPreferences(Constants.SharedPrefs.Geofences, Context.MODE_PRIVATE);
// prefs is shared prefrence (shared is a class or local storage where we store data so that
// our data might not lost when we move to other class or activity)
// variable.we assign our shared prefrence name which is define in Constants class
//public static String Geofences = "SHARED_PREFS_GEOFENCES";
loadGeofences();
// loadGeofences(); is my define method where we load geofences data if they are store
// in our sharedprefrences
}
// region ConnectionCallbacks
private GoogleApiClient.ConnectionCallbacks connectionAddListener = new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
Intent intent = new Intent(context, AreWeThereIntentService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingResult<Status> result = LocationServices.GeofencingApi.
addGeofences(googleApiClient, getAddGeofencingRequest(), pendingIntent);
result.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
if (status.isSuccess()) {
saveGeofence();
} else {
Log.e(TAG, "Registering geofence failed: " + status.getStatusMessage() + " : " + status.getStatusCode());
sendError();
}
}
});
}
#Override
public void onConnectionSuspended(int i) {
Log.e(TAG, "Connecting to GoogleApiClient suspended.");
sendError();
}
};
public void addGeofence(NamedGeofense namedGeofence) {
this.namedGeofenceToAdd = namedGeofence;
this.geofenceToAdd = namedGeofence.geofence();
connectWithCallbacks(connectionAddListener);
}
// endregion
private GeofencingRequest getAddGeofencingRequest() {
List<Geofence> geofencesToAdd = new ArrayList<>();
geofencesToAdd.add(geofenceToAdd);
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(geofencesToAdd);
return builder.build();
}
private void saveGeofence() {
namedGeofences.add(namedGeofenceToAdd);
String json = gson.toJson(namedGeofenceToAdd);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(namedGeofenceToAdd.id, json);
editor.apply();
}
public interface GeofenceControllerListener {
void onGeofencesUpdated();
void onError();
}
public List<NamedGeofense> getNamedGeofences() {
return namedGeofences;
}
// endregion
// region Private
private void loadGeofences() {
// Map<String, ?> is A Map is a data structure consisting of a set of keys and values
// in which each key is mapped to a single value.
// we load geofences data if they are store
// in our sharedprefrences
Map<String, ?> keys = prefs.getAll();
// Loop over all geofence keys in prefs and add to namedGeofences
for (Map.Entry<String, ?> entry : keys.entrySet()) {
String jsonString = prefs.getString(entry.getKey(), null);
// gson is a library where we can store our whole class instance,
// below we assign previously store NamedGeofence class , and jsonString is key of that
// class
NamedGeofense namedGeofence = gson.fromJson(jsonString, NamedGeofense.class);
// than here we just add namedGeofence instance to our array list
namedGeofences.add(namedGeofence);
}
// Sort namedGeofences by name
}
private void connectWithCallbacks(GoogleApiClient.ConnectionCallbacks callbacks) {
googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(callbacks)
.addOnConnectionFailedListener(connectionFailedListener)
.build();
googleApiClient.connect();
}
private void sendError() {
if (listener != null) {
listener.onError();
}
}
// endregion
// region OnConnectionFailedListener
private GoogleApiClient.OnConnectionFailedListener connectionFailedListener = new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "Connecting to GoogleApiClient failed.");
sendError();
}
};
// endregion
// region Interfaces
// end region
}
Constant class
public class Constants {
public static class SharedPrefs {
public static String Geofences = "SHARED_PREFS_GEOFENCES";
}
}
ARE WE THERE YES SERVICE (HERES IS THE WHERE THE NOTIFICATIONS SHOULD BE PUT)
package com.example.adeeb.webviewfordigitalwaiter;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingEvent;
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class AreWeThereIntentService extends IntentService {
// region Properties
private final String TAG = AreWeThereIntentService.class.getName();
private SharedPreferences prefs;
private Gson gson;
// endregion
// region Constructors
public AreWeThereIntentService() {
super("AreWeThereIntentService");
}
// endregion
// region Overrides
#Override
protected void onHandleIntent(Intent intent) {
prefs = getApplicationContext().getSharedPreferences(Constants.SharedPrefs.Geofences, Context.MODE_PRIVATE);
gson = new Gson();
Log.e(TAG, "on handle :)");
GeofencingEvent event = GeofencingEvent.fromIntent(intent);
if (event != null) {
Log.e(TAG, "event not null :) ");
if (event.hasError()) {
onError(event.getErrorCode());
} else {
int transition = event.getGeofenceTransition();
if (transition == Geofence.GEOFENCE_TRANSITION_ENTER || transition == Geofence.GEOFENCE_TRANSITION_EXIT) {
List<String> geofenceIds = new ArrayList<>();
for (Geofence geofence : event.getTriggeringGeofences()) {
geofenceIds.add(geofence.getRequestId());
}
if (transition == Geofence.GEOFENCE_TRANSITION_ENTER || transition == Geofence.GEOFENCE_TRANSITION_EXIT) {
onEnteredGeofences(geofenceIds);
Log.e(TAG, "transition enter :) ");
}
}
}
}
}
// endregion
// region Private
private void onEnteredGeofences(List<String> geofenceIds) {
Log.e(TAG, "on entergeofense: ");
for (String geofenceId : geofenceIds) {
String geofenceName = "";
// Loop over all geofence keys in prefs and retrieve NamedGeofence from SharedPreference
Map<String, ?> keys = prefs.getAll();
for (Map.Entry<String, ?> entry : keys.entrySet()) {
String jsonString = prefs.getString(entry.getKey(), null);
NamedGeofense namedGeofence = gson.fromJson(jsonString, NamedGeofense.class);
if (namedGeofence.id.equals(geofenceId)) {
geofenceName = namedGeofence.name;
break;
}
}
// Set the notification text and send the notification
//String contextText = String.format("you entered in meeting room", geofenceName);
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, GeofenceMain.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.pizaper2)
.setContentTitle("Welcome to geofense")
.setContentText("hello KOKALIS")
.setContentIntent(pendingNotificationIntent)
.setStyle(new NotificationCompat.BigTextStyle().bigText("hello KOKALIS"))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.build(); // id
notificationManager.notify(0, notification);
Log.e(TAG, "notifications: ");
}
}
private void onError(int i) {
Log.e(TAG, "Geofencing Error: " + i);
}
// endregion
}
In your NamedGeofence class, change .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER) to .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT). Otherwise, you'd only monitor the enter events.
Transition types should be set as a bit-wise OR, as stated here.
Ok, so I was recently working on a small project for my own personal preference, and along the way I implemented a small bit of code that did not work. So, as most people would do, I deleted it. But later, I experienced the same glitch that the code prior was causing, but when I checked, it was not there! I may just be plain stupid, blind, or maybe both, but I keep getting only one card in the recyclerView to show up! Feel free to call me stupid if you can find an answer, and I thank you very much in advance.
P.S. Yes, I am very new to Java, so remember this before you decide to roast me.
My MainActivity:
package com.example.whateverthefuckyouwant;
//Imports, in case you couldn't tell
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.api.GoogleApiClient;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.GooglePlayServicesAvailabilityIOException;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.ExponentialBackOff;
import com.google.api.services.sheets.v4.SheetsScopes;
import com.google.api.services.sheets.v4.model.*;
import android.Manifest;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.EasyPermissions;
public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {
GoogleAccountCredential mCredential;
ProgressDialog mProgress;
static final int REQUEST_ACCOUNT_PICKER = 1000;
static final int REQUEST_AUTHORIZATION = 1001;
static final int REQUEST_GOOGLE_PLAY_SERVICES = 1002;
static final int REQUEST_PERMISSION_GET_ACCOUNTS = 1003;
private static final String PREF_ACCOUNT_NAME = "accountName";
private static final String[] SCOPES = {SheetsScopes.SPREADSHEETS_READONLY };
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
//ArrayList holding data from the Google Sheets API
ArrayList<Team> teamAF;
//Number of cards that the user has cycled through
int cardNumber = 1;
//Integers for direction of swipe. 8 = Right, 4 = Left
int RIGHT = 8;
int LEFT = 4;
boolean first = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize credentials and service object.
mCredential = GoogleAccountCredential.usingOAuth2(
getApplicationContext(), Arrays.asList(SCOPES))
.setBackOff(new ExponentialBackOff());
//Create Recycler View
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
//Specific size of Cards
mRecyclerView.setHasFixedSize(true);
//Design choices using LinearLayoutManager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//Create teamAF array list
teamAF = new ArrayList<>();
//Ads another card, so as to make an infinite number of cards
teamAF.add(new Team());
//Creating and setting mAdapter with teamAF
mAdapter = new MyAdapter(teamAF);
mRecyclerView.setAdapter(mAdapter);
//Swipe code for cardView
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
//Don't know what onMove does
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
Toast.makeText(MainActivity.this, "on Move", Toast.LENGTH_SHORT).show();
return false;
}
// Direction 4 = left, Direction 8 = right
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
//Prints swipeDir integer into console
Log.e(".", swipeDir + "");
//Sets variables to null, so they can be reset later
Team t = null;
//String s is reset to a string of code that enables it to check the string in the API with your answer.
String s = "";
//Code for answer. swipeDir == Left(4); Right(8).
if (swipeDir == LEFT) {
//Sets s
s = ((TextView) viewHolder.itemView.findViewById(R.id.left)).getText().toString();
} else if (swipeDir == RIGHT) {
//checks the answer swiped with he API
s = ((TextView) viewHolder.itemView.findViewById(R.id.right)).getText().toString();
}
//Removes card from array
t = teamAF.remove(mRecyclerView.getChildAdapterPosition(viewHolder.itemView));
//Adds some nice animation effect
mAdapter.notifyItemRemoved(mRecyclerView.getChildAdapterPosition(viewHolder.itemView));
//Sends a toast message saying "correct" or "incorrect"
if(t.checkAnswer(s)) {
Toast.makeText(MainActivity.this, "Correct!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Incorrect!", Toast.LENGTH_SHORT).show();
}
if(first) {
//This make the recyclerView shuffle
Collections.shuffle(teamAF, new Random());
first = false;
}
//Adding one, so the cards can go on forever
cardNumber++;
//Calls the methods
mAdapter = new MyAdapter(teamAF);
mRecyclerView.setAdapter(mAdapter);
//This is a 'benchmark' type 'achievement'
if (cardNumber == 50) {
Toast.makeText(getApplicationContext(), "You Reached 50 Points Without Losing! You're Doing Great!", Toast.LENGTH_SHORT).show();
} else if (cardNumber == 100) {
Toast.makeText(getApplicationContext(), "You Reached 100 Points Without Losing! You're A Genius!", Toast.LENGTH_SHORT).show();
}
}
};
//Allows the swiping inside the recyclerView
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(mRecyclerView);
//Calls the google API
mProgress = new ProgressDialog(this);
mProgress.setMessage("Loading...");
getResultsFromApi();
}
//The green was commented from the site
/**
* Attempt to call the API, after verifying that all the preconditions are
* satisfied. The preconditions are: Google Play Services installed, an
* account was selected and the device currently has online access. If any
* of the preconditions are not satisfied, the app will prompt the user as
* appropriate.
*/
private void getResultsFromApi() {
if (! isGooglePlayServicesAvailable()) {
acquireGooglePlayServices();
} else if (mCredential.getSelectedAccountName() == null) {
chooseAccount();
} else if (! isDeviceOnline()) {
System.out.println("No network connection available.");
} else {
new MakeRequestTask(mCredential).execute();
}
}
/**
* Attempts to set the account used with the API credentials. If an account
* name was previously saved it will use that one; otherwise an account
* picker dialog will be shown to the user. Note that the setting the
* account to use with the credentials object requires the app to have the
* GET_ACCOUNTS permission, which is requested here if it is not already
* present. The AfterPermissionGranted annotation indicates that this
* function will be rerun automatically whenever the GET_ACCOUNTS permission
* is granted.
*/
#AfterPermissionGranted(REQUEST_PERMISSION_GET_ACCOUNTS)
private void chooseAccount() {
if (EasyPermissions.hasPermissions(
this, Manifest.permission.GET_ACCOUNTS)) {
String accountName = getPreferences(Context.MODE_PRIVATE)
.getString(PREF_ACCOUNT_NAME, null);
if (accountName != null) {
mCredential.setSelectedAccountName(accountName);
getResultsFromApi();
} else {
// Start a dialog from which the user can choose an account
startActivityForResult(
mCredential.newChooseAccountIntent(),
REQUEST_ACCOUNT_PICKER);
}
} else {
// Request the GET_ACCOUNTS permission via a user dialog
EasyPermissions.requestPermissions(
this,
"This app needs to access your Google account (via Contacts).",
REQUEST_PERMISSION_GET_ACCOUNTS,
Manifest.permission.GET_ACCOUNTS);
}
}
/**
* Called when an activity launched here (specifically, AccountPicker
* and authorization) exits, giving you the requestCode you started it with,
* the resultCode it returned, and any additional data from it.
* #param requestCode code indicating which activity result is incoming.
* #param resultCode code indicating the result of the incoming
* activity result.
* #param data Intent (containing result data) returned by incoming
* activity result.
*/
#Override
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case REQUEST_GOOGLE_PLAY_SERVICES:
if (resultCode != RESULT_OK) {
} else {
getResultsFromApi();
}
break;
case REQUEST_ACCOUNT_PICKER:
if (resultCode == RESULT_OK && data != null &&
data.getExtras() != null) {
String accountName =
data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
SharedPreferences settings =
getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString(PREF_ACCOUNT_NAME, accountName);
editor.apply();
mCredential.setSelectedAccountName(accountName);
getResultsFromApi();
}
}
break;
case REQUEST_AUTHORIZATION:
if (resultCode == RESULT_OK) {
getResultsFromApi();
}
break;
}
}
/**
* Respond to requests for permissions at runtime for API 23 and above.
* #param requestCode The request code passed in
* requestPermissions(android.app.Activity, String, int, String[])
* #param permissions The requested permissions. Never null.
* #param grantResults The grant results for the corresponding permissions
* which is either PERMISSION_GRANTED or PERMISSION_DENIED. Never null.
*/
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String[] permissions,
#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(
requestCode, permissions, grantResults, this);
}
/**
* Callback for when a permission is granted using the EasyPermissions
* library.
* #param requestCode The request code associated with the requested
* permission
* #param list The requested permission list. Never null.
*/
#Override
public void onPermissionsGranted(int requestCode, List<String> list) {
// Do nothing.
}
/**
* Callback for when a permission is denied using the EasyPermissions
* library.
* #param requestCode The request code associated with the requested
* permission
* #param list The requested permission list. Never null.
*/
#Override
public void onPermissionsDenied(int requestCode, List<String> list) {
// Do nothing.
}
/**
* Checks whether the device currently has a network connection.
* #return true if the device has a network connection, false otherwise.
*/
private boolean isDeviceOnline() {
ConnectivityManager connMgr =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
}
/**
* Check that Google Play services APK is installed and up to date.
* #return true if Google Play Services is available and up to
* date on this device; false otherwise.
*/
private boolean isGooglePlayServicesAvailable() {
GoogleApiAvailability apiAvailability =
GoogleApiAvailability.getInstance();
final int connectionStatusCode =
apiAvailability.isGooglePlayServicesAvailable(this);
return connectionStatusCode == ConnectionResult.SUCCESS;
}
/**
* Attempt to resolve a missing, out-of-date, invalid or disabled Google
* Play Services installation via a user dialog, if possible.
*/
private void acquireGooglePlayServices() {
GoogleApiAvailability apiAvailability =
GoogleApiAvailability.getInstance();
final int connectionStatusCode =
apiAvailability.isGooglePlayServicesAvailable(this);
if (apiAvailability.isUserResolvableError(connectionStatusCode)) {
showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode);
}
}
/**
* Display an error dialog showing that Google Play Services is missing
* or out of date.
* #param connectionStatusCode code describing the presence (or lack of)
* Google Play Services on this device.
*/
void showGooglePlayServicesAvailabilityErrorDialog(
final int connectionStatusCode) {
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
Dialog dialog = apiAvailability.getErrorDialog(
MainActivity.this,
connectionStatusCode,
REQUEST_GOOGLE_PLAY_SERVICES);
dialog.show();
}
/**
* An asynchronous task that handles the Google Sheets API call.
* Placing the API calls in their own task ensures the UI stays responsive.
*/
private class MakeRequestTask extends AsyncTask<Void, Void, List<String>> {
private com.google.api.services.sheets.v4.Sheets mService = null;
private Exception mLastError = null;
MakeRequestTask(GoogleAccountCredential credential) {
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
mService = new com.google.api.services.sheets.v4.Sheets.Builder(
transport, jsonFactory, credential)
.setApplicationName("Google Sheets API Android Quickstart")
.build();
}
/**
* Background task to call Google Sheets API.
* #param params no parameters needed for this task.
*/
#Override
protected List<String> doInBackground(Void... params) {
try {
return getDataFromApi();
} catch (Exception e) {
mLastError = e;
cancel(true);
return null;
}
}
/**
* Fetch a list of names and majors of students in a sample spreadsheet:
* https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
* #return List of names and majors
*/
private List<String> getDataFromApi() throws IOException {
String spreadsheetId = "1KlflsDsBn0lhGT87OuRuy_RGOuBP2jBU5zpqn_UIYT0";
String range = "Sheet1!A2:B";
List<String> results = new ArrayList<String>();
ValueRange response = this.mService.spreadsheets().values()
.get(spreadsheetId, range)
.execute();
List<List<Object>> values = response.getValues();
for (List row : values) {
//Obtains the row from the Google Sheet
teamAF.add(new Team(row.get(0).toString(), row.get(1).toString()));
}
//Shuffle the cards with the data on them.
Collections.shuffle(teamAF, new Random());
/*for(String s : results) {
Log.e("HERE", s);
}*/
return results;
}
#Override
protected void onPreExecute() {
//mOutputText.setText("");
mProgress.show();
}
#Override
protected void onPostExecute(List<String> output) {
mProgress.hide();
if (output == null || output.size() == 0) {
//mOutputText.setText("No results returned.");
} else {
output.add(0, "Data retrieved using the Google Sheets API:");
//mOutputText.setText(TextUtils.join("\n", output));
}
}
#Override
protected void onCancelled() {
mProgress.hide();
if (mLastError != null) {
if (mLastError instanceof GooglePlayServicesAvailabilityIOException) {
showGooglePlayServicesAvailabilityErrorDialog(
((GooglePlayServicesAvailabilityIOException) mLastError)
.getConnectionStatusCode());
} else if (mLastError instanceof UserRecoverableAuthIOException) {
startActivityForResult(
((UserRecoverableAuthIOException) mLastError).getIntent(),
MainActivity.REQUEST_AUTHORIZATION);
} else {
//mOutputText.setText("The following error occurred:\n"
//+ mLastError.getMessage());
}
} else {
//mOutputText.setText("Request cancelled.");
}
}
}
}
My Adapter:
package com.example.whateverthefuckyouwant;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Random;
/**
* Created by ebuttikofer20 on 1/20/17.
*/
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ArrayList<Team> mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView mTextView;
public TextView left;
public TextView right;
public ViewHolder(View v) {
super(v);
mTextView = (TextView) v.findViewById(R.id.info_text);
left = (TextView) v.findViewById(R.id.left);
right = (TextView) v.findViewById(R.id.right);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(ArrayList<Team> myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_text_view, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your data at this position
// - replace the contents of the view with that element
holder.mTextView.setText(mDataset.get(position).getTeamName());
Random gen = new Random();
if(gen.nextBoolean()) {
lefter = mDataset.get(position).getTeamNumber();
righter = mDataset.get(gen.nextInt(mDataset.size())).getTeamNumber();
holder.left.setText(lefter);
holder.right.setText(righter);
} else {
righter = mDataset.get(
position).getTeamNumber();
lefter = mDataset.get(gen.nextInt(mDataset.size())).getTeamNumber();
holder.right.setText(righter);
holder.left.setText(lefter);
}
}
String righter;
String lefter;
public String getLeft() {
return lefter;
}
public String getRighter() {
return righter;
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.size();
}
}
set your parent layout's height in your R.layout.my_text_view file to wrap_content
I had the same challenge but i had to set my parent layout height to android:layout_height="wrap_content"
That worked for me so well
The following code is giving me null pointer exception even though I can't find anything wrong with the code. Tried commenting it out and it seems to be working. But still not able to find out what is wrong with the code? tried my own trouble shooting of commenting out the code and such and right now the code below is giving me nullpointer exception
Log Cat
12-19 05:49:14.833: E/AndroidRuntime(3392): Caused by:
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.widget.Button.setOnClickListener(android.view.View$OnClickListener)'
on a null object reference 12-19 05:49:14.833: E/AndroidRuntime(3392):
at
com.techiequickie.bharath.boadraf.newBet_activity.onCreate(newBet_activity.java:80)
Code:
package com.techiequickie.bhr.boadraf;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.Toast;
import org.json.JSONException;
import org.json.JSONObject;
import databasehandler.DatabaseHandler;
import databasehandler.UserFunctions;
/**
* Created by YP on 17-Nov-14.
*/
public class newBet_activity extends ActionBarActivity
{
EditText inputBetname, inputBetbrief, inputBetdescription;
SeekBar valueSeekbar; //= null;
Button placeBet;
// JSON Response node names
private static String KEY_SUCCESS = "success";
#SuppressWarnings("unused")
private static String KEY_ERROR = "error";
#SuppressWarnings("unused")
private static String KEY_ERROR_MSG = "error_msg";
//private static String KEY_UID = "uid";
private static String KEY_BETNAME = "bet_name";
private static String KEY_BETBRIEF = "bet_brief";
private static String KEY_BETDESCRIPTION = "bet_description";
private static String KEY_BETVALUE = "bet_value";
// private static String KEY_CREATED_AT = "created_at";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.newbet);
// Importing all assets like buttons, text fields
inputBetname = (EditText) findViewById(R.id.betName_et);
inputBetbrief = (EditText) findViewById(R.id.betBriefDescription_et);
inputBetdescription = (EditText) findViewById(R.id.betDescription_et);
placeBet = (Button) findViewById(R.id.btn_newbet);
//valueSeekbar = (SeekBar) findViewById(R.id.betValue_bar);
/*
valueSeekbar.setOnSeekBarChangeListener
(
new SeekBar.OnSeekBarChangeListener()
{
int progressChanged = 0;
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
progressChanged = progress;
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
Toast.makeText(newBet_activity.this, "seek bar progress:" + progressChanged, Toast.LENGTH_SHORT).show();
}
}
);*/
placeBet.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
String betname = inputBetname.getText().toString();
String betBrief = inputBetbrief.getText().toString();
String betDescription = inputBetdescription.getText().toString();
//StringBuilder betValue = ((toString()) valueSeekbar.getProgress());
//new BetRegisterTask().execute(betname,betBrief,betDescription);
}
}
);
}
/*
class BetRegisterTask extends AsyncTask<String, Void, String>
{
#Override
protected String doInBackground(String... params)
{
UserFunctions userFunction = new UserFunctions();
JSONObject json = userFunction.createBet(params[0], params[1], params[2]);
// check for login response
try
{
if (json.getString(KEY_SUCCESS) != null)
{
String res = json.getString(KEY_SUCCESS);
if (Integer.parseInt(res) == 1)
{
// user successfully registred
// Store user details in SQLite Database
DatabaseHandler db = new DatabaseHandler(getApplicationContext());
JSONObject json_user = json.optJSONObject("user");
// Clear all previous data in database
userFunction.logoutUser(getApplicationContext());
db.newBet(json_user.getString(KEY_BETNAME), json_user.getString(KEY_BETBRIEF), json.getString(KEY_BETDESCRIPTION));
return "1";
}
}
} catch (JSONException e)
{
e.printStackTrace();
}
return "0";
}
#Override
protected void onPostExecute(String s)
{
super.onPostExecute(s);
if (s.equals("1"))
{
// Launch Dashboard Screen
Intent dashboard = new Intent(getApplicationContext(), Loginactivity.class);
// Close all views before launching Dashboard
dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(dashboard);
// Close Registration Screen
finish();
showToastforSucessfulBetCreation();
}
else
{
// Error in registration
//registerErrorMsg.setText("Error occurred in registration");
showToastforUnsucessfulBetCreation();
}
}
}*/
public void showToastforSucessfulBetCreation() {
Toast toast = Toast.makeText(this, "Registration Sucessfull", Toast.LENGTH_LONG);
toast.setGravity(Gravity.BOTTOM, 0, 30);
toast.show();
}
public void showToastforUnsucessfulBetCreation() {
Toast toast = Toast.makeText(this, "Registration UnSucessfull", Toast.LENGTH_LONG);
toast.setGravity(Gravity.BOTTOM, 0, 30);
toast.show();
}
}
placeBet is not yet initialized that's why it is giving null pointer exception
check the following line
palceBet=findViewId(R.id.btn_newbet);
It seems that you did not create Button with id btn_newbet in the .xml file.
so to find if you define this button in xml file or not you should take your cursor over btn_newbet in
placeBet = (Button) findViewById(R.id.btn_newbet);
and if onclicking ,it will redirect to correct xml .