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");
}
}
Related
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);
}
i have created broadcast receiver for passing data between service to activity, when first time open app broadcast receiver called oknly once but when app open second time then broadcast receiver called twice
-> code for pass data service to
final Intent broadcastIntent = new Intent();
broadcastIntent.setAction(MainActivity.MyWebRequestReceiver.PROCESS_RESPONSE);
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
broadcastIntent.putExtra(BUNDLE, args);
sendBroadcast(broadcastIntent);
and here is code for handle response in activity and register receiver
IntentFilter filter = new IntentFilter(MyWebRequestReceiver.PROCESS_RESPONSE);
filter.addCategory(Intent.CATEGORY_DEFAULT);
receiver = new MyWebRequestReceiver();
registerReceiver(receiver, filter);
registerReceiver(broadcastReceiver, new IntentFilter("broadCastName"));
handle its response
public class MyWebRequestReceiver extends BroadcastReceiver {
public static final String PROCESS_RESPONSE = "com.as400samplecode.intent.action.PROCESS_RESPONSE";
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive");
Bundle bundle = intent.getParcelableExtra(AutoOpenAppService.BUNDLE1);
String mainUrl = bundle.getString(MAINURL);
Boolean wvVisible = bundle.getBoolean(WVBOOLEAN);
Bundle args = intent.getParcelableExtra(AutoOpenAppService.BUNDLE);
ArrayList<? extends UrlTimeModel> list = args.getParcelableArrayList(LIST);
Long TimeOut = args.getLong(TIMEOUT);
if (mainUrl != null) {
if (!isFinishing()) {
setWebView(mainUrl);
}
}
Log.d(TAG, "VISIBLE : " + wvVisible);
if (wvVisible) {
webView.setVisibility(View.VISIBLE);
} else {
if (alert != null) {
alert.dismiss();
}
moveTaskToBack(true);
}
assert list != null;
if (list.size() < 0) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
alert.dismiss();
MainActivity.this.finish();
MainActivity.super.onBackPressed();
MainActivity.this.moveTaskToBack(true);
}
}, TimeOut);
}
LoadSubURl((ArrayList<UrlTimeModel>) list, TimeOut);
}
}
unregister in onstop()
#Override
protected void onStop() {
super.onStop();
if (timer != null && timerTask != null) {
timerTask.cancel();
timer.cancel();
timer.purge();
timer = null;
timerTask = null;
}
// TODO: 20/12/17 Call Hide Icon Method
HideIconMethod();
if (bound) {
unbindService(serviceConnection);
bound = false;
}
this.unregisterReceiver(receiver);
this.unregisterReceiver(broadcastReceiver);
}
I'm having difficulty implementing a ResultReceiver on my IntentService class which scans for available devices on the network. (disregarding the terrible design of my code so far) I can't seem to even get my resultReceiver to pass back a test string, the log picks up the instance which I'm sending, but I get a nullPointerException when I try to access the passed in string.
Here are the relevant sections of my Intent Service class:
public class NetHelper extends IntentService{
private ConnectivityManager cm;
private WifiManager manager;
private WifiInfo connectionInfo;
private NetworkInfo activeNetwork;
public Context myContext;
public ResultReceiver receiver;
public Bundle b;
SharedPreferences netprefs;
SharedPreferences.Editor editor;
#Override
protected void onHandleIntent(#Nullable Intent intent) {
//if intent-int == 0: run netsniff
//if intent-int == 1: run getNetInfo
int OPR = intent.getIntExtra("OPR", 0); //0 is default value...
//result receiver for callback use
Bundle params = intent.getExtras();
receiver = params.getParcelable("receiverTag");
b = new Bundle();
//long running operation is netsniff
listDevices = new ArrayList<Devices>();
myContext = getApplicationContext();
//application based storing of values
netprefs = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE);
editor = netprefs.edit();
cm = (ConnectivityManager) myContext.getSystemService(Context.CONNECTIVITY_SERVICE);
activeNetwork = cm.getActiveNetworkInfo();
manager = (WifiManager) myContext.getSystemService(Context.WIFI_SERVICE);
connectionInfo = manager.getConnectionInfo();
if (OPR == 0) {
try {
netSniff();
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG, e.toString());
}
}
}
snippet from my function which sends a new bundle:
public void netSniff() throws IOException {
Log.d(TAG, "begin sniffing network on network: "+ NET_IP);
Log.d(TAG, "Active Network: " + String.valueOf(activeNetwork));
Log.d(TAG, "IP_ADDR: " + String.valueOf(MYNET_IP));
b.putString("RESULT_RECEIVED", "TESTING23748W3458763298457Y34");
receiver.send(0, b);
myResultReceiver class:
public class myResultReceiver extends ResultReceiver{
private Receiver mReceiver;
public myResultReceiver(Handler handler) {
super(handler);
}
public interface Receiver {
public void onReceiveResult(int resultCode, Bundle resultData);
}
public void setReceiver(Receiver receiver) {
mReceiver = receiver;
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
if (mReceiver != null) {
mReceiver.onReceiveResult(resultCode, resultData);
}
}
and last, here are my calls for my Fragment:
public class devicesFragment extends Fragment implements myResultReceiver.Receiver {
public myResultReceiver mReceiver;
//discover network info, and get a list of devices
public void launchNetworkSniffer(int opr) {
Intent serviceIntent = new Intent(getActivity(), NetHelper.class);
//setup resultReceiver for service callbacks
mReceiver = new myResultReceiver(new Handler());
mReceiver.setReceiver(this);
serviceIntent.putExtra("receiverTag", mReceiver);
serviceIntent.putExtra("OPR", opr);
getActivity().startService(serviceIntent);
}
//receiver implemented methods
#Override
public void onReceiveResult(int resultCode, Bundle resultData) {
Log.d("DATA_RECEIVED******", "processing...");
String newdevjson = resultData.getString("RECEIVED_RESULT");
Log.d("DATA_RECEIVED", newdevjson);
Devices newd = new Gson().fromJson(newdevjson, Devices.class);
devlist.add(newd);
for (Devices i : devlist) {
Log.d("ACTIVE_DEV_COUNT", i.getIp());
}
}
The first log from my fragment's onResultReceived() is showing but it crashes when I assign the resultData.getString() with a nullPointerReference.
I believe this fact means I've instantiated everything correctly, so why isn't anything getting passed back at all?
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"/>
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.