Android : Call a Fragment Method from a service - android

Have a Firebase Cloud messagin Service running , and i want each time i receive a new message a methode in a specif fragment is called.
public class FirebaseMsgService extends FirebaseMessagingService {
public FirebaseMsgService() {
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
ServiceConnector serviceconnector =null;
JSONObject data;
String json = remoteMessage.getData().toString();
try{
data= new JSONObject(json);
**Fragment.method(data);**
}
catch(Exception e){
}
}
}

You can use LocalBroadcastManager
Service:
private void notifyFragment(String json){
Intent intent = new Intent("nameOfTheAction");
Bundle bundle = new Bundle();
bundle.putString("json", json));
intent.putExtras(bundle);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
Fragment:
LocalBroadcastManager bm;
#Override
public void onAttach(Context context) {
super.onAttach(context);
bm = LocalBroadcastManager.getInstance(this);
IntentFilter actionReceiver = new IntentFilter();
actionReceiver.addAction("nameOfTheAction");
bm.registerReceiver(onJsonReceived , actionReceiver);
}
private BroadcastReceiver onJsonReceived = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
String json = intent.getString("json")
data = new JSONObject(json);
}
}
};
#Override
protected void onDetach() {
super.onDetach();
bm.unregisterReceiver(onJsonReceived);
}

Related

How to send data from Intent Service back to Activity and continue executing?

In MainActivity I created an intent and used putExtra() method to pass data to my Intent Service. In my Intent Service I create HTTP request and get the response, I want to pass the response back to MainActivity.
MainActivity code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] a0 = {"first","second"};
int[] a1 = {1,2,3};
Intent intent = new Intent(MainActivity.this,BackGround.class);
intent.putExtra("a0",a0);
intent.putExtra("a1",a1);
intent.putExtra("numberOfArguments",2);
intent.putExtra("fileName","program.java");
startService(intent);
/* i want to continue the program here after getting
the response and do some stuff*/
}
}
IntentService code:
public class BackGround extends IntentService {
final static String NAME = "BackGround";
public BackGround(String name) {
super(NAME);
}
public BackGround(){
super(NAME);
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
Bundle bundle = intent.getExtras();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://68d1e2eb.ngrok.io")
.addConverterFactory(GsonConverterFactory.create())
.build();
Api api = retrofit.create(Api.class);
ServerJsonObject serverJsonObject = new ServerJsonObject(bundle.getString("fileName"),
new NestedObject(bundle.getStringArray("a0"),bundle.getIntArray("a1")),bundle.getInt("numberOfArguments"));
Call<Result> call = api.sendData(serverJsonObject);
try {
Response<Result> response = call.execute();
// i want to return Result to main activity
} catch (IOException e) {
e.printStackTrace();
}
}
}
How to do this in my case?
put Handler in your activity like
Handler mHandler=new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
return false;
}
});
and pass message to handler from service.
if (mHandler != null) {
Message m = new Message();
m.obj = "completed";
mHandler.sendMessage(m);
}

Send service result to activity

I've got a BroadcastReceiver which checks if Internet connection is available then it starts a service which retrieves an ArrayList from the DB:
public class NetworkWatcher extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
Intent retrieveVehicleList = new Intent(context, RetrieveVehicleListService.class);
if (info != null)
{
if (info.isConnected())
{
context.startService(retrieveVehicleList);
}
else
{
context.stopService(retrieveVehicleList);
}
}
}
}
public class RetrieveVehicleListService extends IntentService
{
private static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
private NotificationCompat.Builder builder;
private ArrayList<Vehicle> vehicles;
private void parseVehiclesFromMap(ArrayList vehicles)
{
for (int i = 0; i < vehicles.size(); i++)
{
final Vehicle v = new Vehicle();
HashMap vehicleMap = (HashMap) vehicles.get(i);
v.setPlate(vehicleMap.get("plate").toString());
v.setKm(vehicleMap.get("km") == null ? null : Integer.parseInt(vehicleMap.get("km").toString()));
v.setFuelQuantity(Double.parseDouble(vehicleMap.get("fuel_quantity").toString()));
v.setEffectiveFuelEconomy(Double.parseDouble(vehicleMap.get("fuel_economy").toString()));
v.setInsuranceDate(vehicleMap.get("insurance_date") == null ? null : new LocalDate(vehicleMap.get("insurance_date").toString()));
v.setMatriculationDate(new LocalDate(vehicleMap.get("matriculation_date").toString()));
v.setLatitude(vehicleMap.get("latitude") == null ? null : Double.parseDouble(vehicleMap.get("latitude").toString()));
v.setLongitude(vehicleMap.get("longitude") == null ? null : Double.parseDouble(vehicleMap.get("longitude").toString()));
v.setFuelType(FuelType.fromInt(Integer.parseInt(vehicleMap.get("id_fuel").toString())));
this.vehicles.add(v);
}
}
private void sendRequest(int userID)
{
Response.Listener<String> listener = new Response.Listener<String>()
{
#Override
public void onResponse(String response)
{
try
{
HashMap json = new ObjectMapper().readValue(response, HashMap.class);
String errorCode = json.get("error_code").toString();
switch (errorCode)
{
case "0":
parseVehiclesFromMap((ArrayList) json.get("vehicles"));
break;
default:
// TODO gestire
break;
}
}
catch (IOException e)
{
// TODO gestire
e.printStackTrace();
}
}
};
VehicleListRequest request = new VehicleListRequest(String.valueOf(userID), listener, null);
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(request);
}
#Override
protected void onHandleIntent(Intent intent)
{
SharedPreferences sp = getSharedPreferences(getString(clyky.cartracker.R.string.sharedPreferencesName), Context.MODE_PRIVATE);
int userID = sp.getInt("id_user", SplashActivity.DEFAULT_USER_ID);
if (userID != SplashActivity.DEFAULT_USER_ID)
{
sendRequest(userID);
}
}
public RetrieveVehicleListService()
{
super("RetrieveVehicleList");
vehicles = new ArrayList<>();
}
}
I want my MainActivity gets that ArrayList from RetrieveVehicleListService when the activity is started. How could I do that?
Thanks in advance.
Use LocalBroadcast reciever to send data from service to activity. Add following code to your activty
private BroadcastReceiver BReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
//put here whaterver you want your activity to do with the intent received
ArrayList<String> arrayList=intent.getStringArrayListExtra("arrayList");
}
};
protected void onResume(){
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(bReceiver, new IntentFilter("message"));
}
protected void onPause (){
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(bReceiver);
}
and use following method to send broadcast from service
private void sendBroadcast (boolean success){
Intent intent = new Intent ("message"); //put the same message as in the filter you used in the activity when registering the receiver
intent.putExtra("success", success);
intent.putStringArrayListExtra("arrayList", arrayList);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
Use Local Broadcast Receiver :
send broadcast using below code
Intent intent = new Intent("YourAction");
Bundle bundle = new Bundle();
bundle .putSerializable("ARRAYLIST",(Serializable)vehicles);
intent.putExtra("BUNDLE",bundle);
intent.putExtras(intent)
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
And receive broadcast in your activity:
private MyBroadcastReceiver myReceiver;
#Override
public void onResume(){
myReceiver = new MyReceiver();
final IntentFilter intentFilter = new IntentFilter("YourAction");
LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, intentFilter);
}
#Override
public void onPause(){
if(myReceiver != null)
LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);
myReceiver = null;
}
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Here you have the received broadcast
// And if you added extras to the intent get them here too
// this needs some null checks
Intent intent = getIntent();
Bundle args = intent.getBundleExtra("BUNDLE");
ArrayList<Object> object = (ArrayList<Object>)args.getSerializable("ARRAYLIST");
}
}

android - Passing message from broadcast to activity

I was reading some post but none have a good answer for me.
So, which is the best way to pass data from broadcast to activity without restart the activity?
Actually I'm using this.
SMSListener:
public class SmsListener extends BroadcastReceiver {
private OnSmsReceivedListener listener = null;
#Override
public void onReceive(Context context, Intent intent) {
try {
if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(intent.getAction())) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
String messageBody = smsMessage.getMessageBody();
String phoneNumber = smsMessage.getDisplayOriginatingAddress();
if (listener != null) {
listener.onSmsReceived(phoneNumber, messageBody);
}
}
}
}
} catch (Exception e)
{
Log.e("Error", "Some some");
}
}
public void setOnSmsReceivedListener(Context context) {
this.listener = (OnSmsReceivedListener) context;
}
}
OnSmsReceivedListener:
public interface OnSmsReceivedListener {
void onSmsReceived(String sender, String message);
}
Activity:
public class MainActivity extends AppCompatActivity implements OnSmsReceivedListener {
private SmsListener receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
/***********/
receiver = new SmsListener();
receiver.setOnSmsReceivedListener(this);
}
#Override
public void onSmsReceived(String sender, String message) {
Log.e("Test", "Sender: "+sender+" - Message: "+message);
}
}
Another of my questions is why I never get log "Test" in my activity. Is like listener is always null, why?
You should add at the end of onCreate()
final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
IntentFilter intentFilter = new IntentFilter(SMS_RECEIVED_ACTION);
registerReceiver(receiver, intentFilter);
and in the onPause()
unregisterReceiver(receiver);
add also the following permission on AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_SMS"/>

How can I call a Method of an activity from background service?

I want to update my ChatMessageAdapter by received new data from background service so that I want to call UpdateAdapter method from background to update adapter.
here is my ServiceClass:
public class MyService extends Service{
private String loginUserInfoId;
SessionManager session;
DatabaseHelper db;
MessageListActivity mLA;
long totalSize = 0;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
db = new DatabaseHelper(getApplicationContext());
mLA = new MessageListActivity();
session = new SessionManager(getApplicationContext());
session.checkLogin();
HashMap<String, String> user = session.getUserDetails();
loginUserInfoId = user.get(SessionManager.KEY_USER_INFO_ID);
if(isInternetOn()) {
new syncMessageFromServer().execute();
new SyncPendingMessageToServer();
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
private class syncMessageFromServer extends AsyncTask<Void, Integer, String> {
#Override
protected void onPreExecute() {
// setting progress bar to zero
//progressBar.setProgress(0);
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Integer... progress) {
}
#Override
protected String doInBackground(Void... params) {
return uploadFile();
}
#SuppressWarnings("deprecation")
private String uploadFile() {
String str = "";
HttpResponse response;
HttpClient myClient = new DefaultHttpClient();
HttpPost myConnection = new HttpPost("http://192.168.1.2/AndroidApp/GetAllMessage/" + loginUserInfoId);
try {
response = myClient.execute(myConnection);
str = EntityUtils.toString(response.getEntity(), "UTF-8");
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
JSONArray jArray = new JSONArray(str);
for (int i = 0; i <= jArray.length() - 1; i++) {
JSONObject row = jArray.getJSONObject(i);
ChatMessage cm = new ChatMessage();
String offlineFileURL = "";
/******* Firstly take data in model object ******/
cm.setOriginalMsgThreadId(row.getString("MessageThreadId"));
cm.setSenderUserInfoId(row.getString("SenderUserId")); cm.setReceiverUserInfoId(row.getString("MultipleReceiversId"));
cm.setMessageStatus("SENT");
cm.setIsPending(0);
cm.setMessageText(row.getString("MessageText"));
cm.setMediaURL(offlineFileURL);
cm.setThumbImage(offlineFileURL);
cm.setMediaMIMEType("");
cm.setMediaSize(0);
cm.setMediaName("");
cm.setLatitude("");
cm.setLongitude("");
cm.setSendTimeStamp(row.getString("SendTime"));
cm.setReceiveTimeStamp(row.getString("ReadTime"));
mLA.UpdateAdapter(ChatMessage cm);
long messageThreadId = db.SendMessage(cm);
}
} catch (JSONException e) {
e.printStackTrace();
}
return str;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(isInternetOn()) {
new syncMessageFromServer().execute();
}
}
}
}
and this is my MessageActivityList Class:
public class MessageListActivity extends ActionBarActivity {
private String receiverUserInfoId;
private String loginUserInfoId;
private String orgMsgThreadId;
private String userName;
private String uploadedFileURL = "";
DatabaseHelper db;
SessionManager session;
private ChatMessageAdapter chatMessageAdapter;
private EditText chatText;
private ImageButton buttonSend;
private ListView listView;
private static final String TAG = MessageListActivity.class.getSimpleName();
// Camera activity request codes
private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
private static final int CAMERA_CAPTURE_VIDEO_REQUEST_CODE = 200;
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
private Uri fileUri; // file url to store image/video
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message_list);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
.penaltyLog()
.build());
db = new DatabaseHelper(getApplicationContext());
session = new SessionManager(getApplicationContext());
session.checkLogin();
HashMap<String, String> user = session.getUserDetails();
loginUserInfoId = user.get(SessionManager.KEY_USER_INFO_ID);
Intent intent=getIntent();
Bundle extra = intent.getExtras();
receiverUserInfoId=extra.getString("UserInfoId");
orgMsgThreadId = extra.getString("OrgMessageThreadId");
userName=extra.getString("UserName");
setTitle(userName);
listView = (ListView) findViewById(R.id.messageList);
chatMessageAdapter = new ChatMessageAdapter(getApplicationContext(), R.layout.activity_single_message);
listView.setAdapter(chatMessageAdapter);
buttonSend = (ImageButton) findViewById(R.id.buttonSend);
chatText = (EditText) findViewById(R.id.chatText);
chatText.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
if(chatText.getText().toString().trim().length() > 0){
sendChatMessage();
}
}
return false;
}
});
buttonSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
sendChatMessage();
}
});
listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
// listView.setAdapter(chatMessageAdapter);
//to scroll the list view to bottom on data change
chatMessageAdapter.registerDataSetObserver(new DataSetObserver() {
#Override
public void onChanged() {
super.onChanged();
listView.setSelection(chatMessageAdapter.getCount() - 1);
}
});
setListData();
}
public void UpdateAdapter(ChatMessage cm) {
chatMessageAdapter.add(cm);
}
}
What to do for calling this UpdateAdapter method to update my ChatMessage received by the server?
You should be using a LocalBroadcastReceiver.
Register for receiving the updates in onResume and unregister in onPause.
U can use Broadcast receiver for updating the UI from service.
Register the broadcast receiver in onCreate() of ur Activity:
private UpdateReceiver updateReceiver;
if (UpdateReceiver == null)
{
updateReceiver = new UpdateReceiver();
IntentFilter intentFilter = new
IntentFilter("REFRESH_DATA");
registerReceiver(updateReceiver, intentFilter);
}
Unregister in onDestroy() of ur Activity
if (updateReceiver != null) unregisterReceiver(updateReceiver);
Define the Broadcast receiver in ur Activity :
private class UpdateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("REFRESH_DATA")) {
//update adapter from here
}
}
}
In ur service in which situation u want to update the adapter, there call sendBroadcast. Like:
Intent intent=new Intent("REFRESH_DATA");
//u can pass the data through putExtras
sendBroadcast(intent);
use Broadcast receiver for updating the UI from service and register the broadcast receiver in onCreate() of ur MainActivity where you want to recieve
code will like below
private UpdateReceiver updateReceiver;
if (UpdateReceiver == null)
{
updateReceiver = new UpdateReceiver();
IntentFilter intentFilter = new
IntentFilter("REFRESH_DATA");
registerReceiver(updateReceiver, intentFilter);
}
and create class to check update is recieved or not
private class UpdateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("REFRESH_DATA")) {
//update adapter from here
}
}
}
register a BroadcastReceiver inside your activity. call that method in onReceive method of this receiver. and from your Service sendBroadcast to this receiver, remember to add the required data to your intent and fetch data from onReceive method intent.

Android Service stops working after a certain point in code when called from activity

I am creating an android app which includes an activity which shows a list of tweets. When the activity is created a service is started which runs an async task to fetch the tweets and then passes them back to the activity using a broadcast.
Originally I had this working, but when I went to try it again yesterday the tweets were not showing up. After some debugging, I realised that the service wasn't executing all of my code. I did this by moving about a log message in my code to see the last place that it would print out in the logcat, this is shown in my service code below.
Does anyone know why this service is stopping or what the problem is exactly?
Code for service:
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.i(TAG,"The service has started!");
new GetTweets().execute();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onCreate()
{
super.onCreate();
myFormat = new SimpleDateFormat("yyyy-MM-dd");
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
private class GetTweets extends AsyncTask<String,Void,String>
{
ArrayList<String> text = new ArrayList<String>();
Tweet tweet;
#Override
protected void onPostExecute(String s)
{
super.onPostExecute(s);
}
#Override
protected String doInBackground(String... strings)
{
try
{
List<twitter4j.Status> statuses;
OAuth2Token bearerToken = null;
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey(CONSUMER_KEY)
.setOAuthConsumerSecret(CONSUMER_SECRET)
.setOAuthAccessToken(ACCESS_TOKEN)
.setOAuthAccessTokenSecret(ACCESS_SECRET)
.setApplicationOnlyAuthEnabled(true);
Configuration config = cb.build();
tf = new TwitterFactory(config);
twitter = tf.getInstance();
bearerToken = twitter.getOAuth2Token();
twitter.setOAuth2Token(bearerToken);
Paging page = new Paging(1, NUM_TWEETS);
statuses = twitter.getUserTimeline(name, page);
//Last line that is executed.
Log.i(TAGF, "Nearly Finished");
text = getAllTweets(statuses);
tweet = getLatestTweet(statuses);
Intent sendTweet = new Intent();
sendTweet.setAction(AURORA_ACTION);
sendTweet.putExtra("latestTweet", tweet);
sendTweet.putStringArrayListExtra("allTweets", text);
sendBroadcast(sendTweet);
Toast.makeText(getApplicationContext(), "Sent tweets", Toast.LENGTH_SHORT).show();
} catch (TwitterException e)
{
e.printStackTrace();
}
catch (ParseException parse)
{
}
return null;
}
Activity code:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.aurora);
myList = (ListView) findViewById(R.id.listView);
getActionBar().setTitle("AuroraWatch UK Tweets");
getActionBar().setBackgroundDrawable(new ColorDrawable(R.style.CodeFont));
Intent getTweets = new Intent(this,AuroraService.class);
startService(getTweets);
Toast.makeText(this, "Activity Started", Toast.LENGTH_SHORT).show();
}
#Override
protected void onPause()
{
super.onPause();
unregisterReceiver(myReceiver);
}
#Override
protected void onResume()
{
super.onResume();
myReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
ArrayList<String> tweets=null;
String action = intent.getAction();
if (action.equals(AuroraService.AURORA_ACTION))
{
Toast.makeText(context, "Received tweets", Toast.LENGTH_SHORT).show();
tweets = intent.getStringArrayListExtra("allTweets");
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, tweets);
myList.setAdapter(adapter);
}
};
IntentFilter myFilter = new IntentFilter();
myFilter.addAction(AuroraService.AURORA_ACTION);
registerReceiver(myReceiver,myFilter);
}
EDIT: getAllTweets () method:
public ArrayList<String> getAllTweets(List<twitter4j.Status> statuses)
{
ArrayList<String> myTweets = new ArrayList<String>();
for (twitter4j.Status status: statuses)
{
String tweet = status.getText();
myTweets.add(tweet);
}
return myTweets;
}

Categories

Resources