intentService resultReceiver nullpointerException - android

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?

Related

How to stop Thread in service when its in offline?

I am working on an android app with calling webservice when it has internet by using service and broadcast receivers below is my code:
public class YourService extends IntentService {
private static String TAG = YourService.class.getSimpleName();
private MyThread mythread;
public boolean isRunning = false;
JSONArray SaveOrderDart,SaveOrderDetails,UpdateDart,updateOrderDetails;
private static String urlDartorder= Config.url+"SaveDartDetails";
private static String urlupdateOrderDetails= Config.url+"UpdateOrderDetails";
private static String urlSaveOrderDetails= Config.url+"SaveOrderDetails";
private static String urlDartupdate= Config.url+"UpdateDartDetails";
DartDatabase ddb;
OrderDatabase ord;
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* #param name Used to name the worker thread, important only for debugging.
*/
public YourService(String name) {
super(name);
}
#Override
public void onCreate() {
super.onCreate();
mythread=new MyThread();
}
public YourService()
{
super("call webservice");
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
Bundle extras = intent.getExtras();
boolean isNetworkConnected = extras.getBoolean("isNetworkConnected");
// your code
if(isNetworkConnected){
if(!isRunning){
mythread.start();
isRunning = true;
}
Log.e("TAG", "Yes");
}
else {
if (mythread != null) {
isRunning = false;
mythread.interrupt();
}
//mythread.stop();
}
}
#Override
public void onDestroy() {
super.onDestroy();
if(!isRunning){
mythread.start();
isRunning = true;
}
}
My broadcastreceiver
public class ConnectivityChangeReceiver extends BroadcastReceiver {
boolean mLastState =false;
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that which service class will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
YourService.class.getName());
//mLastState = true;
intent.putExtra("isNetworkConnected", isConnected(context));
context.startService((intent.setComponent(comp)));
}
public boolean isConnected(Context context) {
ConnectivityManager connectivityManager = ((ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE));
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected();
}
}
my purpose is when internet is present i want to call webservice not present then stop the thread and service but by this code i can't stop the service i don't no why please help me!
but i can't stop thread please help me!

IntentService not call api when App closed

I have created one IntentService to send local data to the server.
I am calling this service from two different broadcast receivers.
1) When from Connectivity change receiver.
2) on 12 am with alarm manager
Its working fine when an app is open.
But not working when an app is closed.
Below is my IntentService code.
public class ExpertEventService extends IntentService {
#Inject
Context context;
#Inject
Realm realm;
public ExpertEventService() {
super("ExpertEventService");
Log.e("expertEvent", "service constructor");
// Toothpick.inject(this, Toothpick.openScope(Constants.APPSCOPENAME));
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
Toothpick.inject(this, Toothpick.openScope(Constants.APPSCOPENAME));
Log.e("expertEvent", "service started");
RealmResults<AskExpertEventModel> results = realm.where(AskExpertEventModel.class).findAll();
List<AskExpertEventModel> requestList = realm.copyFromRealm(results);
String language = realm.where(LanguageStore.class).equalTo(LanguageStore.ISSELECTED, true).findAll().first().getCode();
String appInstanceCode = Preferences.getAppInstanceCode(context);
String token = Preferences.getToken(context);
Api.userManagement(context).expertEvent(appInstanceCode, token, language, requestList)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(new ApiSuccess<EventResponse>() {
#Override
public void call(EventResponse eventResponse) {
Log.e("expertEvent", eventResponse.getStatus());
if (eventResponse.getStatus().equalsIgnoreCase(Constants.Status.STATUS_SUCCESS)) {
Log.e("expertEvent", "sucess");
new RealmDB().deleteEvent();;
}
}
}, new ApiFail() {
#Override
public void httpStatus(HttpErrorResponse response) {
Log.e("expertEvent", response.getError());
}
#Override
public void noNetworkError() {
Log.e("expertEvent", "no network connection");
}
#Override
public void unknownError(Throwable e) {
Log.e("expertEvent", e.getMessage());
}
});
}
}
1) Receiver called when connectivity change
public class NetworkStateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("expertEvent", "Connectivity changed");
ConnectivityManager cm = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null) {
if (info.isConnected()) {
//start service
Log.e("expertEvent", "Connected ");
Intent serviceIntent = new Intent(context,
ExpertEventService.class);
context.startService(serviceIntent);
}
} else {
Log.e("expertEvent", "not connected");
}
}
}
2) Execute when 12 am
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//call service
Log.e("alarmreceiver","in alarm receiver");
Intent serviceIntent = new Intent(context, ExpertEventService.class);
context.startService(serviceIntent);
}
}

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 Charge intent has no extra data

I am trying to display an alert in a specific Activity when the charging status changes.
this is my receiver class:
public class BatteryChargeReceiver extends BroadcastReceiver {
private String TAG = "receiver";
private ChargeReceiverCallback callback;
public BatteryChargeReceiver(ChargeReceiverCallback callback) {
this.callback =callback;
Log.v(TAG,"Inside Constructor (Callback)");
}
public interface ChargeReceiverCallback {
public void onReceive(Intent intent);
}
#Override
public void onReceive(Context context, Intent intent) {
callback.onReceive(intent);
}
}
And below is how I instantiate it from my MainActivity's onResume. MainActivity implements my interface and overrides onReceive(intent). I found out that at no stage does intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1) return anything else then -1.
BatteryChargeReceiver batteryReceiver = new BatteryChargeReceiver(this);
IntentFilter filterPower = new IntentFilter("android.intent.action.ACTION_POWER_CONNECTED");
registerReceiver(batteryReceiver, filterPower);
Intent.ACTION_POWER_CONNECTED not delivering current plugged-in state - this is probably a change in how API works, but I could not locate any mention of such change in docs.
The broadcast Intent.ACTION_POWER_CONNECTED was never meant to receive current plugged-in type, but it merely lets the receiving end of power connection (ref.). In fact, BatteryService.java broadcasts plain intent without any extra values (lines 410~412 as of this writing):
Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);
statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
However, following code with
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="19" />
worked on Nexus 5:
public class MainActivity extends Activity {
private static final String TAG = "PowerReceiver";
private final BroadcastReceiver mPowerReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
Log.d(TAG, "Power connected");
checkPluggedState(context, intent);
} else if (Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
Toast.makeText(context, "Power disconnected", Toast.LENGTH_SHORT).show();
} else {
Log.wtf(TAG, "Unknown action: " + action);
}
}
};
private void checkPluggedState(Context context, Intent intent) {
Intent chargingIntent = registerReceiver(null, new IntentFilter(
Intent.ACTION_BATTERY_CHANGED));
final int pluggedState = chargingIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
final String msg;
switch (pluggedState) {
case 0:
msg = "The device is running on battery";
break;
case BatteryManager.BATTERY_PLUGGED_AC:
msg = "Plugged into AC charger";
break;
case BatteryManager.BATTERY_PLUGGED_USB:
msg = "Plugged into USB charger";
break;
case BatteryManager.BATTERY_PLUGGED_WIRELESS:
msg = "Plugged into wireless charger";
break;
default:
msg = "Unknown state: " + pluggedState;
}
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_POWER_CONNECTED);
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
registerReceiver(mPowerReceiver, filter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mPowerReceiver);
}
}
Hope this helps.
According to The docs, EXTRA_STATUS is for ACTION_BATTERY_CHANGED

How to cast in IntentService::handleIntent the CustomResultReceiver passed as an intent extra

I am trying to cast the Intent::extraParcelable received, to my custom RestResultReceiver like this
public class APIHttpV1Service
extends IntentService
{
...
protected void onHandleIntent (Intent intent)
{
final int apiCall = intent.getIntExtra("uri");
final RestResultReceiver resultReceiver = intent.getParcelableExtra(RestResultReceiver.EXTRA_ID_RESULT_RECEIVER);
// check if the uri is correct
if( apiCall == -1)
{
// TODO call failed as we didn't provide any URI
resultReceiver.send(RestStatus.ERROR, Bundle.EMPTY);
}
...
}
}
and this is the RestResultReceiver
public class RestResultReceiver
extends ResultReceiver
{
private static final String TAG = "com...RestResultReceiver";
public static final String EXTRA_ID_RESULT_RECEIVER = "com...RestResultRecevier.Receiver";
private Receiver __mReceiver;
public RestResultReceiver(Handler handler)
{
super(handler);
}
public void clearReceiver()
{
__mReceiver = null;
}
/**
* Set the receiver
* #param receiver the object getting called back using onReceiveResult
*/
public void setReceiver( Receiver receiver )
{
__mReceiver = receiver;
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData)
{
if (__mReceiver != null)
{
__mReceiver.onReceiveResult(RestStatus.getEnum(resultCode), resultData);
}
else
{
Log.w(TAG, "Dropping result on floor for code " + resultCode + ": "
+ resultData.toString());
}
}
public void send(RestStatus resultStatus, Bundle resultData)
{
super.send(resultStatus.getCode(), resultData);
}
/**
* Interface to implement for objects doing rest service call
*/
public interface Receiver
{
public void onReceiveResult(RestStatus resultStatus, Bundle resultData);
}
}
At runtime I have a java.lang.ClassCastException exception. I am just wondering why I can get my RestResultReceiver.
If I use
final ResultReceiver resultReceiver = intent.getParcelableExtra(RestResultReceiver.EXTRA_ID_RESULT_RECEIVER);
it doesn't throw any error but I can't call my custom send function obviously.
Any idea?
Thx a lot for any help you could provide :)

Categories

Resources