Notifications not Showing up in Android while using Tabs - android

I am writing an app in which i am using two tabs, one to get list of facebook friends and second tab to get list of phonebook friends
And In Phonebook friends tab i am also getting friends birthdays and also showing reminder for that, and i am able to get reminder as well if i will try it alone, without combined to another Tab (i.e.: with Facebook Tab)
It means once i combined it in Tabs, then i am not getting any birthday Notifications.
I am using below class to get Notifications for Phonebook friends birthdays:
public class BirthdayReminder extends ListActivity {
// TODO: call/write message on birthday
// TODO: hideNotificationPref
private final DateFormatSymbols dateSymbols = new DateFormatSymbols();
private Database db;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getListView().setFastScrollEnabled(true);
this.db = new Database(getContentResolver());
// debug code
// Debug.logDatabase(this);
// start BirthdayBroadcastReceiver if it is activated
Preferences prefs = Preferences.getInstance(getApplicationContext());
if (prefs.getActivateService()) {
BirthdayBroadcastReceiver.restart(getApplicationContext());
}
}
#Override
protected void onResume() {
super.onResume();
updateView();
}
private void updateView() {
// create new list adapter
MultiListAdapter listAdapter = new MultiListAdapter();
List<ListAdapter> adapterList = listAdapter.getListAdapters();
// load birthday and contact information
List<Contact> contacts = this.db.getAllContacts();
List<BirthContact> birthContacts = BirthContactHelper.createBirthContactList(contacts);
// group all contacts by known and unknown birthday
SortedSet<BirthContact> knownBirthdays = new TreeSet<BirthContact>(new BirthContactBirthdayComparator());
SortedSet<BirthContact> unknownBirthdays = new TreeSet<BirthContact>(new BirthContactNameComparator());
for (BirthContact birthContact : birthContacts) {
DateOfBirth dateOfBirth = birthContact.getDateOfBirth();
if (dateOfBirth != null) {
knownBirthdays.add(birthContact);
} else {
unknownBirthdays.add(birthContact);
}
}
Integer currentMonth = null;
BirthContactAdapter currentBirthContactAdapter = null;
String[] monthStrs = this.dateSymbols.getMonths();
for (BirthContact birthContact : knownBirthdays) {
int month = birthContact.getDateOfBirth().getDate().get(Calendar.MONTH);
if (currentMonth == null || currentMonth != month) {
currentMonth = month;
currentBirthContactAdapter = new BirthContactAdapter(this);
adapterList.add(new CategoryAdapter(this, monthStrs[currentMonth]));
adapterList.add(currentBirthContactAdapter);
}
currentBirthContactAdapter.add(birthContact);
}
adapterList.add(new CategoryAdapter(this, getResources().getString(R.string.unknownBirthdays)));
adapterList.add(new BirthContactAdapter(this, unknownBirthdays));
setListAdapter(listAdapter);
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
BirthContact birthContact = (BirthContact) l.getAdapter().getItem(position);
Intent editorIntent = new Intent(this, BirthdayEditor.class);
editorIntent.putExtra(BirthdayEditor.CONTACT_ID, birthContact.getContact().getId());
startActivity(editorIntent);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.layout.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.preferences:
startActivity(new Intent(this, PreferenceWindow.class));
return true;
case R.id.quit:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
I am using below code to call two different classes while click on a particular tab.
but whenever i change it to tab, i am not getting any notification, TabSample.java:
public class TabSample extends TabActivity {
String response;
#SuppressWarnings("unused")
private static JSONArray jsonArray;
public static TabHost mTabHost;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Bundle extras = getIntent().getExtras();
if (extras == null) {
return;
}
response = getIntent().getStringExtra("FRIENDS");
try {
jsonArray = new JSONArray(response);
} catch (JSONException e) {
FacebookUtility.displayMessageBox(this,
this.getString(R.string.json_failed));
}
setTabs();
}
private void setTabs() {
addTab("", R.drawable.tab_menu, com.chr.tatu.sample.friendslist.facebook.FriendsList.class);
addTab("", R.drawable.tab_contact, com.chr.tatu.sample.friendslist.contacts.BirthdayReminder.class);
}
Notification:
public class BirthdayBroadcastReceiver extends BroadcastReceiver {
private static final String TIMED = "timed";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getBooleanExtra(TIMED, false)) {
notifyBirthdays(context);
}
start(context);
}
private static PendingIntent createPendingIntent(Context context) {
Intent intent = new Intent(context, BirthdayBroadcastReceiver.class);
intent.putExtra(TIMED, true);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public static void start(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = createPendingIntent(context);
Preferences prefs = Preferences.getInstance(context);
Time nextUpdateTime = prefs.getUpdateTime();
Calendar wakeUpCal = Calendar.getInstance();
wakeUpCal.set(Calendar.HOUR_OF_DAY, nextUpdateTime.getHours());
wakeUpCal.set(Calendar.MINUTE, nextUpdateTime.getMinutes());
wakeUpCal.set(Calendar.SECOND, wakeUpCal.getActualMinimum(Calendar.SECOND));
wakeUpCal.set(Calendar.MILLISECOND, wakeUpCal.getActualMinimum(Calendar.MILLISECOND));
if (wakeUpCal.before(Calendar.getInstance())) {
wakeUpCal.add(Calendar.DAY_OF_MONTH, 1);
}
alarmManager.set(AlarmManager.RTC_WAKEUP, wakeUpCal.getTimeInMillis(), pendingIntent);
}
public static void stop(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = createPendingIntent(context);
alarmManager.cancel(pendingIntent);
pendingIntent.cancel();
}
public static void restart(Context context) {
stop(context);
start(context);
}
private void notifyBirthdays(Context context) {
Calendar today = CalendarUtils.todaysCalendar();
Database db = new Database(context.getContentResolver());
Preferences prefs = Preferences.getInstance(context);
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Resources res = context.getResources();
List<Contact> contacts = db.getAllContacts();
// calculate next birthdays
SortedMap<Integer, List<String>> nextBirthdays = new TreeMap<Integer, List<String>>();
for (Contact contact : contacts) {
Integer timeSpanToNextBirthday = null;
for (RawContact rawContact : contact.getRawContacts()) {
for (DateOfBirth dateOfBirth : rawContact.getDatesOfBirth()) {
int timeSpan = CalendarUtils.timeSpanToNextBirthday(today, dateOfBirth.getDate());
if (timeSpanToNextBirthday == null || timeSpanToNextBirthday > timeSpan) {
timeSpanToNextBirthday = timeSpan;
}
}
}
if (timeSpanToNextBirthday != null && timeSpanToNextBirthday <= prefs.getDaysBeforeReminder()) {
List<String> infoNames = nextBirthdays.get(timeSpanToNextBirthday);
if (infoNames == null) {
infoNames = new ArrayList<String>();
nextBirthdays.put(timeSpanToNextBirthday, infoNames);
}
infoNames.add(contact.getName());
}
}
// collect all sentences for the notification
List<String> notificationTexts = new ArrayList<String>();
int countBirthdays = 0;
for (Integer days : nextBirthdays.keySet()) {
List<String> birthdayList = nextBirthdays.get(days);
String names = StringUtils.join(birthdayList, ", ").toString();
notificationTexts.add(getBirthdayText(res, days, names));
countBirthdays += birthdayList.size();
}
// cancel all notifications (clear old once)
notificationManager.cancelAll();
// create new notification
if (notificationTexts.size() > 0) {
String titleText = String.format(res.getQuantityString(R.plurals.notificationTitle, countBirthdays),
countBirthdays);
Intent intent = new Intent(context, BirthdayReminder.class);
Notification notification = new Notification(R.drawable.balloons2, titleText, System.currentTimeMillis());
if (countBirthdays > 1) {
notification.number = countBirthdays;
}
PendingIntent pi = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
notification.setLatestEventInfo(context, titleText, StringUtils.join(notificationTexts, ", "), pi);
notificationManager.notify(0, notification);
}
}
private String getBirthdayText(Resources res, int days, String names) {
String text;
switch (days) {
case 0:
text = String.format(res.getString(R.string.notificationText_today), names);
break;
case 1:
text = String.format(res.getString(R.string.notificationText_tomorrow), names);
break;
default:
text = String.format(res.getString(R.string.notificationText_other), days, names);
}
return text;
}
}

Are you using correct package name with Notifications Service class, like i have made same type of project few months ago and i was struggling at same movement and when i got my mistake that was just silly:
It is the correct way:
<receiver android:name="packagename.BirthdayBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

Related

.getStringExtra returning null value instead String

Getting value in putExtra But cant retrieve in getStringExtra.
public class StartNotificationReceiver extends BroadcastReceiver{
private void sendTodayNotification() {
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
Date todateDate = new Date();
String TodayDate_String = dateFormat.format(todateDate);
String Val=AppSettingsPref.getStringValue(context, AppSettingsPref.KEY_TODAY_DATE_AND_TIME, "");
if(!Val.equals(TodayDate_String))
{
AppSettingsPref.saveString(context, AppSettingsPref.KEY_TODAY_DATE_AND_TIME, TodayDate_String);
final HGDate englishDate = new HGDate(context);
englishDate.setGregorian(Calendar.YEAR, Calendar.MONTH + 1, 1);
final HGDate islamicDateToday = new HGDate(englishDate);
islamicDateToday.toHigri();
int islamicDayToday = islamicDateToday.getDay();
int islamicMonthToday = islamicDateToday.getMonth();
String otherMonth = Dates.islamicMonthName(context, islamicDateToday.getMonth() - 1);
int adjustedDate = AppSettingsPref.getIntValue(context, AppSettingsPref.CURRENT_ADJUSTMENT_KEY, 0);
String todayDateTimeinhijri = islamicDateToday.getDay() + (adjustedDate) + " "
+ otherMonth + " " + islamicDateToday.getYear();
Intent intent = new Intent(context,NotificationReceiver.class);
-------->intent.putExtra("todayDateTimeinhijri", todayDateTimeinhijri.toString());<-----------
databaseAccess = DatabaseAccess.getInstance(context);
databaseAccess.open();
ArrayList<Event> events = databaseAccess.showEventsByMuslimType(muslimType);
for (int i = 0; i < events.size(); i++) {
Event event = events.get(i);
String[] date = event.getHejriDate().split("-");
int islamicDayOfEvent = Integer.parseInt(date[0].trim());
int islamicMonthOfEvent = Integer.parseInt(date[1].trim());
boolean isViladat = event.isVilaadat;
if (islamicDayToday == islamicDayOfEvent && islamicMonthToday == islamicMonthOfEvent) {
makeNotification(event);
}
}
}
intent.putExtra("todayDateTimeinhijri", todayDateTimeinhijri.toString());
This is where .getStringExtra is getting null value
public class NotificationReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
this.context = context;
}
todayDateTime2 = intent.getStringExtra("todayDateTimeinhijri");
}
The extra code is removed for better understanding
Thanks in advance
Help will be appreciated.
cant find solution.
Where do you send (or start) the intent with the parameter "todayDateTimeinhijri"?
If you don't send the intent the NotificationReceiver isn't able to receive anything.
//example activity using receiver and send intent via broadcast ( sendBroadcast(intent) )
public class Example extends AppCompatActivity {
private NotificationReceiver mNotificationReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNotificationReceiver = new NotificationReceiver();
IntentFilter intentFilter = new IntentFilter("your_action");
registerReceiver(mNotificationReceiver, intentFilter);
StartNotificationReceiver mStartNotificationReceiver = new StartNotificationReceiver(getApplicationContext());
mStartNotificationReceiver.sendTodayNotification();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mNotificationReceiver != null) {
unregisterReceiver(mNotificationReceiver);
}
}
private class NotificationReceiver extends BroadcastReceiver {
Context context;
#Override
public void onReceive(Context context, Intent intent) {
this.context = context;
String action = intent.getAction();// should be "your_action"
String todayDateTime2 = intent.getStringExtra("todayDateTimeinhijri");
Log.i("NotificationReceiver","action: " + action );
Log.i("NotificationReceiver","dateTime: " + todayDateTime2 );
}
}
public class StartNotificationReceiver {
private Context context;
public StartNotificationReceiver(Context ctx){
this.context = ctx;
}
public void sendTodayNotification() {
Intent intent = new Intent("your_action");
intent.putExtra("todayDateTimeinhijri", "your String value");
context.sendBroadcast(intent);
}
}
}
Putting the extra in the intent does not send it. There sould be a sendBroadcast() call or similar somewhere.

Android app crashes on 4.4.4 device but not 4.4.2/5.0 emulator?

I'm using Android Studio to develop my first app. On my 4.4.4 device, I can launch MainActivity but when I click something on the screen that navigates to another activity, the app crashes. It only crashes on my one device, and runs fine on my Note 2 running 4.4.2, as well as two emulators running 4.4.2 and 5.0.
I've tried downloading several free LogCat apps onto my device, but none of them have worked. Otherwise, I'm unable to view any sort of LogCat message on my computer because I'm unable to download Samsung's device driver (constantly getting timed out). Both emulators aren't crashing, but they give OpenGL errors.
Here is my MainActivity, if that's not enough then the full code is here.
public class MainActivity extends Activity {
SharedPreferences firstCheck,
spPointValue,
spNotifications,
spSpreadsheets;
SharedPreferences.Editor editor;
final int initialPointValue = 15;
int screenWidth, screenHeight;
static final String prefsPointValueName = "userPointValue",
prefsNotificationToggle = "notificationToggle",
prefsSpreadsheets = "spreadsheets",
directionsURI = "geo:0,0?q=11000+Beach+Blvd+Jacksonville+Fl+32246",
facebookURL = "https://www.facebook.com/ComedyClubOfJacksonville",
twitterURL = "https://twitter.com/comedyclubofjax",
showSpreadsheetURL = "https://docs.google.com/spreadsheets/d/1Ax2-gUY33i_pRHZIwR8AULy6-nbnAbM8Qm5-CGISevc/gviz/tq",
dealsSpreadsheetURL = "https://docs.google.com/spreadsheets/d/1dnpODnbz6ME4RY5vNwrtAc6as3-uj2rK_IgtYszsvsM/gviz/tq";
Intent browserIntent, alarmIntent/*, updateIntent*/;
MyAdapter adapter;
ListView listView;
ConnectivityManager connMgr;
NetworkInfo networkInfo;
ArrayList<Show> shows;
ArrayList<Offer> offers;
DateFormat df;
Date today;
java.util.Calendar calendar, updateCalendar;
AlarmManager alarmManager, updateAlarmManager;
PendingIntent pendingIntent, updatePendingIntent;
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out.println("onCreate called");
declarations();
addMenuButtonFunctionality();
setListViewAdapter();
checkFirstRun();
checkForPastShows();
}//end onCreate
public void declarations() {
ActivityManager manager = new ActivityManager(this);
manager.manageActionBar(getActionBar());
manager.scaleBackground((LinearLayout) findViewById(R.id.linearLayoutMain), R.drawable.background);
manager.scaleImage((ImageView) findViewById(R.id.ivLogo), R.drawable.comedyclublogo2, 1, .5);
firstCheck = PreferenceManager.getDefaultSharedPreferences(this);
shows = new ArrayList<>();
offers = new ArrayList<>();
spSpreadsheets = getSharedPreferences(prefsSpreadsheets, MODE_PRIVATE);
/*
creates the ListView adapter and populates the ListView using generateData()
*/
adapter = new MyAdapter(this, generateData());
listView = (ListView) findViewById(R.id.listview);
/*
simpledateformat used to compare dates from spreadsheet
to current date
*/
df = new SimpleDateFormat("MM/dd/yyyy", Locale.US);
today = new Date();
today.setTime(System.currentTimeMillis() - 1000 * 60 * 60 * 24);
spNotifications = getSharedPreferences(prefsNotificationToggle, MODE_PRIVATE);
/*
alarmmanager and notification declarations
*/
alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarmIntent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
calendar = java.util.Calendar.getInstance();
/*
updateAlarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
updateIntent = new Intent(MainActivity.this, Update.class);
updatePendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, updateIntent, PendingIntent.FLAG_CANCEL_CURRENT);
updateCalendar = java.util.Calendar.getInstance();
*/
}//end declarations
public void manageNotifications() {
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.FRIDAY);
calendar.set(java.util.Calendar.HOUR_OF_DAY, 8);
calendar.set(java.util.Calendar.MINUTE, 15);
/*
sets alarm manager to go off at 8:15 in the morning every 7 days on Thursday
for testing, starts at 815 every morning starting wednesday
*/
alarmManager.setInexactRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24/*1000 * 60 * 60 * 24 * 7*/, pendingIntent);
}//end manageNotifications
public void updateSpreadsheets() {
/*
not currently being used, will revisit later.
*/
updateCalendar.setTimeInMillis(System.currentTimeMillis());
updateCalendar.set(java.util.Calendar.HOUR_OF_DAY, 0);
updateCalendar.set(java.util.Calendar.MINUTE, 0);
updateAlarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, updateCalendar.getTimeInMillis(), 1000 * 60 * 60 * 24, updatePendingIntent);
}//end updateSpreadsheets
public void checkForPastShows() {
try {
for (int i = 0; i < shows.size(); i++) {
if (today.after(df.parse(shows.get(i).getShowDate())))
shows.remove(i);
for (int j = 0; j < shows.size(); j++) {
if (shows.get(i).equals(shows.get(j)) && i != j)
shows.remove(j);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void setListViewAdapter() {
listView.setAdapter(adapter);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position, long arg3) {
switch (position) {
case 0://this weekend
if (!shows.isEmpty())
startActivity(new Intent(MainActivity.this, ThisWeekend.class).putParcelableArrayListExtra("shows", shows));
else {
getShows();
startActivity(new Intent(MainActivity.this, Calendar.class).putParcelableArrayListExtra("shows", shows));
}
System.out.println("this weekend clicked");
break;
case 1://calendar
if (!shows.isEmpty())
startActivity(new Intent(MainActivity.this, Calendar.class).putParcelableArrayListExtra("shows", shows));
else {
getShows();
startActivity(new Intent(MainActivity.this, Calendar.class).putParcelableArrayListExtra("shows", shows));
}
System.out.println("calendar clicked");
break;
case 2://rewards and offers
if (!offers.isEmpty())
startActivity(new Intent(MainActivity.this, Deals.class).putParcelableArrayListExtra("offers", offers));
else {
getDeals();
startActivity(new Intent(MainActivity.this, Deals.class).putParcelableArrayListExtra("offers", offers));
}
System.out.println("deals clicked");
break;
case 3://food and drink
startActivity(new Intent(MainActivity.this, FoodAndDrink.class));
System.out.println("food and drink clicked");
break;
case 4://groups and parties
startActivity(new Intent(MainActivity.this, GroupsAndParties.class).putParcelableArrayListExtra("shows", shows));
System.out.println("groups and parties clicked");
break;
}
}
});
}//end setListViewAdapter
public void checkFirstRun() {
/*
first run check. If first run, sets reward point value to 15, sets notifications
to true, manages notifications.
*/
getShows();
getDeals();
if (!firstCheck.getBoolean("firstRun", false)) {
spPointValue = getSharedPreferences(prefsPointValueName, MODE_MULTI_PROCESS);
editor = spPointValue.edit();
editor.putInt("pointValue", initialPointValue);
editor.apply();
editor = spNotifications.edit();
editor.putBoolean("notifications", true);
editor.apply();
editor = firstCheck.edit();
editor.putBoolean("firstRun", true);
editor.apply();
manageNotifications();
//updateSpreadsheets();
} else {
try {
processShowsJson(new JSONObject(spSpreadsheets.getString("showsSpreadsheet", "")));
processDealsJson(new JSONObject(spSpreadsheets.getString("dealsSpreadsheet", "")));
} catch (Exception e) {
e.printStackTrace();
}
}
}//end checkFirstRun
private ArrayList<Model> generateData() {
/*
populates the ListView on activity_main.xml with an icon and title.
*/
ArrayList<Model> models = new ArrayList<>();
models.add(new Model(R.drawable.ic_action_event, "This Weekend"));
models.add(new Model(R.drawable.ic_action_go_to_today, "Upcoming Shows"));
models.add(new Model(R.drawable.ic_action_important_gold, "Rewards and Offers"));
models.add(new Model(R.drawable.ic_action_view_as_list, "Food and Drinks"));
models.add(new Model(R.drawable.ic_action_group, "Groups and Parties"));
return models;
}
public void addMenuButtonFunctionality() {
/*
enables overflow menu icon, even with presence of hardware menu key
*/
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if (menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception e) {
// presumably, not relevant
}
}
#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) {
System.out.println("onOptionsItemSelected called");
int id = item.getItemId();
switch (id) {
case R.id.action_settings:
startActivity(new Intent(MainActivity.this, Settings.class));
System.out.println("settings clicked");
return true;
case R.id.action_directions:
Intent directionsIntent = new Intent(Intent.ACTION_VIEW).setData(Uri.parse(directionsURI));
if (directionsIntent.resolveActivity(getPackageManager()) != null) {
startActivity(directionsIntent);
}
System.out.println("directions clicked");
return true;
case R.id.action_about_us:
startActivity(new Intent(MainActivity.this, AboutUs.class));
System.out.println("about us clicked");
return true;
case R.id.action_contact:
startActivity(new Intent(MainActivity.this, Contact.class));
System.out.println("contact clicked");
return true;
case R.id.action_now_hiring:
startActivity(new Intent(MainActivity.this, NowHiring.class));
System.out.println("now hiring clicked");
return true;
case R.id.action_report_a_bug:
startActivity(new Intent(MainActivity.this, ReportABug.class));
System.out.println("report a bug clicked");
default:
return super.onOptionsItemSelected(item);
}
}//end onOptionsItemSelected
public void onFacebookClick(View view) {
/*
handles the click method for the facebook button. opens an internet intent for the
comedy club facebook.
*/
browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(facebookURL));
startActivity(browserIntent);
}//onFacebookClick
public void onTwitterClick(View view) {
/*
handles the click method for the twitter button. opens an internet intent for the
comedy club twitter.
*/
browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(twitterURL));
startActivity(browserIntent);
}//end onTwitterClick
public void getShows() {
connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
networkInfo = connMgr.getActiveNetworkInfo();
try {
if (networkInfo != null && networkInfo.isConnected()) {
new DownloadWebpageTask(this, new AsyncResult() {
#Override
public void onResult(JSONObject object) {
if (!object.toString().equals(spSpreadsheets.getString("showsSpreadsheet", ""))) {
System.out.println("shows spreadsheet is the same");
processShowsJson(object);
editor = spSpreadsheets.edit();
editor.putString("showsSpreadsheet", object.toString());
editor.apply();
}
}
}).execute(showSpreadsheetURL);
} else {
Toast.makeText(this, "Network not available.", Toast.LENGTH_SHORT).show();
System.out.println("Network info not available.");
}
} catch (Exception e) {
e.printStackTrace();
}
}//end getShows
public void getDeals() {
connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
networkInfo = connMgr.getActiveNetworkInfo();
try {
if (networkInfo != null && networkInfo.isConnected()) {
new DownloadWebpageTask(this, new AsyncResult() {
#Override
public void onResult(JSONObject object) {
if (!object.toString().equals(spSpreadsheets.getString("dealsSpreadsheet", ""))) {
System.out.println("deals spreadsheet is the same");
processDealsJson(object);
editor = spSpreadsheets.edit();
editor.putString("dealsSpreadsheet", object.toString());
editor.apply();
}
}
}).execute(dealsSpreadsheetURL);
} else {
Toast.makeText(this, "Network not available.", Toast.LENGTH_SHORT).show();
System.out.println("Network info not available.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void processShowsJson(JSONObject object) {
try {
JSONArray rows = object.getJSONArray("rows");
for (int i = 0; i < rows.length(); ++i) {
JSONObject row = rows.getJSONObject(i);
JSONArray columns = row.getJSONArray("c");
String showDate = columns.getJSONObject(0).getString("v");
int showTime = columns.getJSONObject(1).getInt("v");
String comedian = columns.getJSONObject(2).getString("v");
String description = columns.getJSONObject(3).getString("v");
String videoURL = columns.getJSONObject(4).getString("v");
Show show = new Show(comedian, description, showDate, showTime, videoURL);
shows.add(show);
}
} catch (JSONException e) {
e.printStackTrace();
}
}//end processShowsJson
private void processDealsJson(JSONObject object) {
try {
JSONArray rows = object.getJSONArray("rows");
for (int i = 0; i < rows.length(); ++i) {
JSONObject row = rows.getJSONObject(i);
JSONArray columns = row.getJSONArray("c");
String offerTitle = columns.getJSONObject(0).getString("v");
String offerDescription = columns.getJSONObject(1).getString("v");
int pointValue = columns.getJSONObject(2).getInt("v");
Offer offer = new Offer(pointValue, offerTitle, offerDescription);
offers.add(offer);
}
} catch (JSONException e) {
e.printStackTrace();
}
}//end processDealsJson
}

App widget fetch data from server

I have developed a widget which will fetch the data from a server and do some modifications and display in widget.
I have a ALARM manager which starts a service in every 10 sec and service fetches data with async task and display.
It consumes a lot of CPU usage.
Kindly help if I can change the code design and make the widget more effective.
I use Jsoup to connect and fetch data.
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Log.d("Widget : " , "Inside onUpdate widget");
// To prevent any ANR timeouts, we perform the update in a service
final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
final Calendar TIME = Calendar.getInstance();
TIME.set(Calendar.MINUTE, 0);
TIME.set(Calendar.SECOND, 0);
TIME.set(Calendar.MILLISECOND, 0);
final Intent i = new Intent(context, UpdateService.class);
if (service == null)
{
service = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
}
m.setRepeating(AlarmManager.RTC, TIME.getTime().getTime(), 100 * 60, service);
}
public static class UpdateService extends Service {
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// System.out.println("Inside config change ");
enableControls(this);
}
#Override
public void onStart(Intent intent, int startId) {
// Build the widget update for today
mContext = this;
Log.d("Widget : " , "Service started");
enableControls(this);
}
public static void enableControls(Context context){
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_status);
Intent active = new Intent(context, MyWidgetProvider.class);
active.setAction(ACTION_WIDGET_REFRESH);
active.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context, 0, active, 0);
pushWidgetUpdate(context, remoteViews);
fetchStatus();
}
public static void fetchStatus(){
new AsyncTask<String, Void, String>() {
#Override
protected String doInBackground(String... urls) {
try {
if(getWiFiStatus(mContext) == true ){
boolean getRedirectedURL = false;
String url,finalURL;
finalURL = "http://mobile.server.status";
Document doc = Jsoup.connect(finalURL).get();
while(getRedirectedURL == false){
Log.d(LOG_TAG,"inside while loop ---- : " + getRedirectedURL);
doc = Jsoup.connect(finalURL).get();
Log.d(LOG_TAG,"Complete doc: " + doc);
// System.out.println("Found the doc : " +doc.toString().contains("status"));
// Log.d(LOG_TAG,"Whole data third :"+doc);
// System.out.println("Printing redirected URL " + (docHead.select("meta")));
if(doc.toString().contains("status")){
getRedirectedURL = true;
break;
}
else
getRedirectedURL = false;
Elements docHead = doc.select("meta");
for(Element emt :docHead) {
url =null;
//Log.d(LOG_TAG,"Value boolean :"+emt.getElementsByAttribute("http-equiv").toString().toLowerCase().contains("url"));
if(emt.getElementsByAttribute("http-equiv").toString().toLowerCase().contains("url") ){
//getRedirectedURL = true;
url = emt.getElementsByAttribute("http-equiv").toString().toLowerCase().split("url=")[1].toString();
if (emt.getElementsByAttribute("http-equiv").toString().toLowerCase().contains("http://")){
finalURL = null;
finalURL = url.split("\"")[0].toString();
}
else
finalURL = finalURL + url.split("\"")[0].toString();
//Log.d(LOG_TAG,"Final URL :"+finalURL);
}
// else
// getRedirectedURL = false;
}
}
Log.d(LOG_TAG,"Final URL :"+finalURL);
doc = Jsoup.connect(finalURL).get();
Document noFramesDoc = Jsoup.parseBodyFragment(doc.toString());
}
else{
refreshStatus(mContext);
}
} catch (UnknownHostException exception){
System.out.println("Inside unknown host : ");
}
catch (Exception e) {
Log.d(LOG_TAG,"other Exception found :"+e.toString());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
if(mContext != null)
}
#Override
protected void onCancelled() {
}
}.execute();
}

Receive Push Notifications into library project (Android C2DM in a lib project)

I have one project as a library of another one because I need whitelabeling it (and more projects for other partners). In the library project, I have implemented push notifications system. I've executed the library project as a normal project and the pushs work like a charm. My problem happens when i am importing this project as a library in another project. The receiver is never called.
There is one post with the same issue but the solution is not working for me. I am getting crazy!!!
Android C2DM and lib project
The main problem is that I am not receiving the message from C2DM. My code is the next:
Manifests of the both project (I have the same piece of code in both projects) (I am using the tags lib_project and app_project to be clear):
<receiver
android:name="com.lib_project.C2DMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.app_project.android" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.app_project.android" />
</intent-filter>
</receiver>
And the permissions:
<uses-permission android:name="com.app_project.android.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name="com.app_project.android.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
And also I have declared in the manifest the service that manage the push notifications but it is called properly.
<service android:name="com.lib_project.android.C2DMReceiver" />
Really, I don't know what is wrong. I think is ok but is not working. Thanks in advance.
It is my class C2DMBaseReceiver :
public abstract class C2DMBaseReceiver extends IntentService {
private static final String C2DM_RETRY = "com.google.android.c2dm.intent.RETRY";
public static final String REGISTRATION_CALLBACK_INTENT = "com.google.android.c2dm.intent.REGISTRATION";
private static final String C2DM_INTENT = "com.google.android.c2dm.intent.RECEIVE";
// Logging tag
private static final String TAG = "C2DM";
// Extras in the registration callback intents.
public static final String EXTRA_UNREGISTERED = "unregistered";
public static final String EXTRA_ERROR = "error";
public static final String EXTRA_REGISTRATION_ID = "registration_id";
public static final String ERR_SERVICE_NOT_AVAILABLE = "SERVICE_NOT_AVAILABLE";
public static final String ERR_ACCOUNT_MISSING = "ACCOUNT_MISSING";
public static final String ERR_AUTHENTICATION_FAILED = "AUTHENTICATION_FAILED";
public static final String ERR_TOO_MANY_REGISTRATIONS = "TOO_MANY_REGISTRATIONS";
public static final String ERR_INVALID_PARAMETERS = "INVALID_PARAMETERS";
public static final String ERR_INVALID_SENDER = "INVALID_SENDER";
public static final String ERR_PHONE_REGISTRATION_ERROR = "PHONE_REGISTRATION_ERROR";
// wakelock
private static final String WAKELOCK_KEY = "C2DM_LIB";
private static PowerManager.WakeLock mWakeLock;
private final String senderId;
/**
* The C2DMReceiver class must create a no-arg constructor and pass the
* sender id to be used for registration.
*/
public C2DMBaseReceiver(String senderId) {
// senderId is used as base name for threads, etc.
super(senderId);
this.senderId = senderId;
}
/**
* Called when a cloud message has been received.
*/
protected abstract void onMessage(Context context, Intent intent);
/**
* Called on registration error. Override to provide better
* error messages.
*
* This is called in the context of a Service - no dialog or UI.
*/
public abstract void onError(Context context, String errorId);
/**
* Called when a registration token has been received.
*/
public void onRegistered(Context context, String registrationId) throws IOException {
// registrationId will also be saved
}
/**
* Called when the device has been unregistered.
*/
public void onUnregistered(Context context) {
}
#Override
public final void onHandleIntent(Intent intent) {
try {
Context context = getApplicationContext();
if (intent.getAction().equals(REGISTRATION_CALLBACK_INTENT)) {
handleRegistration(context, intent);
} else if (intent.getAction().equals(C2DM_INTENT)) {
onMessage(context, intent);
} else if (intent.getAction().equals(C2DM_RETRY)) {
C2DMessaging.register(context, senderId);
}
} finally {
// Release the power lock, so phone can get back to sleep.
// The lock is reference counted by default, so multiple
// messages are ok.
// If the onMessage() needs to spawn a thread or do something else,
// it should use it's own lock.
mWakeLock.release();
}
}
/**
* Called from the broadcast receiver.
* Will process the received intent, call handleMessage(), registered(), etc.
* in background threads, with a wake lock, while keeping the service
* alive.
*/
static void runIntentInService(Context context, Intent intent) {
if (mWakeLock == null) {
// This is called from BroadcastReceiver, there is no init.
PowerManager pm =
(PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
WAKELOCK_KEY);
}
mWakeLock.acquire();
// Use a naming convention, similar with how permissions and intents are
// used. Alternatives are introspection or an ugly use of statics.
String receiver = context.getPackageName() + ".C2DMReceiver";
intent.setClassName(context, receiver);
context.startService(intent);
}
private void handleRegistration(final Context context, Intent intent) {
final String registrationId = intent.getStringExtra(EXTRA_REGISTRATION_ID);
String error = intent.getStringExtra(EXTRA_ERROR);
String removed = intent.getStringExtra(EXTRA_UNREGISTERED);
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "dmControl: registrationId = " + registrationId +
", error = " + error + ", removed = " + removed);
}
if (removed != null) {
// Remember we are unregistered
C2DMessaging.clearRegistrationId(context);
onUnregistered(context);
return;
} else if (error != null) {
// we are not registered, can try again
C2DMessaging.clearRegistrationId(context);
// Registration failed
Log.e(TAG, "Registration error " + error);
onError(context, error);
if ("SERVICE_NOT_AVAILABLE".equals(error)) {
long backoffTimeMs = C2DMessaging.getBackoff(context);
Log.d(TAG, "Scheduling registration retry, backoff = " + backoffTimeMs);
Intent retryIntent = new Intent(C2DM_RETRY);
PendingIntent retryPIntent = PendingIntent.getBroadcast(context,
0 /*requestCode*/, retryIntent, 0 /*flags*/);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.ELAPSED_REALTIME,
backoffTimeMs, retryPIntent);
// Next retry should wait longer.
backoffTimeMs *= 2;
C2DMessaging.setBackoff(context, backoffTimeMs);
}
} else {
try {
onRegistered(context, registrationId);
C2DMessaging.setRegistrationId(context, registrationId);
} catch (IOException ex) {
Log.e(TAG, "Registration error " + ex.getMessage());
}
}
}
}
Ant this one is my C2DMReceiver:
public class C2DMReceiver extends C2DMBaseReceiver {
public static final String EXTRA_DATETIME = "datetime";
public static final String EXTRA_CAM_ID = "cam_id";
public static final String EXTRA_TYPE = "type";
public static final String GCM_PROJECT_ID = "58312821729";
public static void getC2DMRegistration(Context context){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO){
String id = C2DMessaging.getRegistrationId(context);
if(id.equals(""))
C2DMessaging.register(context, C2DMReceiver.GCM_PROJECT_ID);
else
C2DMReceiver.registerPushDevice(context, id);
Log.d("restored id: " + id);
}
}
public static String getDeviceID(Context context){
String out = null;
try {
TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(TELEPHONY_SERVICE);
out = telephonyManager.getDeviceId();
} catch (Exception e) {
Log.w("Error getting device uid", e);
}
return out;
}
public static void registerPushDevice(Context context, String registrationId){
try {
CameraManager app = null;
if(context instanceof Activity)
{
app = (CameraManager)(((Activity)context).getApplication());
}
else if(context instanceof Service)
{
app = (CameraManager)(((Service)context).getApplication());
}
else if(context instanceof Application)
{
app = (CameraManager)context;
}
if(app != null && app.isLoggedIn())
{
HashMap<String, String> keyValues = new HashMap<String, String>(app.getUserSessionKeys());
keyValues.put("imei", getDeviceID(context));
keyValues.put("registration_id", registrationId);
keyValues.put("application_id", context.getString(R.string.application_id));
keyValues.put("gcm", "true");
new ServerCall(context, Script.MOBILE, Method.ADD_REGISTRATION_ID, keyValues, null)
.execute();
}
} catch (Exception e) {
Log.e("Failed to register C2DM", e);
}
}
public C2DMReceiver() {
super(GCM_PROJECT_ID);
}
#Override
public void onRegistered(Context context, String registrationId) {
Log.i("onRegistered: " + registrationId);
registerPushDevice(context, registrationId);
}
#Override
public void onUnregistered(Context context) {
Log.i("onUnregistered");
}
#Override
public void onError(Context context, String errorId) {
Log.w("onError: " + errorId);
}
#SuppressWarnings("unchecked")
#Override
protected void onMessage(Context context, Intent receiveIntent){
Bundle extras = receiveIntent.getExtras();
CameraManager app = null;
if(context instanceof Activity)
{
app = (CameraManager)(((Activity)context).getApplication());
}
else if(context instanceof Service)
{
app = (CameraManager)(((Service)context).getApplication());
}
else if(context instanceof Application)
{
app = (CameraManager)context;
}
boolean activateNotificationsphone = app.getUserStorage().getBoolean(Constants.PUSH_NOTIFI_ACTIVATE_FROM_PHONE, true);
if(extras != null && activateNotificationsphone)
{
Log.e(""+extras.keySet());
Iterator<String> i = extras.keySet().iterator();
while(i.hasNext())
{
String key = i.next();
if(key.equalsIgnoreCase(Constants.EXTRA_ALARM_MOTION) || key.equalsIgnoreCase(Constants.EXTRA_CAMERA_DOWN) || key.equalsIgnoreCase(Constants.EXTRA_LSU_DOWN))
{
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.ic_launcher, context.getString(R.string.app_name), System.currentTimeMillis());
Intent notificationIntent = new Intent(context, FragmentTabs.class);
String type = key.toUpperCase();
String value = receiveIntent.getStringExtra(key);
String collapse_key = receiveIntent.getStringExtra("collapse_key");
String message = "";
String[] pair = value.split("[:]");
if(pair.length == 2)
{
notificationIntent
.putExtra(EXTRA_TYPE, type)
.putExtra(EXTRA_CAM_ID, pair[0])
.putExtra(EXTRA_DATETIME, pair[1])
.setAction(collapse_key);
Log.e("Type c2dm:"+type);
Log.e("Cam ID c2dm: " + pair[0]);
Log.e("DateTime c2dm: " + pair[1]);
ArrayList<CamerasFeedItem> cameras = null;
XMLObject settings = null;
ArrayList<EventItem> listEvents = null;
User user = null;
try
{
user = (User)Utils.deserializeObject(new File(getFilesDir(), CameraManager.USER_OBJ_FILE));
cameras = (ArrayList<CamerasFeedItem>)Utils.deserializeObject(new File(getFilesDir(), user.getUserId() + "_" + CameraManager.CAMERAS_OBJ_FILE));
settings = (XMLObject)Utils.deserializeObject(new File(getFilesDir(), user.getUserId() + "_" + CameraManager.SETTINGS_OBJ_FILE));
//List of events:
if(user!=null)
{
listEvents = (ArrayList<EventItem>)Utils.deserializeObject(new File(getFilesDir(), user.getUserId() + "_" + CameraManager.LIST_EVENTS_OBJ_FILE));
}
}
catch (Exception e)
{ }
CamerasFeedItem item = null;
if(settings == null || cameras == null || (item = isItemExists(cameras, pair[0])) == null)
{
return;
}
if(type.equals(Constants.EXTRA_ALARM_MOTION))
{
if(settings.getValue("motion", "no").equals("no"))
{
return;
}
GregorianCalendar curTime = new GregorianCalendar();
long offset = curTime.get(Calendar.ZONE_OFFSET) + curTime.get(Calendar.DST_OFFSET);
Calendar c = Calendar.getInstance();
c.setTimeZone(TimeZone.getTimeZone("UTC"));
c.setTimeInMillis(Long.parseLong(pair[1]) + offset);
String when = DateFormat.format("dd-MM-yyyy kk:mm:ss", c).toString();
message = context.getString(R.string.push_motion_on_camera, item.getName(), when);
}
else if(type.equals(Constants.EXTRA_CAMERA_DOWN))
{
if(settings.getValue("cameraDown", "no").equals("no"))
{
return;
}
message = context.getString(R.string.push_camera_is_down, item.getName(), getDownString(pair[1]));
//typeIndex = 1;
}
else if(type.equals(Constants.EXTRA_LSU_DOWN))
{
//typeIndex = 3;
message = "";
}
}
if(!message.equals(""))
{
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notification.defaults |= Notification.DEFAULT_SOUND;
notification.flags |= Notification.FLAG_AUTO_CANCEL;
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notification);
contentView.setTextViewText(R.id.title, context.getString(R.string.app_name));
contentView.setTextViewText(R.id.text, message);
notification.contentView = contentView;
notification.contentIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), notificationIntent, 0);
mNotificationManager.notify(collapse_key, (int)Math.random(), notification);
}
return;
}
}
}
}
private CamerasFeedItem isItemExists(ArrayList<CamerasFeedItem> cameras, String id){
for(CamerasFeedItem item: cameras)
{
if(item.getID().equals(id))
{
return item;
}
if(item.isFolderItem())
{
LSUItem lsu = ((FolderItem)item).getLsuItem();
if(lsu != null && lsu.getID().equals(id))
{
return lsu;
}
CamerasFeedItem result = isItemExists(CamerasFeedItem.parse(item), id);
if(result != null)
{
return result;
}
}
}
return null;
}
private String getDownString(String hours){
StringBuilder out = new StringBuilder();
int total = Integer.parseInt(hours);
int m = total / 720;
total = total % 720;
int w = total / 168;
total = total % 168;
int d = total / 24;
total = total % 24;
if(m > 0)
{
out.append(getResources().getQuantityString(R.plurals.push_month, m, m));
out.append(" ");
}
if(w > 0)
{
out.append(getResources().getQuantityString(R.plurals.push_weeks, w, w));
out.append(" ");
}
if(d > 0)
{
out.append(getResources().getQuantityString(R.plurals.push_days, d, d));
out.append(" ");
}
if(total > 0)
{
out.append(getResources().getQuantityString(R.plurals.push_hours, total, total));
out.append(" ");
}
return out.toString().trim();
}
C2DMBroadcastReceiver.java
public class C2DMBroadcastReceiver extends BroadcastReceiver {
#Override
public final void onReceive(Context context, Intent intent) {
// To keep things in one place.
C2DMBaseReceiver.runIntentInService(context, intent);
setResult(Activity.RESULT_OK, null /* data */, null /* extra */);
}
}
And the last one: C2DMessaging:
public class C2DMessaging {
public static final String EXTRA_SENDER = "sender";
public static final String EXTRA_APPLICATION_PENDING_INTENT = "app";
public static final String REQUEST_UNREGISTRATION_INTENT = "com.google.android.c2dm.intent.UNREGISTER";
public static final String REQUEST_REGISTRATION_INTENT = "com.google.android.c2dm.intent.REGISTER";
public static final String LAST_REGISTRATION_CHANGE = "last_registration_change";
public static final String BACKOFF = "backoff";
public static final String GSF_PACKAGE = "com.google.android.gsf";
// package
static final String PREFERENCE = "com.google.android.c2dm";
private static final long DEFAULT_BACKOFF = 30000;
/**
* Initiate c2d messaging registration for the current application
*/
public static void register(Context context, String senderId) {
try {
Intent registrationIntent = new Intent(REQUEST_REGISTRATION_INTENT);
registrationIntent.setPackage(GSF_PACKAGE);
registrationIntent.putExtra(EXTRA_APPLICATION_PENDING_INTENT, PendingIntent.getBroadcast(context, 0, new Intent(), 0));
registrationIntent.putExtra(EXTRA_SENDER, senderId);
context.startService(registrationIntent);
} catch (Exception e) {
Log.w("Couldn't use C2DM, check OS version", e);
}
}
/**
* Unregister the application. New messages will be blocked by server.
*/
public static void unregister(Context context) {
Intent regIntent = new Intent(REQUEST_UNREGISTRATION_INTENT);
regIntent.setPackage(GSF_PACKAGE);
regIntent.putExtra(EXTRA_APPLICATION_PENDING_INTENT, PendingIntent.getBroadcast(context, 0, new Intent(), 0));
context.startService(regIntent);
}
/**
* Return the current registration id.
*
* If result is empty, the registration has failed.
*
* #return registration id, or empty string if the registration is not complete.
*/
public static String getRegistrationId(Context context) {
final SharedPreferences prefs = context.getSharedPreferences(
PREFERENCE,
Context.MODE_PRIVATE);
String registrationId = prefs.getString("dm_registration", "");
return registrationId;
}
public static long getLastRegistrationChange(Context context) {
final SharedPreferences prefs = context.getSharedPreferences(
PREFERENCE,
Context.MODE_PRIVATE);
return prefs.getLong(LAST_REGISTRATION_CHANGE, 0);
}
static long getBackoff(Context context) {
final SharedPreferences prefs = context.getSharedPreferences(
PREFERENCE,
Context.MODE_PRIVATE);
return prefs.getLong(BACKOFF, DEFAULT_BACKOFF);
}
static void setBackoff(Context context, long backoff) {
final SharedPreferences prefs = context.getSharedPreferences(
PREFERENCE,
Context.MODE_PRIVATE);
Editor editor = prefs.edit();
editor.putLong(BACKOFF, backoff);
editor.commit();
}
// package
static void clearRegistrationId(Context context) {
final SharedPreferences prefs = context.getSharedPreferences(
PREFERENCE,
Context.MODE_PRIVATE);
Editor editor = prefs.edit();
editor.putString("dm_registration", "");
editor.putLong(LAST_REGISTRATION_CHANGE, System.currentTimeMillis());
editor.commit();
}
// package
static void setRegistrationId(Context context, String registrationId) {
final SharedPreferences prefs = context.getSharedPreferences(
PREFERENCE,
Context.MODE_PRIVATE);
Editor editor = prefs.edit();
editor.putString("dm_registration", registrationId);
editor.commit();
}
}
Your problem is in this method :
static void runIntentInService(Context context, Intent intent) {
if (mWakeLock == null) {
// This is called from BroadcastReceiver, there is no init.
PowerManager pm =
(PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
WAKELOCK_KEY);
}
mWakeLock.acquire();
// Use a naming convention, similar with how permissions and intents are
// used. Alternatives are introspection or an ugly use of statics.
String receiver = context.getPackageName() + ".C2DMReceiver";
intent.setClassName(context, receiver);
context.startService(intent);
}
In the following line context.getPackageName() returns the package of your app (com.app_project.android).
String receiver = context.getPackageName() + ".C2DMReceiver";
However, .C2DMReceiver is located in your library project (com.lib_project.android), and that's why this class is not found when you try to use your library project from your app.
The way to fix it is to refer to the C2DMReceiver class explicitly :
String receiver = C2DMReceiver.class.getName ();

Updating ListView while viewing the ListView after receiving message from GCM

I am developing an android app based on GCM. The functionality is working perfectly, but I am running into an issue where when I am using the app and on the list screen, the list does not automatically refresh when the app receives a message from GCM. Notifications work fine, but I do not know how to get the message to appear in the list while I'm viewing it.
Here is my GcmBroadcastReceiver:
public class GcmBroadcastReceiver extends BroadcastReceiver {
static final String TAG = "GCMDemo";
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
private MessageDatabaseHelper MDH;
Context ctx;
#Override
public void onReceive(Context context, Intent intent) {
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
ctx = context;
String messageType = gcm.getMessageType(intent);
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
try {
sendNotification("Send error: " + intent.getExtras().toString());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
try {
sendNotification("Deleted messages on server: " +
intent.getExtras().toString());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
try {
if(intent.getExtras().getString("message") != null){
sendNotification(intent.getExtras().getString("message"));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
setResultCode(Activity.RESULT_OK);
}
// Put the GCM message into a notification and post it.
private void sendNotification(String msg) throws JSONException {
mNotificationManager = (NotificationManager)
ctx.getSystemService(Context.NOTIFICATION_SERVICE);
SharedPreferences prefs1 = ctx.getSharedPreferences("UNIQUE", Context.MODE_PRIVATE);
int unique_id = prefs1.getInt("UNIQUE_ID", 0);
SharedPreferences.Editor editor = prefs1.edit();
unique_id++;
editor.putInt("UNIQUE_ID", unique_id);
editor.commit();
Log.v("TEST", "sharedprefs - " + prefs1.getInt("UNIQUE_ID", 0));
JSONObject JSdata = new JSONObject(msg);
String category = "";
String text = "";
String subject = "";
String from = "";
if(JSdata.getString("Category") != null){
Log.v("TEST", "CATEGORY - " + JSdata.getString("Category"));
category = JSdata.getString("Category");
}
if(JSdata.getString("Subject") != null){
Log.v("TEST", "SUBJECT - " + JSdata.getString("Subject"));
subject = JSdata.getString("Subject");
}
if(JSdata.getString("Message") != null){
Log.v("TEST", "Message - " + JSdata.getString("Message"));
text = JSdata.getString("Message");
}
if(JSdata.getString("From") != null){
Log.v("TEST", "FROM - " + JSdata.getString("From"));
from = JSdata.getString("From");
}
String dateTime = "";
Time now = new Time();
now.setToNow();
dateTime = (now.month + 1) + "/" + now.monthDay + " " + now.hour + ":" + now.minute;
Log.v("date", "date - " + dateTime);
Message message = new Message(1, category, text, subject, from, dateTime);
MDH = new MessageDatabaseHelper(ctx);
MDH.addMessage(message);
// new AsyncTask() {
// #Override
// protected String doInBackground(Object... arg0) {
// Intent mainIntent = new Intent(ctx, MainActivity.class);
// mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// ctx.startActivity(mainIntent);
// Log.v("GCMDEMO", "background");
// return "";
// }
// }.execute(null, null, null);
Intent gcmIntent = new Intent(ctx, MessageActivity.class);
gcmIntent.putExtra("message1", message);
PendingIntent contentIntent = PendingIntent.getActivity(ctx, unique_id,
gcmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(ctx)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Choice Cloud Notification")
.setContentText(JSdata.getString("Subject") + " " + JSdata.getString("Category"))
.setAutoCancel(true);
NotificationCompat.InboxStyle big = new NotificationCompat.InboxStyle(
mBuilder);
big.setSummaryText(JSdata.getString("Subject") + " " + JSdata.getString("Category"));
big.addLine(JSdata.getString("Message"));
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(unique_id, big.build());
//mBuilder.setContentIntent(contentIntent);
//mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
And here is my MainActivity
public class MainActivity extends Activity{
private MessageDatabaseHelper MDH;
private boolean initialLaunch = false;
private StableArrayAdapter adapter;
private ListView listview;
private List<Message> mList;
private Spinner spinner;
public static final String EXTRA_MESSAGE = "message";
public static final String PROPERTY_REG_ID = "registration_id";
private static final String PROPERTY_APP_VERSION = "appVersion";
private static final String SENDER_ID = "469307705305"; //This is the project number under the API
static final String TAG = "GCMDemo";
GoogleCloudMessaging gcm;
AtomicInteger msgId = new AtomicInteger();
SharedPreferences prefs;
Context context;
String regid;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
regid = getRegistrationId(context);
if (regid.length() == 0) {
registerBackground();
}
gcm = GoogleCloudMessaging.getInstance(this);
spinner = (Spinner) findViewById(R.id.category_spinner);
MDH = new MessageDatabaseHelper(this);
//On first launch of app, add some mock messages for testing
if(isInitialLaunch()){
setInitialLaunch(true);
Message m1 = new Message(1, "RateCenter", "rates are low", "Sub1", "From1", "7/31 8:45");
MDH.addMessage(m1);
SharedPreferences prefs1 = getSharedPreferences("UNIQUE", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs1.edit();
editor.putInt("UNIQUE_ID", 0);
editor.commit();
}
//Message m1 = new Message(1, "RateCenter", "rates are low", "Sub1", "From1");
//MDH.addMessage(m1);
//Grab all categories dynamically from database
List<String> cList = new ArrayList<String>();
cList = MDH.getAllCategories();
HashSet hs = new HashSet();
hs.addAll(cList);
cList.clear();
cList.addAll(hs);
//Add those categories to arraylist for use in spinner
List<String> categories = new ArrayList<String>();
//categories.add("Please select a category");
categories.add("All");
for(String s:cList){
categories.add(s);
}
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, categories);
// Specify the layout to use when the list of choices appears
adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter1);
//add onitemselected listener to spinner
spinner.setOnItemSelectedListener(new OnItemSelectedListener(){
public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) {
//Refresh main activity with correct set of messages pertaining to category selected
String test1 = parent.getItemAtPosition(pos).toString();
String test2 = MyApplication.globalCategory;
if(!(test1.equals(test2))){
MyApplication.sPos = pos;
MyApplication.globalCategory = parent.getItemAtPosition(pos).toString();
Intent intent = getIntent();
finish();
startActivity(intent);
}
}
public void onNothingSelected(AdapterView<?> arg0) {
}});
//Creates a listview to be used to store messages
listview = (ListView) findViewById(R.id.list);
listview.setItemsCanFocus(false);
//grab messages from database for use in listview corresponding to category selected
mList = new ArrayList<Message>();
if(MyApplication.globalCategory.equals("All")){
mList = MDH.getAllMessages();
}
else {
mList = MDH.getMessagesWithCategory(MyApplication.globalCategory);
}
//instantiates adapter and adds it to listview
adapter = new StableArrayAdapter(this, mList);
listview.setAdapter(adapter);
listview.setClickable(true);
//adds click listener to list
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view,
int position, long id) {
Log.v("GCMDemo", "Registration id is - " + getRegistrationId(MainActivity.this));
Message clickedMessage = (Message)parent.getItemAtPosition(position);
clickedMessage.setUnread(false);
MDH.updateUnread(clickedMessage);
//starts new messageactivity, passing the message clicked on as an extra to the intent
listview.invalidateViews();
Intent startMessageActivityIntent = new Intent();
startMessageActivityIntent.putExtra("message1", clickedMessage);
startMessageActivityIntent.setClass(MainActivity.this,
MessageActivity.class);
startActivity(startMessageActivityIntent);
finish();
}
});
}
#SuppressWarnings("unchecked")
private void registerBackground() {
new AsyncTask() {
#Override
protected String doInBackground(Object... arg0) {
String msg = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
regid = gcm.register(SENDER_ID);
msg = "Device registered, registration id=" + regid;
// Save the regid - no need to register again.
setRegistrationId(context, regid);
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
}
Log.v("GCMDEMO", "GCMWHAT - " + msg);
return msg;
}
}.execute(null, null, null);
}
private void setRegistrationId(Context context, String regid) {
final SharedPreferences prefs = getGCMPreferences(context);
int appVersion = getAppVersion(context);
Log.v(TAG, "Saving regId on app version " + appVersion);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(PROPERTY_REG_ID, regid);
editor.putInt(PROPERTY_APP_VERSION, appVersion);
editor.commit();
}
private String getRegistrationId(Context context) {
final SharedPreferences prefs = getGCMPreferences(context);
String registrationId = prefs.getString(PROPERTY_REG_ID, "");
if (registrationId.length() == 0) {
Log.v(TAG, "Registration not found.");
return "";
}
// check if app was updated; if so, it must clear registration id to
// avoid a race condition if GCM sends a message
int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
int currentVersion = getAppVersion(context);
if (registeredVersion != currentVersion) {
Log.v(TAG, "App version changed");
return "";
}
return registrationId;
}
private int getAppVersion(Context context2) {
try {
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
return packageInfo.versionCode;
} catch (NameNotFoundException e) {
// should never happen
throw new RuntimeException("Could not get package name: " + e);
}
}
private SharedPreferences getGCMPreferences(Context context2) {
return getSharedPreferences(MainActivity.class.getSimpleName(),
Context.MODE_PRIVATE);
}
private class StableArrayAdapter extends ArrayAdapter<Message> {
//adapter class for use with listview, maps items to positions
//HashMap<Message, Integer> hMap = new HashMap<Message, Integer>();
private final Context context1;
private final List<Message> adaptList;
public StableArrayAdapter(Context cont,
List<Message> objects) {
super(context, R.layout.ccm_list_item, objects);
//for (int i = 0; i < objects.size(); i++) {
// hMap.put(objects.get(i), i);
//}
this.context1 = cont;
this.adaptList = new ArrayList<Message>();
this.adaptList.addAll(objects);
}
private class ViewHolder {
public TextView text;
public TextView text2;
public TextView textTime;
public CheckBox checkBox;
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder holder = null;
Log.v("ConvertView", String.valueOf(position));
if (convertView == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.ccm_list_item, null);
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context1
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
holder.text = (TextView) convertView.findViewById(R.id.rowText);
holder.text2 = (TextView) convertView.findViewById(R.id.rowText2);
holder.textTime = (TextView) convertView.findViewById(R.id.rowTextTime);
holder.checkBox = (CheckBox) convertView
.findViewById(R.id.listCheck);
holder.checkBox.setFocusable(false);
holder.checkBox.setFocusableInTouchMode(false);
convertView.setTag(holder);
holder.checkBox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
Message message = (Message)cb.getTag();
Toast.makeText(getApplicationContext(),
"Clicked on Checkbox: " + cb.getText() +
" is " + cb.isChecked(),
Toast.LENGTH_LONG).show();
//country.setSelected(cb.isChecked());
}
});
}
else {
holder = (ViewHolder) convertView.getTag();
}
int count = 0;
Message m1 = new Message();
if(MyApplication.globalCategory.equals("All")){
mList = MDH.getAllMessages();
for (Message m: mList) {
if(count == position){
m1 = m;
}
count++;
}
}
else {
mList = MDH.getMessagesWithCategory(MyApplication.globalCategory);
for (Message m: mList) {
if(count == position){
m1 = m;
}
count++;
}
}
if (m1.getUnread() == false) {
holder.text.setText(m1.toString());
holder.text2.setText(m1.getText());
holder.textTime.setText(m1.getTime());
convertView.setBackgroundColor(Color.LTGRAY);
} else {
holder.text.setText(m1.toString());
holder.text2.setText(m1.getText());
holder.textTime.setText(m1.getTime());
convertView.setBackgroundColor(Color.WHITE);
holder.text.setTypeface(null, Typeface.BOLD);
holder.text2.setTypeface(null, Typeface.BOLD);
}
holder.checkBox.setFocusable(false);
holder.checkBox.setFocusableInTouchMode(false);
holder.text.setFocusable(false);
holder.text.setFocusableInTouchMode(false);
((ViewGroup) convertView).setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
return convertView;
}
}
public void setInitialLaunch(boolean initialLaunch) {
SharedPreferences settings = getSharedPreferences("APPLAUNCH", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("APPLAUNCHKEY", false);
editor.commit();
this.initialLaunch = initialLaunch;
}
public boolean isInitialLaunch() {
SharedPreferences settings = getSharedPreferences("APPLAUNCH", 0);
this.initialLaunch = settings.getBoolean("APPLAUNCHKEY", true);
return initialLaunch;
}
#Override
protected void onStart() {
//on start, grabs message from database and updates adapter with changes to data
super.onStart();
if(MyApplication.globalCategory.equals("All")){
mList = MDH.getAllMessages();
for (Message m: mList) {
}
}
else {
mList = MDH.getMessagesWithCategory(MyApplication.globalCategory);
for (Message m: mList) {
}
}
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
adapter.notifyDataSetChanged() ;
}
});
spinner.setSelection(MyApplication.sPos);
}
#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);
super.onCreateOptionsMenu(menu);
return true;
}
//option item about added to menu and starts aboutactivity when selected
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_settings) {
Intent startActivityIntent = new Intent(this,
AboutActivity.class);
startActivity(startActivityIntent);
return true;
}
return true;
}
}

Categories

Resources