I have a second class from which I call some methods to handle app updating. There is a progress dialog in them so I have to pass the current application context to its constructor. The code works fine when called directly in my MainActivity onCreate(), but it breaks down when I delegate the code to an external class. What's going wrong?
Method Call in OnCreate():
private AppUpdateHelper appUpdateHelper = new AppUpdateHelper(getApplicationContext());
#Override
protected void onCreate(Bundle savedInstanceState) {
appUpdateHelper.handleAppUpdate();
}
Delegate Class:
public class AppUpdateHelper {
private Context mContext;
public AppUpdateHelper(Context mContext) {
this.mContext = mContext;
}
public void handleAppUpdate() {
String versionCode = getVersionCode(); // Get app's current version code
// Is app update to date?
if (isAppCurrent(versionCode)) {
promptAppUpdate();
}
}
private String getVersionCode() {
String versionCode = null;
try {
PackageInfo pInfo = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
versionCode = pInfo.versionName;
// Log.w(mContext.getClass().getSimpleName(), "Current Version: " + versionCode);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return versionCode;
}
private boolean isAppCurrent(String versionCode) {
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
String userAppVersion = installation.getString("appVersion");
return !userAppVersion.equals(versionCode);
}
private void promptAppUpdate() {
SweetAlertDialog pDialog = new SweetAlertDialog(mContext, SweetAlertDialog.WARNING_TYPE);
pDialog.setTitleText("Update Available!");
pDialog.setContentText("You must update to continue using Yeet Club!");
pDialog.setConfirmClickListener(sDialog -> {
final String appPackageName = mContext.getPackageName(); // getPackageName() from Context or Activity object
try {
mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
} catch (ActivityNotFoundException anfe) {
mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
}
sDialog.dismissWithAnimation();
});
pDialog.setCancelable(false);
pDialog.showCancelButton(false);
pDialog.show();
}
}
Exception:
08 - 20 15: 43: 43.874 21456 - 21456 / com.app.android E / AndroidRuntime: FATAL EXCEPTION: main
Process: com.app.android, PID: 21456
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo {
com.app.android / com.app.android.activity.MainActivity
}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()'
on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java: 2458)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java: 2613)
at android.app.ActivityThread.access$900(ActivityThread.java: 180)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java: 1473)
at android.os.Handler.dispatchMessage(Handler.java: 111)
at android.os.Looper.loop(Looper.java: 207)
at android.app.ActivityThread.main(ActivityThread.java: 5710)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java: 900)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java: 761)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()'
on a null object reference
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java: 117)
at com.app.android.activity.MainActivity. < init > (MainActivity.java: 77)
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java: 1072)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java: 2448)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java: 2613)
at android.app.ActivityThread.access$900(ActivityThread.java: 180)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java: 1473)
at android.os.Handler.dispatchMessage(Handler.java: 111)
at android.os.Looper.loop(Looper.java: 207)
at android.app.ActivityThread.main(ActivityThread.java: 5710)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java: 900)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java: 761)
This is very simple.
You can get context instance after called OnCreate
private AppUpdateHelper appUpdateHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
appUpdateHelper = new AppUpdateHelper(getApplicationContext());
appUpdateHelper.handleAppUpdate();
}
You can pass the activity context it self using this key word.
#Override
protected void onCreate(Bundle savedInstanceState) {
appUpdateHelper = new AppUpdateHelper(this);
appUpdateHelper.handleAppUpdate();
}
You can't call getApplicationContext() before the class initialized
You can only call after the class initialized. You can get it on onCreate() or other methods called by android.
you are safe to call inside onCreate()
#Override
protected void onCreate(Bundle savedInstanceState) {
appUpdateHelper = new AppUpdateHelper(getActivity()); // if it is Fragment
appUpdateHelper = new AppUpdateHelper(this); // if it is Activity
appUpdateHelper.handleAppUpdate();
}
Application context won't work with Dialog. Because application context does not have theme related information. Use Activity context instead of Application Context
Related
Apologizes if this is a stupid question but I'm attempting to create a Intent to the next activity in AsynTask after it has pulled a user from my AWS Database. Note that this class is HomeActivity and the next one is GroupActivity. Below I have the button that will run the AsynTask:
Button groupPageBtm = findViewById(R.id.groupPage);
groupPageBtm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LoadGroupUser loadGroupUser = new LoadGroupUser(HomeActivity.this);
loadGroupUser.execute(makeUserIDString.uniqueIDCreater(userProfile));
}
});
Here is my AsynTask subclass:
class LoadGroupUser extends AsyncTask<String, Void, GroupDO>{
private DynamoDBMapper dynamoDBMapper;
Activity activity;
public LoadGroupUser(Activity mActivity){
this.activity = mActivity;
}
Intent groupLoadIntent = new Intent(activity, GroupActivity.class);
#Override
protected GroupDO doInBackground(String... groupPresidentGroups) {
AmazonDynamoDBClient dynamoDBClient = new AmazonDynamoDBClient(AWSMobileClient.getInstance().getCredentialsProvider());
this.dynamoDBMapper = DynamoDBMapper.builder()
.dynamoDBClient(dynamoDBClient)
.awsConfiguration(AWSMobileClient.getInstance().getConfiguration())
.build();
GroupDO groupPresDO = dynamoDBMapper.load(GroupDO.class, groupPresidentGroups[0]);
Log.i("loadedPresident: ", groupPresDO.getGroupId().toString());
return null;
}
#Override
protected void onPostExecute(GroupDO groupDO) {
super.onPostExecute(groupDO);
groupLoadIntent.putExtra("groupPresident", groupDO.getGroupPresident().toString());
activity.startActivity(groupLoadIntent);
Log.i("groupPresident", groupDO.getGroupPresident().toString());
}
}
Error Message:
-12 17:02:59.424 10503-10503/com.ronone.securesender E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ronone.securesender, PID: 10503
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.content.ComponentName.<init>(ComponentName.java:130)
at android.content.Intent.<init>(Intent.java:5780)
at com.ronone.securesender.LoadGroupUser.<init>(HomeActivity.java:188)
at com.ronone.securesender.HomeActivity$1.onClick(HomeActivity.java:77)
at android.view.View.performClick(View.java:6294)
at android.view.View$PerformClick.run(View.java:24770)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
The problem is here:
public LoadGroupUser(Activity mActivity){
this.activity = mActivity;
}
Intent groupLoadIntent = new Intent(activity, GroupActivity.class);
The field initializer runs before the constructor, so activity is still null. Do this instead:
Intent groupLoadIntent;
public LoadGroupUser(Activity mActivity){
this.activity = mActivity;
groupLoadIntent = new Intent(activity, GroupActivity.class);
}
But note that you're potentially leaking your activity by having a strong reference to it in an AsyncTask. That's a whole other topic. Search this site for "AsyncTask activity leak."
So I'm working on an app and I had this part working for days, and out of no where it just stopped working for no reason...
I also had the same error when I was trying to use another headless fragment in my MainActivity, but ended up replacing the fragment with inner methods inside of the MainActivity and everything went back to working properly.
However, I can't rewrite every bit of code I have just to avoid using fragments. The fragment code is below.
public class IMEIFragment extends Fragment implements ActivityCompat.OnRequestPermissionsResultCallback{
public static final String TAG_IMEI = "IMEILoader";
protected Activity mActivity;
private String RecordedIMEI;
//public static final String CHECK_INTERNET = "network_connection";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return null; //Do we need this at all?
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
Activity activity = context instanceof Activity ? (Activity) context : null;
mActivity = activity;
}
//Is this needed?
#SuppressWarnings("deprecation")
#Override
public void onAttach(Activity activity) {
activity = getActivity();
if (isAdded() && activity != null) {
super.onAttach(activity);
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
mActivity = activity;
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public void onDetach() {
super.onDetach();
mActivity = null;
}
public String loadIMEI(Context context) {
if (Build.VERSION.SDK_INT >= 23) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
// READ_PHONE_STATE permission has not been granted.
requestPermissions(context);
} else {
// READ_PHONE_STATE permission is already been granted.
RecordedIMEI = permissionGrantedActions(context);
}
if (RecordedIMEI != null) {
Log.i("loadIMEIService", "IMEI number returned!");
}
} else {
// READ_PHONE_STATE permission is already been granted.
RecordedIMEI = permissionGrantedActions(context);
}
if (RecordedIMEI != null) {
Log.i("loadIMEIService", "IMEI number returned!");
}
return RecordedIMEI;
}
private void requestPermissions(Context context) {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
Log.i("loadIMEIService", "READ_PHONE_STATE permission not granted, asking for it...");
// TODO create proper notification content
PermissionHelper.requestPermissions(((PriceActivity) getActivity()),
new String[]{Manifest.permission.READ_PHONE_STATE},
Constants.PERM_REQUEST_PHONE_STATE,
getString(R.string.notify_perm_title),
getString(R.string.notify_perm_body),
R.drawable.ic_security);
}
}
// Callback received when a permissions request has been completed.
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
boolean isGranted = false;
for (int i = 0; i < grantResults.length; i++)
if (permissions[i].equals(Manifest.permission.READ_PHONE_STATE) && (grantResults[i] == PackageManager.PERMISSION_GRANTED))
isGranted = true;
if (isGranted) {
Context context = getActivity().getApplicationContext();
permissionGrantedActions(context);
}
else
Log.w("loadIMEIService", "READ_PHONE_STATE permission not granted. loadIMEI will not be available.");
}
public String permissionGrantedActions(Context context) {
//Have an object of TelephonyManager
TelephonyManager tm =(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
//Get IMEI Number of Phone
String IMEINumber = tm.getDeviceId();
if(IMEINumber != null) {
Log.i("loadIMEIService", "IMEI number recorded!");
}
return IMEINumber;
}
}
Error is below:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.project1, PID: 5498
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.project1/com.android.project1.main.MainActivity}: java.lang.IllegalStateException: Fragment IMEIFragment{3e80da7 IMEILoader} not attached to Activity
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.IllegalStateException: Fragment IMEIFragment{3e80da7 IMEILoader} not attached to Activity
at android.app.Fragment.getResources(Fragment.java:805)
at android.app.Fragment.getString(Fragment.java:827)
at com.android.project1.fragments.IMEIFragment.requestPermissions(IMEIFragment.java:107)
at com.android.project1.fragments.IMEIFragment.loadIMEI(IMEIFragment.java:80)
at com.android.project1.main.MainActivity.onCreate(MainActivity.java:108)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
And here's the relevant part of my MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDeviceCode = (TextView) findViewById(R.id.device_code);
// Initializing headless fragment
mFragment =
(IMEIFragment) getFragmentManager()
.findFragmentByTag("IMEILoader");
if (mFragment == null) {
mFragment = new IMEIFragment();
getFragmentManager().beginTransaction()
.add(mFragment, "IMEILoader").commit();
}
if (mFragment != null) {
mNumber = mFragment.loadIMEI(MainActivity.this);
mDeviceCode.setText(Html.fromHtml("<b>IMEI</b>: " + mNumber));
}
I literally had the exact same code working for over a week. Anyone knows what could be the problem?
Edit 1: The error is pointing to requestPermissions inside my fragment
Fragments should be self contained as much as possible. You are calling directly into your IMEIFragment from the activity,
Caused by: java.lang.IllegalStateException: Fragment IMEIFragment{3e80da7 IMEILoader} not attached to Activity
at android.app.Fragment.getResources(Fragment.java:805)
at android.app.Fragment.getString(Fragment.java:827)
at com.android.project1.fragments.IMEIFragment.requestPermissions(IMEIFragment.java:107)
at com.android.project1.fragments.IMEIFragment.loadIMEI(IMEIFragment.java:80)
at com.android.project1.main.MainActivity.onCreate(MainActivity.java:108)
You can't do that. Adding the fragment via a transaction from the activity is an asynchronous operation. E.g., when the commit() method completes, the fragment is not initialized. Moreover, you have no way of knowing when it's initialized. That's why it should be self contained. The fragment decides when to call loadIMEI(), not the activity.
If you really need it to be initiated by the activity, you can add a callback from the fragment to the activity like,
void onFragmentReady(Fragment f);
Or something.
And yes, onCreateView() should return something. If your fragment really doesn't have any UI at all, you don't need it to be a fragment.
onPostExecute()-NullPointerException: Attempt to invoke v.method'android.view.Window$Callback android.view.Window.getCallback()'on a null object ref.
Null pointer Exception(onPostExecute()-NullPointerException: Attempt to invoke v.method'android.view.Window$Callback) on set method(MainActivity) or on postExecute
methode(img load) appears.
I was trying to load an image and set it to the imageview in mainactivity. but I cant refer to that imageview.
I can't refer to that imageview from imageload class but I can refer to that from any method in mainactivity.
Here is MainActivity :
public class MainActivity extends AppCompatActivity {
ImageView imageView;
Context context;
TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageView);
textView = (TextView) findViewById(R.id.textView);
}
public void network(View view) {
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
// fetch data
Toast.makeText(this, "Network detected", Toast.LENGTH_SHORT).show();
String stringUrl = "http://www.lorempixel.com/420/240/";
new imgLoad().execute(stringUrl);
} else {
// display error
Toast.makeText(this, "No network detected", Toast.LENGTH_SHORT).show();
// textView.setText("No network connection available.");
}
}
public void set(Bitmap bitmap) {
textView = (TextView) findViewById(R.id.textView);
if (textView != null) {
textView.setText("setting image..");
}
Toast.makeText(this, "setting..,", Toast.LENGTH_SHORT).show();
if (imageView != null) {
Toast.makeText(this, "good", Toast.LENGTH_SHORT).show();
textView.setText("image not null..");
imageView.setImageBitmap(bitmap);
}else {
textView.setText("null");
}
}
Here references on set method are null and cant get reference on below class for ImageView.
Here is Imageloader class:
public class imgLoad extends AsyncTask<String, Void, Bitmap> {
#Override
protected Bitmap doInBackground(String... params) {
return load(params[0]);
}
#Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
MainActivity m = new MainActivity();
// ImageView c = m.x();
m.set(bitmap);
// Toast.makeText(MainActivity.getContext(), "downloaded", Toast.LENGTH_SHORT).show();
// if (c!=null) {
// c.setImageBitmap(bitmap);
// }
}
private Bitmap load(String param) {
Bitmap bitmap = null;
InputStream inputStream;
try {
URL url = new URL(param);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("Get");
httpURLConnection.setConnectTimeout(4000);
httpURLConnection.setReadTimeout(2000);
httpURLConnection.setDoInput(true);
httpURLConnection.connect();
inputStream = httpURLConnection.getInputStream();
bitmap = BitmapFactory.decodeStream(inputStream);
} catch (MalformedURLException e) {
Log.e("error", "wrong url : " + e.getMessage());
// e.printStackTrace();
} catch (IOException e) {
// e.printStackTrace();
Log.e("error", "failed : " + e.getMessage());
}
return bitmap;
}
}
Here is the Logcat:
12-13 10:15:53.234 28054-28127/com.facebook.mahmud.r.pixels E/error: failed : Expected one of [OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, PATCH] but was Get
12-13 10:15:53.347 28054-28054/com.facebook.mahmud.r.pixels D/AndroidRuntime: Shutting down VM
12-13 10:15:53.364 28054-28054/com.facebook.mahmud.r.pixels E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.facebook.mahmud.r.pixels, PID: 28054
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference
at android.support.v7.app.AppCompatDelegateImplBase.<init>(AppCompatDelegateImplBase.java:68)
at android.support.v7.app.AppCompatDelegateImplV7.<init>(AppCompatDelegateImplV7.java:145)
at android.support.v7.app.AppCompatDelegateImplV11.<init>(AppCompatDelegateImplV11.java:28)
at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java:41)
at android.support.v7.app.AppCompatDelegateImplV23.<init>(AppCompatDelegateImplV23.java:29)
at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:186)
at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:170)
at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:502)
at android.support.v7.app.AppCompatActivity.findViewById(AppCompatActivity.java:174)
at com.facebook.mahmud.r.pixels.MainActivity.set(MainActivity.java:151)
at com.facebook.mahmud.r.pixels.imgLoad.onPostExecute(imgLoad.java:35)
at com.facebook.mahmud.r.pixels.imgLoad.onPostExecute(imgLoad.java:20)
at android.os.AsyncTask.finish(AsyncTask.java:651)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
12-13 10:15:56.700 28054-28054/com.facebook.mahmud.r.pixels I/Process: Sending signal. PID: 28054 SIG: 9
TIA.
Let's put your problem in proper format. When you ran your application you created an object for MainActivity. Let us call that mainActivityObject1. From mainActivityObject1 you created an object for imgLoad class. In that after downloading the image you created yet another object for MainActivity (let's call it mainActivityObject2). Now you are trying to call the method mainActivityObject2.set(bitmap); where you should be calling mainActivityObject1.set(bitmap);.
You can solve this problem couple of ways. But the most basic one is by passing the activity context.
Create a constructor in imgLoad class and change your onPostExecute method like this:
private MainActivity mainActivityContext;
public imgLoad(MainActivity passedActivityContext){
this.mainActivityContext = passedActivityContext;
}
#Override
protected Bitmap doInBackground(String... params) {
return load(params[0]);
}
#Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
mainActivityContext.set(bitmap);
}
From your MainActivity class when you do instantiate imgLoad pass your activity context like this:
new imgLoad(MainActivity.this).execute(stringUrl);
Now you when you call set(Bitmap bitmap) from imgLoad class it should call the original MainActivity object that created the imgLoad object.
Note:
I also noticed you are not calling network method in your MainActivity class that you posted in here. Do call it to test properly.
I'm creating a simple Android Class that update a variable with the most recent value readed from some specific sensors (Light, temp and more), which I access it(sensor value) by getData() method, but i'm getting an error. I hope u can help me!
Here is my generic sensor class.
MySensor
public class mySensor extends Service implements SensorEventListener {
private SensorManager mSensorManager =null;
private Sensor s=null;
float data = 0;
public void onCreate(){
super.onCreate();
mSensorManager= (SensorManager) getSystemService(Context.SENSOR_SERVICE);
}
public mySensor(int type){
//HERE I'M GETTING THE ERROR
s= mSensorManager.getDefaultSensor(type);
}
public String getData(){
return String.valueOf(data);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_LIGHT) {
data = event.values[0];
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
protected void onResume() {
mSensorManager.registerListener((SensorEventListener) this, s, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
// super.onPause();
mSensorManager.unregisterListener((SensorEventListener) this);
}
}
Here is the log
...
E/AndroidRuntime: FATAL EXCEPTION: main
Process: project.luke.com.sensorreader, PID: 25297
java.lang.RuntimeException: Unable to start activity ComponentInfo{project.luke.com.sensorreader/project.luke.com.sensorreader.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.hardware.Sensor android.hardware.SensorManager.getDefaultSensor(int)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2460)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2522)
at android.app.ActivityThread.access$800(ActivityThread.java:169)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:967)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.hardware.Sensor android.hardware.SensorManager.getDefaultSensor(int)' on a null object reference
at project.luke.com.sensorreader.mySensor.<init>(mySensor.java:39)
at project.luke.com.sensorreader.MainActivity.onCreate(MainActivity.java:32)
at android.app.Activity.performCreate(Activity.java:5975)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1111)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2413)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2522)
at android.app.ActivityThread.access$800(ActivityThread.java:169)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:967)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
In my MainActivity class I simple call mLight=new mySensor(Sensor.TYPE_LIGHT); but this trigger the error, cause mSensorManager=null, always.
From your MainActivity:
Intent intent = new Intent(this, mySensor.class);
intent.putExtra("type", Sensor.TYPE_LIGHT);
and within your service:
#Override
public IBinder onBind(Intent intent) {
mSensorManager= (SensorManager) getSystemService(Context.SENSOR_SERVICE);
int type = intent.getExtras().get("type");
s= mSensorManager.getDefaultSensor(type);
return null;
}
then you can remove:
public mySensor(int type){
...
}
and eventually the code you wrote within the onCreate.
Hi first of all i searched some similar questions like mine but unfortunately i couldn't find the similarity of my code to them so please here me out
I have a Main Activity Class
public class MainActivity extends AppCompatActivity {
public ProgressDialog loading;
public String[] itemer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RetrofitHandler handler = new RetrofitHandler();
handler.getContacts(MainActivity.this);
}
public void getter(String[] response, int size) {
String[] itemer;
itemer = new String[size];
if (response != null) {
itemer = response;
Toast.makeText(MainActivity.this, itemer[0], Toast.LENGTH_SHORT).show();
}
}
And a Handler for my result
public class RetrofitHandler {
public String[] item;
public static final String ROOT_URL = "http://api.androidhive.info";
public List<Contacts> contacts;
// final MainActivity main = new MainActivity();
public void getContacts(final Context context) {
final ProgressDialog loading = ProgressDialog.show(context, "Fetching Data", "Please wait...", false, false);
RestAdapter adapter = new RestAdapter.Builder().setEndpoint(ROOT_URL).build();
ContactsAPI api = adapter.create(ContactsAPI.class);
api.getContacts(new Callback<Contacts>() {
#Override
public void success(Contacts contacts, Response response) {
loading.dismiss();
MainActivity update = new MainActivity();
List<Contact> contactList = contacts.getContacts();
item = new String[contactList.size()];
int size = contactList.size();
for (int i = 0; i < contactList.size(); i++) {
item[i] = contactList.get(i).getName();
}
update.getter(item, size);
}
#Override
public void failure(RetrofitError error) {
Toast.makeText(context, "Error Occured", Toast.LENGTH_LONG).show();
}
});
}
But I get an error on my response in the main activity here is my log
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
at android.content.ContextWrapper.getResources(ContextWrapper.java:87)
at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:81)
at android.support.v7.app.AppCompatActivity.getResources(AppCompatActivity.java:542)
at android.widget.Toast.<init>(Toast.java:102)
at android.widget.Toast.makeText(Toast.java:259)
at com.exist.kelvs.retrofit2.MainActivity.getter(MainActivity.java:55)
at com.exist.kelvs.retrofit2.RetrofitHandler$1.success(RetrofitHandler.java:41)
at com.exist.kelvs.retrofit2.RetrofitHandler$1.success(RetrofitHandler.java:28)
at retrofit.CallbackRunnable$1.run(CallbackRunnable.java:45)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I maked sure that the handler item where not null tested it with toast but when i pass it to getter it gives me the error where did i do wrong? :(
MainActivity update = new MainActivity();
Never instantiate activities with new. They are not initialized to be useful.
Instead, you can pass your activity as a reference where needed. Change
public void getContacts(final Context context)
to e.g.
public void getContacts(final MainActivity mainActivity)
and use mainActivity where you need an activity Context (such as with Dialogs) and when you need to invoke a method on MainActivity.
Note that generally passing activity references to async operations can be prone to significant memory leaks, and you need to take activity lifecycle into account - the activity might not be active when the async operation finishes.
try to delete the toast in your main activity or replace Mainactivity.this to getApplicationContext() .
from :
Toast.makeText(MainActivity.this, itemer[0], Toast.LENGTH_SHORT).show();
to :
Toast.makeText(getApplicationContext(), itemer[0], Toast.LENGTH_SHORT).show();