Null object reference onReceive BroadcastReceiver - java

I'm using two activities, the main one, and the camera one. In the mainActivity i call startActivity(new Intent(this, CameraActivity));
Now, when camera activity starts, the onCreate() is:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_preview);
View myView= (View) findViewById(R.id.camera_previeww);
myView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
cameraID= Camera.CameraInfo.CAMERA_FACING_FRONT;
mCamera=openCamera(cameraID);
mCamera.startPreview();
IntentFilter filter = new IntentFilter();
filter.addAction(Tabbed.BROADCAST_ACTION_TABBED);
LocalBroadcastManager bm = LocalBroadcastManager.getInstance(this);
bm.registerReceiver(mBroadcastReceiver, filter);
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) this.findViewById(R.id.camera_previeww);
preview.addView(mPreview);
}
The openCamera(int cameraID) method is:
public Camera openCamera(int cameraIDD){
Camera c=null;
try{
c=Camera.open(cameraIDD);
}catch (Exception e){
Log.d("Camera Activity", e.getMessage());
}
return c;
}
Also I'm using a BroadcastReceiver like:
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
byte [] data=new byte[3];
if (intent.getAction().equals(Tabbed.BROADCAST_ACTION_TABBED)) {
data = intent.getByteArrayExtra(Tabbed.EXTRA_PARAM_BYTE);
}
if (data[FINGER]==MIDDLE_FINGER && data[TYPE]==SINGLE_TAP){
//switchCamera();
//releaseCamera();
//mCamera=Camera.open();
}
else if (data[FINGER]==MIDDLE_FINGER && data[TYPE]==DOUBLE_TAP){
// HAVE TO GO BACK
kill_activity();
}
else if (data[FINGER]==INDEX_FINGER && data[TYPE]==SINGLE_TAP){
mCamera.takePicture(null, null, mPicture);
}
// kill activity
}
};
And some other methods:
#Override
protected void onPause() {
super.onPause();
//releaseCamera(); // release the camera immediately on pause event
}
private void releaseCamera(){
if (mCamera != null){
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
void kill_activity()
{
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
releaseCamera();
finish();
}
Here is the crash:
FATAL EXCEPTION: main
Process: com.etu.goglove, PID: 6008
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.Camera.takePicture(android.hardware.Camera$ShutterCallback, android.hardware.Camera$PictureCallback, android.hardware.Camera$PictureCallback)' on a null object reference
at com.etu.goglove.CameraActivity$2.onReceive(CameraActivity.java:155)
at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:297)
at android.support.v4.content.LocalBroadcastManager.access$000(LocalBroadcastManager.java:46)
at android.support.v4.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:116)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
With all this, I'm trying to take a photo when I receive broadcast intents. So, after my activity has started, I open mCamera and when I receive an intent I make the photo or I get back. At the first time, i can take the photo and then I finish my activity. If i try to restart cameraActivity from the mainActivity, calling startActivity(intent),in the onCreate() camera is open and it is not null (checked with the debugger), but this time, when I get in the onReceive() method, mCamera is always null, so I get a null object reference on mCamera!(when I'm trying to do mCamera.takePicture()) don't know how ...
Thanks!

private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
byte [] data=new byte[3];
if (intent!=null && intent.getAction().equals(Tabbed.BROADCAST_ACTION_TABBED)) {
data = intent.getByteArrayExtra(Tabbed.EXTRA_PARAM_BYTE);
if (data[FINGER]==MIDDLE_FINGER && data[TYPE]==SINGLE_TAP){
//switchCamera();
//releaseCamera();
//mCamera=Camera.open();
}
else if (data[FINGER]==MIDDLE_FINGER && data[TYPE]==DOUBLE_TAP){
// HAVE TO GO BACK
kill_activity();
}
else if (data[FINGER]==INDEX_FINGER && data[TYPE]==SINGLE_TAP){
mCamera.takePicture(null, null, mPicture);
}
}
// kill activity
}
};

Related

Check if nfc tag is near by

I want my phone to detect if there is a nfc tag near by (near the surface of it)
The following code has no errors but as soon as i run the app, it crashes. It would be very helpful if someone of you can look through my code and check if there is something i dont see. Down bellow is the runtimeerror.
public class AccessControlActivity extends AppCompatActivity {
NfcAdapter nfcAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_access_control);
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
// Checks if there is NFC function
if(nfcAdapter != null && nfcAdapter.isEnabled()) {
//Toast.makeText(this, "NFC works", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(this, "NFC is not available!", Toast.LENGTH_SHORT).show();
//finish();
}
}
#Override
protected void onNewIntent(Intent intent) {
Toast.makeText(this, "NFC intent received", Toast.LENGTH_LONG).show();
super.onNewIntent(intent);
}
#Override
protected void onResume() {
Intent intent = new Intent(this, AccessControlActivity.class);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
IntentFilter[] intentFilters = new IntentFilter[]{};
nfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFilters, null);
super.onResume();
}
#Override
protected void onPause() {
nfcAdapter.disableForegroundDispatch(this);
super.onPause();
}
}
The runtimeerror looks like this:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.nfc.netvision, PID: 5484
java.lang.RuntimeException: Unable to resume activity {com.nfc.netvision/com.nfc.netvision.AccessControlActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.nfc.NfcAdapter.enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], java.lang.String[][])' on a null object reference
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4341)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4373)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2043)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7464)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:955)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.nfc.NfcAdapter.enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], java.lang.String[][])' on a null object reference
at com.nfc.netvision.AccessControlActivity.onResume(AccessControlActivity.java:116)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1456)
at android.app.Activity.performResume(Activity.java:8125)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4331)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4373) 
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52) 
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2043) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:216) 
at android.app.ActivityThread.main(ActivityThread.java:7464) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:955) 
I/Process: Sending signal. PID: 5484 SIG: 9
So you check that the nfcAdapter != null in onCreate and just show a toast, your app will then blindly go and try and use a possibly null adapter in onResume.
This would explain the Attempt to invoke virtual method on a null object reference in onResume as the variable nfcAdapter is probably null in onResume
You should check for null again in onResume
Also your Intent filters don't look right as well, they code either cause no Intents to be sent to you or the opposite cause all including non NFC Intents to be sent to you.
More normal code to get called when any type of tag is presented would be.
#Override
protected void onResume() {
super.onResume();
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
IntentFilter ndefDetected = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
ndefDetected.addDataType("*/*");
} catch (IntentFilter.MalformedMimeTypeException e) {}
IntentFilter techDetected = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
IntentFilter[] nfcIntentFilter = new IntentFilter[]{ndefDetected,techDetected,tagDetected};
PendingIntent pendingIntent = PendingIntent.getActivity(
this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
if(nfcAdapter!= null)
nfcAdapter.enableForegroundDispatch(this, pendingIntent, nfcIntentFilter, null);
}
#Override
protected void onPause() {
super.onPause();
if(nfcAdapter!= null)
nfcAdapter.disableForegroundDispatch(this);
}

How to start new activity on nfc tag discovery?

I am writing a code which should return NFC tag value on the next activity ( page ) when NFC get detected during scan. What happens here is that when I launch the app for the first time it the first page shows for a fraction of a second and moves to second page directly ( activity ).
Here is the piece of code for the first activity ( which is just for asking user to tap to scan )
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
askPermissions();
mtxtViewNfcContent = (TextView) findViewById(R.id.text);
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Toast.makeText(this, "No NFC", Toast.LENGTH_SHORT).show();
finish();
return;
}
else {
Intent in = new Intent(Main2Activity.this, MainActivity.class);
startActivity(in);
}
What I want is the the to show the first page at launch and when user tap to nfc scan, show the output on the next page ( MainActivity).
PS : I am new to android, please excuse with my codes.
what are you doing until now is to exit the app when the device doesnot support nfc or to start another activity when the device supports nfc.
you are actually not listening at all to any tag.
here you have two possibilities:
first : read an nfc tag in the first activity and then creat a new intent with and put the result of tag reading as extra bundel.
two : listen to tag existance in the first activity and then send the tag to second one and read it in the second activity.
I would prefer the first secinario.
on firstActivity:
public class MainActivity extends AppCompatActivity {
private PendingIntent pendingIntent;
private IntentFilter[] writeTagFilters;
private NfcAdapter nfcAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.AppTheme);
setContentView(R.layout.activity_main);
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Toast.makeText(this, "No NFC", Toast.LENGTH_SHORT).show();
finish();
return;
}
setForeground();
}
private void setForeground() {
pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
writeTagFilters = new IntentFilter[]{tagDetected};
}
#Override
protected void onResume() {
super.onResume();
if (nfcAdapter != null) {
nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
}
processNfcTag(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
#Override
protected void onPause() {
super.onPause();
if (nfcAdapter != null) {
nfcAdapter.disableForegroundDispatch(this);
}
}
private void processNfcTag(Intent intent) {
//TODO: here you should to check if this intent is an NFC Intent, in case it is an nfc intent you could read it according of tag tech you have
// for example MifareUltralight.
MifareUltralight mfu = MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
try {
mfu.connect();
byte [] bytes = mfu.readPages(pageNumber);
mfu.close();
} catch (IOException e) {
e.printStackTrace();
}
// then you could get this bytes and send it to the other activity
}
please check this link to know how to send data between activities.
p.s: you should to check the code I have wrote it quickly.
You can use intent.putExtra (key,value) while calling the intent and use bundle on the result activity to fetch the variable data
use this while calling the intent
`Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("some_key", value);
intent.putExtra("some_other_key", "a value");
startActivity(intent);`
use this on result activity
`Bundle bundle = getIntent().getExtras();
int valueText = bundle.getInt("some_key");
String valueString = bundle.getString("some_other_key");
TextView textone =(TextView)findVeiwById(R.id.textone);
textone.setText(valueText);
TextView stringTextView = (TextView)FindViewById(R.id.stringTextView)
stringTextView.setText(valueString)`

Trying to show ad when sound played 10 times, ad doesn't show & no sound after 5th time played

I'm trying to show ad When user presses on sound card 10 times but when I press on sound card 10th time no ad is shown and no sound plays anymore until I press stop button after which sound plays again until I press it 10 times again
Part of my main activity:
..
MobileAds.initialize(this,
"ca-app-pub-2470537820941001~1050614569");
mInterstitialAd = new InterstitialAd(this);
mInterstitialAd.setAdUnitId("ca-app-pub-3940256099942544/1033173712");
mInterstitialAd.loadAd(new AdRequest.Builder().build());
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mPowerSaverChangeReceiver);
if (mSoundPlayer != null) {
mSoundPlayer.release();
mSoundPlayer = null;
}
}
#Override
public void onResume() {
super.onResume();
if (mSoundPlayer == null) mSoundPlayer = new SoundPlayer(MainActivity.this);
}
#Override
public void onPause() {
super.onPause();
if (mSoundPlayer != null) {
mSoundPlayer.release();
mSoundPlayer = null;
}
}
this is my sound player class:
class SoundPlayer {
private MediaPlayer mPlayer;
private Context mContext;
private static final String TAG = "SoundPlayer";
private int counter = 0;
private void playSound(Sound sound) {
int resource = sound.getResourceId();
if (counter == 5) {
if (mInterstitialAd.isLoaded()) {
mInterstitialAd.show();
} else {
Log.d("TAG", "The interstitial wasn't loaded yet.");
}
} else {
counter++;
}
if (mPlayer != null) {
if (mPlayer.isPlaying())
mPlayer.stop();
mPlayer.reset();
../
The error
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean com.google.android.gms.ads.InterstitialAd.isLoaded()' on a null object reference
at my.app.SoundPlayer.playSound(SoundPlayer.java:38)
at my.app.reactionsounds.SoundPlayer.onEvent(SoundPlayer.java:32)
at java.lang.reflect.Method.invoke(Native Method)
at org.greenrobot.eventbus.EventBus.invokeSubscriber(EventBus.java:507)
at org.greenrobot.eventbus.EventBus.invokeSubscriber(EventBus.java:501)
at org.greenrobot.eventbus.AsyncPoster.run(AsyncPoster.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
You have not initialised interstiial Ad in your sound player class.Your error shows clearly that Interstitial ad is null.
interstitialAd = new InterstitialAd(ReadingPage.this);
interstitialAd.setAdUnitId(getResources().getString(R.string.interstitial1));
interstitialAd.loadAd(new AdRequest.Builder().build());

Android service running but overlay activity flicks and disappears

Background info: I'm trying to create a service. I create it in my main activity. I know the service is running because the notification is showing. So the service doesn't stop at any point.
What i want to happen: when the screen is locked/turned off i want a certain activity to be displayed for when the screen is turned back on.
What is happening: first, When the screen is turned back on the main activity shows and then the activity i want shows over that. I dont want the main activity to show at all when the screen is turned on .
Then i changed a few things: and now the desired activity flickers on the main screen and then vanishes. It seems very unreliable and only comes a few times.
That should be enough info, here is the code so far (specifically onReceive())
public class OverlayService extends Service{
//IN THIS CLASS CHECK WHETHER LOCK BUTTON WAS PRESSED OR IF PHONE WHEN TO SLEEP.. UPON AWAKENING START THE OVERLAY ACTIVITY...
private BroadcastReceiver mReceiver;
private boolean isShowing = false;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private WindowManager windowManager;
WindowManager.LayoutParams params;
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
//Register receiver for determining screen off and if user is present
mReceiver = new OverlayStateReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(mReceiver, filter);
makeNotification();
}
void makeNotification() {
Notification notification = new NotificationCompat.Builder(this)
//TODO change icon
.setSmallIcon(R.drawable.test)
.setContentTitle("App")
.setContentText("service is running...")
.setPriority(Notification.PRIORITY_LOW)
.build();
startForeground(1, notification);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
public class OverlayStateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.i("app", "load view");
showOverlayActivity(context);
}
}
}
private void showOverlayActivity(Context context) {
Intent intent = new Intent(context, OverlayActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
#Override
public void onDestroy() {
//unregister receiver when the service is destroy
if (mReceiver != null) {
unregisterReceiver(mReceiver);
}
//TODO remove view if it is showing and the service is destroy
super.onDestroy();
}
}

Android App Crashes when paused

I have an android activity which displays a live camera preview using a surfaceview. Everything works fine, however when I press the lock button on my phone and then unlock my phone or when a dialog box from another activity (example bluetooth transfer, or incoming call) overlays my camera preview the app crashes. I suspect this is a problem with my onResume() or onPause() activities as I get an error "method called after release()". However, I am unsure how to fix this.
CAMERA ACTIVITY:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_screen);
setStatusBarColor();
Display display = getWindowManager().getDefaultDisplay();
final int height = display.getHeight();
session = new SessionManager(getApplicationContext());
try {
mCamera = Camera.open();//you can use open(int) to use different cameras
} catch (Exception e) {
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
if (mCamera != null) {
mCameraView = new CameraPreview(this, mCamera);//create a SurfaceView to show camera data
FrameLayout camera_view = (FrameLayout) findViewById(R.id.camera_view);
camera_view.addView(mCameraView);//add the SurfaceView to the layout
//rotate preview
mCamera.setDisplayOrientation(90);
//rotate camera
Camera.Parameters p = mCamera.getParameters();
p.setRotation(90);
mCamera.setParameters(p);
}
#Override
protected void onPause() {
super.onPause();
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCameraView.getHolder().removeCallback(mCameraView);
mCamera.release();
}
}
#Override
public void onResume() {
super.onResume();
// Get the Camera instance as the activity achieves full user focus
if (mCamera == null) {
initializeCamera(); // Local method to handle camera initialization
}
}
protected void initializeCamera(){
// Get an instance of Camera Object
try{
mCamera = Camera.open();//you can use open(int) to use different cameras
} catch (Exception e){
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
if(mCamera != null) {
mCameraView = new CameraPreview(this, mCamera);//create a SurfaceView to show camera data
FrameLayout camera_view = (FrameLayout)findViewById(R.id.camera_view);
camera_view.addView(mCameraView);//add the SurfaceView to the layout
}
}
Try adding this line to your onPause():
camera_view.removeView(mCameraView);
onPause(){
...
mCamera.release(); // close mCamera, but not set it to null
//mCamera = null; // you need reset mCamera to trigger init method;
}
onResume(){
...
initializeCamera();// need mCamera == null
}
//If you find other problems.
//Add some codes in the initializeCamera().
{
//mCamera.setPreviewCallback("something");
//mCameraView.getHolder().addCallback(mCameraView);
}
//as onPause do.

Categories

Resources