Parcelable object being received null via notification but works between activites - java

I have an Intent Service called ParserService which performs some task and creates an object(ArtistInfo) which is parcelable. Then it checks if the app is in foreground. If it is then it sends a broadcast with the parcelable object in the intent extras. This broadcast is received by the activity MainActivity.java which then creates an intent with the same object and launches an activity called ListSongsActivity where the parcelable object is successfully received.
But if the app is not in foreground then the ParserService sends a notification which has the same intent as that of a broadcast. But when the ListSongsActivity is being launched through the notification the parcelable object(ArtistInfo) this time is null. And I am also passing a string in the intent. This string is being received correctly via the notification intent but the parcelable object is null.
Please find the relevant code snippets below.
Broadcast and notification code from the ParserService:
if (CommonUtils.appInForeground(getApplicationContext())) {
Log.d(TAG, "onHandleIntent(): Sending success broadcast.");
sendBroadcast(createSuccessIntent(artistInfo));
} else {
// TODO: 10-10-2018 tapping on notification does nothing!!
Log.d(TAG, "onHandleIntent(): Sending success notification.");
String body = "Parsing complete for the url: " + url;
Intent notifyIntent = new Intent(getApplicationContext(), ListSongsActivity.class);
notifyIntent.putExtra(Constants.MUSIC_SITE, siteName);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
Bundle bundle = new Bundle();
bundle.putParcelable(Constants.PARSED_ARTIST_INFO, artistInfo);
intent.putExtras(bundle);
CommonUtils.sendNotification(getApplicationContext(), Constants.LIST_SONGS_NOTIFICATION_TITLE
, body, Constants.LIST_SONGS_NOTIFICATION_CHANNEL_ID, notifyIntent,
Constants.LIST_SONGS_NOTIFICATION_ID, R.drawable.ic_launcher_background);
}
private Intent createSuccessIntent(ArtistInfo artistInfo) {
Intent intent = new Intent();
intent.setAction(Constants.PARSE_SUCCESS_ACTION_KEY);
Bundle bundle = new Bundle();
bundle.putParcelable(Constants.PARSE_SUCCESS_MESSAGE_KEY, artistInfo);
intent.putExtras(bundle);
return intent;
}
Broadcast Received in a fragment of the MainActivity:
private class ParserBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "ParserBroadcastReceiver, onReceive()");
String parseResult = intent.getAction();
if (parseResult == null || parseResult.equals(Constants.EMPTY_STRING)) {
return;
}
switch (parseResult) {
case Constants.PARSE_SUCCESS_ACTION_KEY:
ArtistInfo artistInfo = intent.getParcelableExtra(Constants.PARSE_SUCCESS_MESSAGE_KEY);
Log.d(TAG, "ParserBroadcastReceiver, onReceive() PARSE_SUCCESS_ACTION_KEY, artistInfo: "
+ artistInfo.toString());
Log.d(TAG, "site: " + musicSite);
createIntentAndDelegateActivity(artistInfo);
break;
default:
break;
}
}
}
private void createIntentAndDelegateActivity(ArtistInfo artistInfo) {
Log.d(TAG, "createIntentAndDelegateActivity()");
Intent intent = new Intent(getContext(), ListSongsActivity.class);
intent.putExtra(Constants.MUSIC_SITE, musicSite);
Bundle bundle = new Bundle();
bundle.putParcelable(Constants.PARSED_ARTIST_INFO, artistInfo);
intent.putExtras(bundle);
startActivity(intent);
}
sendNotification in CommonUtils:
public static void sendNotification(Context context, String title, String body,
String channelId, Intent intent, Integer id, Integer iconResourceId) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager == null) {
Log.d(TAG, "sendNotification(): noti manager null!!");
return;
}
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
Constants.DEFAULT_NOTIFICATION_CHANNEL_NAME,
NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription(Constants.DEFAULT_NOTIFICATION_CHANNEL_DESCRIPTION);
notificationManager.createNotificationChannel(channel);
}
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntentWithParentStack(intent);
PendingIntent pendingIntent1 = stackBuilder.getPendingIntent(Constants.PENDING_INTENT_DEFAULT_REQ_CODE,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId);
builder.setContentTitle(title);
builder.setContentText(body);
builder.setSmallIcon(iconResourceId);
builder.setContentIntent(pendingIntent1);
Notification notification = builder.build();
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
NotificationManagerCompat.from(context).notify(id, notification);
}
This is how I getIntentExtras in the ListSongsActivity:
private void getIntentExtras() {
Log.d(TAG, "getIntentExtras()");
Intent intent = getIntent();
parsedArtistInfo = intent.getParcelableExtra(Constants.PARSED_ARTIST_INFO);
String siteName = intent.getStringExtra(Constants.MUSIC_SITE);
Log.d(TAG, "getIntentExtras() sitename: " + siteName);
musicSite = Enum.valueOf(MusicSite.class, siteName);
Log.d(TAG, "getIntentExtras() artInfo: " + parsedArtistInfo.toString());
}
When the ListSongsAtivity is started by the broadcast receiver, the parsedArtistInfo object is the correct object passed by the ParserService, but when ListSongsActivity is opened by notification the parsedArtistInfo object is null.
ArtistInfo class:
public class ArtistInfo implements Parcelable {
private static final String TAG = ArtistInfo.class.getSimpleName();
private String url;
private String artist;
// album name to list of ids of songs
private HashMap<String, List<Integer>> albumInfo;
// song id to songInfo
private SparseArray<SongInfo> songsMap;
/**
* to be used only for ui display logic, don't use for downloading logic
*/
private HashMap<String, Boolean> albumCheckedStatus;
public ArtistInfo() {
}
private ArtistInfo(Parcel in) {
url = in.readString();
artist = in.readString();
// Read album info
getAlbumInfo();
int albumInfoSize = in.readInt();
for (int i = 0; i < albumInfoSize; i++) {
String key = in.readString();
List<Integer> value = new ArrayList<>();
in.readList(value, null);
albumInfo.put(key, value);
}
// Read songs map
getSongsMap();
int songsMapSize = in.readInt();
for (int i = 0; i < songsMapSize; i++) {
int key = in.readInt();
SongInfo value = in.readParcelable(SongInfo.class.getClassLoader());
songsMap.put(key, value);
}
getAlbumCheckedStatus();
int albumCheckStatusSize = in.readInt();
for (int i = 0; i < albumCheckStatusSize; i++) {
String key = in.readString();
Boolean value = in.readByte() != 0;
albumCheckedStatus.put(key, value);
}
}
public static final Creator<ArtistInfo> CREATOR = new Creator<ArtistInfo>() {
#Override
public ArtistInfo createFromParcel(Parcel in) {
return new ArtistInfo(in);
}
#Override
public ArtistInfo[] newArray(int size) {
return new ArtistInfo[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(url);
dest.writeString(artist);
// Write album info
getAlbumInfo();
dest.writeInt(albumInfo.size());
for (Map.Entry<String, List<Integer>> item : albumInfo.entrySet()) {
dest.writeString(item.getKey());
dest.writeList(item.getValue());
}
// Write song map
getSongsMap();
dest.writeInt(songsMap.size());
for (int i = 0; i < songsMap.size(); i++) {
int key = songsMap.keyAt(i);
dest.writeInt(key);
dest.writeParcelable(songsMap.get(key), flags);
}
getAlbumCheckedStatus();
dest.writeInt(albumCheckedStatus.size());
for (Map.Entry<String, Boolean> item : albumCheckedStatus.entrySet()) {
dest.writeString(item.getKey());
dest.writeByte((byte) (item.getValue() ? 1 : 0));
}
}
Can someone please point out the error I am making while sending the object in via notification. Thanks!

Before calling sendNotification() in your else condition, you are putting bundle to a different intent, not to notifyIntent. Change your code inside the else like below
else {
// TODO: 10-10-2018 tapping on notification does nothing!!
Log.d(TAG, "onHandleIntent(): Sending success notification.");
String body = "Parsing complete for the url: " + url;
Intent notifyIntent = new Intent(getApplicationContext(), ListSongsActivity.class);
notifyIntent.putExtra(Constants.MUSIC_SITE, siteName);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
Bundle bundle = new Bundle();
bundle.putParcelable(Constants.PARSED_ARTIST_INFO, artistInfo);
notifyIntent.putExtras(bundle);
CommonUtils.sendNotification(getApplicationContext(), Constants.LIST_SONGS_NOTIFICATION_TITLE
, body, Constants.LIST_SONGS_NOTIFICATION_CHANNEL_ID, notifyIntent,
Constants.LIST_SONGS_NOTIFICATION_ID, R.drawable.ic_launcher_background);
}

Maybe you are creating pending intents more than ones in your app. In this case, you should use,
PendingIntent.FLAG_CANCEL_CURRENT
to create the Intent from scratch and inflate your bundle

Related

Why is my foreground service killed by Android System?

My app is a tracking app where I want to track user location in a service and then display every location in a fragment.
I have a problem with background service: my service is stopped after some minutes (sometimes < 10 minutes, sometimes > 30 minutes).
I start my location service in this fragment and everything goes fine when I use my app.
The problem is when I close (not kill) my app and start something else on my phone (or just block it), after a few minutes my service is stopped and I don't know why.
I show a foreground notification when my service is running but android system still stops it, I notice this because my notification disappear and my app restarts.
Here is my code for the service:
public class LocationService extends Service {
private static final String TAG = "LocationService";
public static final String NEW_VALUE_INTENT_ACTION = "service_new_value";
public static final String INTENT_LATITUDE = "latitude";
public static final String INTENT_LONGITUDE = "longitude";
public static final String INTENT_SPEED = "speed";
public static final String INTENT_ACCURACY = "accuracy";
private static final long TWO_MINUTES = 1000 * 60 * 2;
private static final long INTERVAL = 5000;
private static final long FASTEST_INTERVAL = 2000;
private int ONGOING_NOTIFICATION = 1111;
private Location currentLocation;
NotificationCompat.Builder builder = null;
private LocationRequest mLocationRequest;
/**
* Provides access to the Fused Location Provider API.
*/
private FusedLocationProviderClient mFusedLocationClient;
/**
* Callback for changes in location.
*/
private LocationCallback mLocationCallback;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Log.d(LocationService.TAG, "LocationService ---> onCreate()");
super.onCreate();
}
#Override
public void onDestroy() {
Log.d(LocationService.TAG, "LocationService ---> onDestroy()");
super.onDestroy();
stopForeground(true);
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(LocationService.TAG, "LocationService ---> onStartCommand()");
startServiceTask();
return super.onStartCommand(intent, flags, startId);
}
#Override
public boolean onUnbind(Intent intent) {
Log.d(LocationService.TAG, "LocationService ---> onUnbind()");
return super.onUnbind(intent);
}
private void startServiceTask() {
Log.d(LocationService.TAG, "GpsService ---> Starting ...");
setServiceAsForeground();
initFusedLocationProvider();
Log.d(LocationService.TAG, "MyStartedService ---> Starting ...");
}
private void initFusedLocationProvider() {
mFusedLocationClient = new FusedLocationProviderClient(this);
mLocationRequest = new LocationRequest();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
if (currentLocation == null)
currentLocation = locationResult.getLastLocation();
else if (isBetterLocation(locationResult.getLastLocation(), currentLocation)) {
Log.d(TAG, "onLocationChanged(): Updating Location ... " + currentLocation.getProvider());
currentLocation = locationResult.getLastLocation();
}
notifyValueUpdate();
} }, getMainLooper());
}
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null) {
// A new location is always better than no location
return true;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use
// the new location
// because the user has likely moved
if (isSignificantlyNewer) {
return true;
// If the new location is more than two minutes older, it must be
// worse
} else if (isSignificantlyOlder) {
return false;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation
.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and
// accuracy
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate
&& isFromSameProvider) {
return true;
}
return false;
}
/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
private void setServiceAsForeground() {
Log.d(LocationService.TAG, "GpsService ---> setServiceAsForeground()");
// Prepare the intent triggered if the notification is selected
Intent intent = new Intent(this, LocationService.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
builder = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel notificationChannel = new NotificationChannel("ID", "Name", importance);
notificationManager.createNotificationChannel(notificationChannel);
builder = new NotificationCompat.Builder(getApplicationContext(), notificationChannel.getId());
} else {
builder = new NotificationCompat.Builder(getApplicationContext());
}
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
v.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
//deprecated in API 26
v.vibrate(500);
}
// Build the notification
// Use NotificationCompat.Builder instead of just Notification.Builder to support older Android versions
Notification notification = builder.setContentTitle("MyMovements")
.setContentText("Running ...")
.setSmallIcon(getNotificationIcon())
.setBadgeIconType(getNotificationIcon())
.setContentIntent(pIntent)
.setAutoCancel(true).build();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
startForeground(ONGOING_NOTIFICATION, notification, FOREGROUND_SERVICE_TYPE_LOCATION);
}
else {
startForeground(ONGOING_NOTIFICATION,notification);
}
}
private int getNotificationIcon(){
SharedPreferences settings = this.getSharedPreferences(MainActivity.PREFERENCE,0);
String icon = settings.getString(MapFragment.NOTIFICATION_PREF, " ");
switch (icon) {
case "Walking":
return R.drawable.walk;
case "Public Transportation":
return R.drawable.bus;
case "Driving":
return R.drawable.car;
default:
return 0;
}
}
private void updateNotification(){
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String conc = "Running...\n" + "Lat: " + currentLocation.getLatitude() + " " + "Lng: " + currentLocation.getLongitude();
Notification notification = builder.setStyle(new NotificationCompat.BigTextStyle()
.bigText(conc))
.setContentText(conc).build();
notificationManager.notify(ONGOING_NOTIFICATION, notification);
}
private void notifyValueUpdate(){
Log.d(TAG, "MyStartedService ---> notifyValueUpdate()");
if(currentLocation != null) {
updateNotification();
Log.d(LocationService.TAG, currentLocation.getProvider());
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(NEW_VALUE_INTENT_ACTION);
Bundle bundle = new Bundle();
bundle.putDouble(INTENT_LATITUDE, currentLocation.getLatitude());
bundle.putDouble(INTENT_LONGITUDE, currentLocation.getLongitude());
bundle.putDouble(INTENT_SPEED, currentLocation.getSpeed()*3.6);
bundle.putDouble(INTENT_ACCURACY, currentLocation.getAccuracy());
broadcastIntent.putExtras(bundle);
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
}
}
}
I started my service in OnServiceCommand() -> startServiceTask() -> setServiceAsForeground()
I will really appreciate any tips for my code (this is a scholar project and this is my first app, so probably I am doing something wrong).
Thanks to everyone

Display notifications over activity when app is starting

At this moment i use push notifications in my app. when i start my app they go into the notification drawer like this
1
but i need them to be over the main activity. i cant find the solution anywhere... Which type of notifications can i use ?(without losing the functionality) and how to dublicate the info from push notifications into that type? also is there a way to display push notifications on the whole screen ? fullscreen ? thats what i want: 2
Can someone give me a solution and its code as an example?
my code:
private static int sNotificationId = 1;
public static int showsId = -1;
...
Utils.GetAuthToken(this);
Bundle intent_extras = getIntent().getExtras();
showsId = -1;
if (intent_extras != null && intent_extras.containsKey("com.example.romanchuk.appisode.show_id")) {
if (intent_extras.containsKey("com.example.romanchuk.appisode.notifyId")) {
int notification_id = intent_extras.getInt("com.example.romanchuk.appisode.notifyId", -1);
new ReadNotification(notification_id).execute();
}
showsId = intent_extras.getInt("com.example.romanchuk.appisode.show_id", -1);
} else {
try {
ArrayList<NotificationItem> list = new LoadNotifications().execute().get();
for (int jIndex = 0; jIndex < list.size(); jIndex++) {
new sendNotification(this, list.get(jIndex).getId(),
list.get(jIndex).getShow_id(),
list.get(jIndex).getMessage(),
"Appisode",
list.get(jIndex).getImage()).execute();
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
...
private void handleDataMessage(int id, String title, String message) {
try {
String imageUrl = "";
Log.e(TAG, "title: " + title);
Log.e(TAG, "message: " + message);
Log.e(TAG, "imageUrl: " + imageUrl);
if (!true) {
// app is in foreground, broadcast the push message
Intent pushNotification = new Intent(Config.PUSH_NOTIFICATION);
pushNotification.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
// play notification sound
NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
notificationUtils.playNotificationSound();
} else {
// app is in background, show the notification in notification tray
Intent resultIntent = new Intent(this, MainActivity.class);
resultIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
resultIntent.putExtra("com.example.romanchuk.appisode.notifyId", id);
resultIntent.putExtra("message", message);
NotificationUtils notificationUtils = new NotificationUtils(this);
// resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
notificationUtils.showNotificationMessage(title, message, resultIntent);
}
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
private class sendNotification extends AsyncTask<String, Void, Bitmap> {
Context ctx;
int id, show_id;
String message;
String title;
String icon;
public sendNotification(Context context, int id, int show_id, String message, String title, String icon) {
super();
this.ctx = context;
this.id = id;
this.show_id = show_id;
this.message = message;
this.title = title;
this.icon = icon;
}
...
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
Intent intent = new Intent(ctx, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("com.example.romanchuk.appisode.notifyId", id);
intent.putExtra("com.example.romanchuk.appisode.show_id", show_id);
PendingIntent pendingIntent = PendingIntent.getActivity(ctx, sNotificationId , intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
inboxStyle.addLine(message);
NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle();
bigText.bigText(message);
bigText.setBigContentTitle(getString(R.string.app_name));
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx);
Notification notification = null;
notification = builder.setSmallIcon(R.mipmap.ic_launcher).setTicker(title).setWhen(0)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setColor(getResources().getColor(R.color.color_accent))
.setContentTitle("Appisode")
.setContentIntent(pendingIntent)
.setFullScreenIntent(pendingIntent, true)
.setContentText(message)
.setDefaults(Notification.DEFAULT_ALL)
.setAutoCancel(true)
.setStyle(inboxStyle)
.setSmallIcon(R.drawable.small_icon)
.setWhen(System.currentTimeMillis())
.setSound(defaultSoundUri).build();
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(sNotificationId++, notification);
}
}

I need to update list adapter in background auto refresh listview and notify user if there new data from database

Hello I am creating a social network in android, I have fetching data from mysql data and put it in listview Adapter but I need auto refresh for listview and notification if there is new insert data, I am using Broadcast receiver and service but it there is nothing happen please help me
here is my code
Broadcast receiver
public class BraodcastReceiverNotif extends BroadcastReceiver {
static int noOfTimes = 0;
JSONObject data;
Exception exception;
SharedPreferences sharedpreferences;;
public static final String mypreference = "pkAppPrefs";
int pageNumber = 0;
public static final int REQUEST_CODE = 12345;
Intent intnt;
Context context;
#Override
public void onReceive(final Context context, Intent intent) {
sharedpreferences = context.getSharedPreferences(mypreference, Context.MODE_PRIVATE);
noOfTimes++;
//Toast.makeText(context, "BC Service Running for " + noOfTimes + " times", Toast.LENGTH_SHORT).show();
// TODO Auto-generated method stub
noOfTimes++;
try {
startNetworkCalls ();
} catch (JSONException e) {
e.printStackTrace();
}
}
private void startNetworkCalls () throws JSONException {
data = new JSONObject();
data.put("user_key", sharedpreferences.getString("userKey", ""));
data.put("city_id", sharedpreferences.getString("user_city_id", ""));
data.put("sector_id", sharedpreferences.getString("sector_id", ""));
data.put("page", pageNumber);
String URL = ".............................................";
getOnlinePosts onlinePosts = new getOnlinePosts();
onlinePosts.execute(URL);
}
private class getOnlinePosts extends AsyncTask<String, Void, String[]> {
private final String LOG_TAG =getOnlinePosts.class.getSimpleName();
private Exception exception = null;
#Override
protected void onPreExecute() {
}
#Override
protected String[] doInBackground(String... params) {
URL url;
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String docsJson = null;
String JsonDATA = data.toString();
String JsonResponse = null;
Context context = null;
try {
Log.e(LOG_TAG, "Started Connecting to " + params[0] + " Sending " +JsonDATA);
url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "application/json");
Writer writer = new BufferedWriter(new OutputStreamWriter(urlConnection.getOutputStream(), "UTF-8"));
writer.write(JsonDATA);
writer.close();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String inputLine;
while ((inputLine = reader.readLine()) != null)
buffer.append(inputLine + "\n");
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
docsJson = buffer.toString();
Log.v(LOG_TAG, "My data is: " + docsJson);
} catch (Exception e) {
exception = e;
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
try {
return getDocumentDataFromJson(docsJson);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
// this will only happen if there is an error
return null;
}
#Override
protected void onPostExecute(String[] result) {
}
}
private String[] getDocumentDataFromJson(String documentJsonStrArr)
throws JSONException {
final String data_status = "status";
final String data_data = "data";
final String data_name = "fullname";
final String data_username = "community";
JSONObject documentJson = new JSONObject(documentJsonStrArr);
String status = documentJson.getString(data_status);
if (status.equals("success")) {
JSONArray docs = documentJson.getJSONArray(data_data);
if (docs.length() > 0) {
for (int i = 0; i < docs.length(); i++) {
JSONObject singleDoc = docs.getJSONObject(i);
// String success = singleDoc.getString(documentJson.getString(data_status));
String name = singleDoc.getString(data_name);
String username = singleDoc.getString(data_username);
intnt = new Intent(context, MyService.class);
// Set unsynced count in intent data
intnt.putExtra("success", "success");
intnt.putExtra("name", name);
// Call MyService
context.startService(intnt);
}
}
}
return null;
}
}
here is my service
public class MyService extends Service {
int numMessages = 0;
ArrayList<SinglePost> PostEntries = null;
public ArrayAdapter<SinglePost> mycardAdapter;
SharedPreferences sharedpreferences;;
public static final String mypreference = "pkAppPrefs";
public MyService() {
}
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
Toast.makeText(this, "Service was Created", Toast.LENGTH_LONG).show();
sharedpreferences = getSharedPreferences(mypreference, Context.MODE_PRIVATE);
}
#Override
public void onStart(Intent intent, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
Intent resultIntent = new Intent(this, Community.class);
Toast.makeText(this, intent.getStringExtra("name"), Toast.LENGTH_LONG).show();
PostEntries.add(new SinglePost(intent.getStringExtra("post_key"),
intent.getStringExtra("name"),
intent.getStringExtra("username"), intent.getStringExtra("profile_image"),intent.getStringExtra("poster_key") ,
intent.getStringExtra("postdate"),intent.getStringExtra("message") ,intent.getStringExtra("likes") ,
intent.getStringExtra("liked"),intent.getStringExtra("comments") ,intent.getStringExtra("commented") ,
Boolean.parseBoolean(intent.getStringExtra("moderate")),intent.getStringExtra("sector") ,
intent.getStringExtra("district"),intent.getStringExtra("province") ,
intent.getStringExtra("city"),intent.getStringExtra("country") ,intent.getStringExtra("media") ,
Integer.parseInt(intent.getStringExtra("media_count") ),
Integer.parseInt(intent.getStringExtra("moderate_level")) ,
Boolean.parseBoolean( intent.getStringExtra("own_post")) ,intent.getStringExtra("online")));
//if (Integer.parseInt(intent.getStringExtra("count_data")) < Integer.parseInt(sharedpreferences.getString("count_data", ""))){
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0,
resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mNotifyBuilder;
NotificationManager mNotificationManager;
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Sets an ID for the notification, so it can be updated
int notifyID = 9001;
mNotifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("Alert")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_launcher);
// Set pending intent
mNotifyBuilder.setContentIntent(resultPendingIntent);
// Set Vibrate, Sound and Light
int defaults = 0;
defaults = defaults | android.app.Notification.DEFAULT_LIGHTS;
defaults = defaults | android.app.Notification.DEFAULT_VIBRATE;
defaults = defaults | android.app.Notification.DEFAULT_SOUND;
mNotifyBuilder.setDefaults(defaults);
// Set the content for Notification
mNotifyBuilder.setContentText(intent.getStringExtra("success"));
// Set autocancel
mNotifyBuilder.setAutoCancel(true);
// Post a notification
mNotificationManager.notify(notifyID, mNotifyBuilder.build());
// }
}
#Override
public void onDestroy() {
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
MainActivity class i am passing scheduleAlarm method to check every 10 second in database and refresh my listview
Setup a recurring alarm every 10 seconds
public void scheduleAlarm() {
BroadCase Receiver Intent Object
Intent alarmIntent = new Intent(getContext().getApplicationContext(), BraodcastReceiverNotif.class);
// Pending Intent Object
PendingIntent pendingIntent = PendingIntent.getBroadcast(getContext().getApplicationContext(), 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Alarm Manager Object
AlarmManager alarmManager = (AlarmManager) getContext().getApplicationContext().getSystemService(Context.ALARM_SERVICE);
// Alarm Manager calls BroadCast for every Ten seconds (10 * 1000), BroadCase further calls service to check if new records are inserted in
// Remote MySQL DB
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis() + 5000, 10 * 1000, pendingIntent);
}
fixed format
I really dont understand your question but I got some sense.
If I understand correctly, you want to fetch data from server, store in SQLite database and display the data in Listview
To achieve this functionality,
Create the Http class that gets data from the server.
Create IntentService to make HTTP request.
Once receive data from the server, insert into SQLite. And Broadcast
how you can broadcast is,
you register broadcast receiver in your activity that has the listview.
The broadcast only pass the message as the 'boolean' value that determines did data fetch from the server? If successfully fetched from the server then pass boolean true and after broadcast receive , make a local db call and fetch all changes. After that you can update the listview

Android upload file to AWS S3 error Status Code: 400

I am uploading a file to Amazon S3 server into my BUCKET i am getting error, i am using the code from github https://github.com/jgilfelt/android-simpl3r i will post my code: i have found some information here about my error but i don not know to solve this error https://github.com/jgilfelt/android-simpl3r/issues/4
Status Code: 400, AWS Service: Amazon S3, AWS Request ID: D49EFFBB39B49EEA, AWS Error Code: MalformedXML, AWS Error Message: The XML you provided was not well-formed or did not validate against our published schema, S3 Extended Request ID: fpAsdF+sxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
select.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// start file chooser
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent,"Select a file to upload"),FILE_SELECT_CODE);
}
});
public class UploadService extends IntentService {
public static final String ARG_FILE_PATH = "file_path";
public static final String UPLOAD_STATE_CHANGED_ACTION = "com.readystatesoftware.simpl3r.example.UPLOAD_STATE_CHANGED_ACTION";
public static final String UPLOAD_CANCELLED_ACTION = "com.readystatesoftware.simpl3r.example.UPLOAD_CANCELLED_ACTION";
public static final String S3KEY_EXTRA = "s3key";
public static final String PERCENT_EXTRA = "percent";
public static final String MSG_EXTRA = "msg";
private static final int NOTIFY_ID_UPLOAD = 1337;
private AmazonS3Client s3Client;
private Uploader uploader;
private NotificationManager nm;
public UploadService() {
super("simpl3r-example-upload");
}
#Override
public void onCreate() {
super.onCreate();
s3Client = new AmazonS3Client(
new BasicAWSCredentials(getString(R.string.s3_access_key), getString(R.string.s3_secret)));
nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
IntentFilter f = new IntentFilter();
f.addAction(UPLOAD_CANCELLED_ACTION);
registerReceiver(uploadCancelReceiver, f);
}
#Override
protected void onHandleIntent(Intent intent) {
String filePath = intent.getStringExtra(ARG_FILE_PATH);
File fileToUpload = new File(filePath);
Log.v("filePath", ""+filePath);
final String s3ObjectKey = md5(filePath);
Log.v("s3ObjectKey", ""+s3ObjectKey);
String s3BucketName = getString(R.string.s3_bucket);
final String msg = "Uploading " + s3ObjectKey + "...";
// create a new uploader for this file
uploader = new Uploader(this, s3Client, s3BucketName, s3ObjectKey, fileToUpload);
// listen for progress updates and broadcast/notify them appropriately
uploader.setProgressListener(new UploadProgressListener() {
#Override
public void progressChanged(ProgressEvent progressEvent,
long bytesUploaded, int percentUploaded) {
Notification notification = buildNotification(msg, percentUploaded);
nm.notify(NOTIFY_ID_UPLOAD, notification);
broadcastState(s3ObjectKey, percentUploaded, msg);
}
});
// broadcast/notify that our upload is starting
Notification notification = buildNotification(msg, 0);
nm.notify(NOTIFY_ID_UPLOAD, notification);
broadcastState(s3ObjectKey, 0, msg);
try {
String s3Location = uploader.start(); // initiate the upload
broadcastState(s3ObjectKey, -1, "File successfully uploaded to " + s3Location);
} catch (UploadIterruptedException uie) {
broadcastState(s3ObjectKey, -1, "User interrupted");
} catch (Exception e) {
e.printStackTrace();
broadcastState(s3ObjectKey, -1, "Error: " + e.getMessage());
}
}
#Override
public void onDestroy() {
nm.cancel(NOTIFY_ID_UPLOAD);
unregisterReceiver(uploadCancelReceiver);
super.onDestroy();
}
private void broadcastState(String s3key, int percent, String msg) {
Intent intent = new Intent(UPLOAD_STATE_CHANGED_ACTION);
Bundle b = new Bundle();
b.putString(S3KEY_EXTRA, s3key);
b.putInt(PERCENT_EXTRA, percent);
b.putString(MSG_EXTRA, msg);
intent.putExtras(b);
sendBroadcast(intent);
}
private Notification buildNotification(String msg, int progress) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setWhen(System.currentTimeMillis());
builder.setTicker(msg);
builder.setContentTitle(getString(R.string.app_name));
builder.setContentText(msg);
builder.setSmallIcon(R.drawable.ic_stat_uploading);
builder.setOngoing(true);
builder.setProgress(100, progress, false);
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
builder.setContentIntent(contentIntent);
return builder.build();
}
private BroadcastReceiver uploadCancelReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (uploader != null) {
uploader.interrupt();
}
}
};
private String md5(String s) {
try {
// create MD5 Hash
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
digest.update(s.getBytes());
byte messageDigest[] = digest.digest();
// create Hex String
StringBuffer hexString = new StringBuffer();
for (int i=0; i<messageDigest.length; i++)
hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
}

Return String from AsyncTask in BroadcastReceiver

I have been trying all day, but I can't seem to figure it out. I am trying to return a string from AsyncTask in BroadcastReceiver but I am not sure how to do it correctly (new at Java). I have an app that accesses the internet and reads a text file and this text file is a long string. I delimit the string into an array and use it contents that way. In the BroadcastReceiver I want to broadcast (update) the temperature from the weather station every 10-60 minutes depending on what the user sets-up on the notification bar.
Should I use a Thread instead of AsyncTask?
The error I get is with the following line:
String output = new GetWeatherValues().execute(weburi);
I also tried the following code that is commented out:
// GetWeatherValues clientraw = new GetWeatherValues();
// clientraw.doInBackground(weburi);
Below is my Class, please help, I have searched a lot and still no result.
public class UpdateFrequency extends BroadcastReceiver {
// Notification Text Elements
private final CharSequence tickerText = "Weather Updated";
private CharSequence contentTitle = "Weather at ";
private final CharSequence contentText = "Current Temperature is ";
final String http = "http://";
final String clientraw = "/clientraw.txt";
String weburi, webUrl;
// Notification Action Elements
private Intent notificationIntent;
private PendingIntent mContentIntent;
// Notification ID to allow for future updates
private static final int MY_NOTIFICATION_ID = 1;
final String PREFS_NAME = "SettingsFile";
SharedPreferences settings;
public String[] parts;
public static final String WebAddress = "webAddressKey";
#SuppressLint("NewApi")
#Override
public void onReceive(Context context, Intent intent) {
Log.e("log_etag", "Entered Update Frequency");
settings = context.getSharedPreferences(PREFS_NAME,
Context.MODE_PRIVATE);
if (settings.contains(WebAddress)) {
webUrl = settings.getString(WebAddress, "");
weburi = http + webUrl + clientraw;
Log.e("log_etag", "WEB URL Frequency " + weburi);
}
// GetWeatherValues clientraw = new GetWeatherValues();
// clientraw.doInBackground(weburi);
String output = new GetWeatherValues().execute(weburi);
String[] parts = output.split(" ");
ArrayList<String> clientRawData = new ArrayList<String>();
clientRawData.addAll(Arrays.asList(parts));
//Time of last update from weather station.
contentTitle = contentTitle + parts[29] + ":" + parts[30];
Log.e("log_etag", "Content Title " + contentTitle);
// The Intent to be used when the user clicks on the Notification View
notificationIntent = new Intent(context, MainActivity.class);
// The PendingIntent that wraps the underlying Intent
mContentIntent = PendingIntent.getActivity(context, 0,
notificationIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
// Build the Notification
Notification.Builder notificationBuilder = new Notification.Builder(
context).setTicker(tickerText)
.setSmallIcon(android.R.drawable.stat_sys_warning)
.setAutoCancel(true).setContentTitle(contentTitle)
.setContentText(contentText).setContentIntent(mContentIntent);
// Get the NotificationManager
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
// Pass the Notification to the NotificationManager:
mNotificationManager.notify(MY_NOTIFICATION_ID,
notificationBuilder.build());
}
private class GetWeatherValues extends AsyncTask<Void, Integer, String> {
#Override
protected String doInBackground(Void... params) {
try {
HttpClient httpclient = new DefaultHttpClient();
// get url data
HttpPost httppost = new HttpPost(weburi);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream webs = entity.getContent();
// convert response to string
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(webs, "iso-8859-1"),
8);
// read one line of code, file is one whole string.
try {
String returnData = reader.readLine();
webs.close();
return returnData;
} catch (Exception e) {
Log.e("log_tag",
"Error in displaying textview "
+ e.toString());
e.printStackTrace();
}
} catch (Exception e) {
Log.e("log_tag",
"Error converting string " + e.toString());
}
} catch (Exception e) {
Log.e("log_tag",
"Error in http connection " + e.toString());
}
return null;
}
}
}
what you can do is to override onPostExecute() in Async Task have a look at this link for How to use AsyncTask correctly in Android
onPostExecute() allow to handle your things on UI Thread.
and here you can access your String (String returnData)
and you can also return value from async-task for that have look at this link How to handle return value from AsyncTask
but i will prefer for you not to that cos i will be a little bit complicated
a piece of code
private class ABC extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//here your code
return returnData;
}
#Override
protected void onPostExecute(String returnedData) {
//
String[] parts = returnedData.split(" ");
ArrayList<String> clientRawData = new ArrayList<String>();
clientRawData.addAll(Arrays.asList(parts));
//Time of last update from weather station.
contentTitle = contentTitle + parts[29] + ":" + parts[30];
Log.e("log_etag", "Content Title " + contentTitle);
// The Intent to be used when the user clicks on the Notification View
notificationIntent = new Intent(context, MainActivity.class);
// The PendingIntent that wraps the underlying Intent
mContentIntent = PendingIntent.getActivity(context, 0,
notificationIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
// Build the Notification
Notification.Builder notificationBuilder = new Notification.Builder(
context).setTicker(tickerText)
.setSmallIcon(android.R.drawable.stat_sys_warning)
.setAutoCancel(true).setContentTitle(contentTitle)
.setContentText(contentText).setContentIntent(mContentIntent);
// Get the NotificationManager
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
// Pass the Notification to the NotificationManager:
mNotificationManager.notify(MY_NOTIFICATION_ID,
notificationBuilder.build());
}
}
}

Categories

Resources