I have a widget with a button that enables the camera service.
It works quite well but after some time (maybe with the home screen app exit) it loses the status (bein on or off).
I have a crash with a NullPointerException from, I believe, Context.CAMERA_SERVICE. It is really hard to reproduce and so far I haven't found the sequence that leads to the crash.
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
at android.content.ContextWrapper.getSystemService(ContextWrapper.java:714)
at com.widget.tst.Widget.CallbackWidgetService.isCameraInUse(CallbackWidgetService.java:163)
at com.widget.tst.Widget.CallbackWidgetService.startCameraInUse(CallbackWidgetService.java:242)
//** button click-->
at com.widget.tst.Widget.CameraWidgetReceiver.updateWidgetButton(CameraWidgetReceiver.java:55)
at com.widget.tst.Widget.CameraWidgetReceiver.onReceive(CameraWidgetReceiver.java:32)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:3632)
at android.app.ActivityThread.-wrap18(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1975)
at android.os.Handler.dispatchMessage(Handler.java:109)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7367)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:469)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:963)
How can Context.CAMERA_SERVICE be null?
private void isCameraInUse(){
if(context == null) return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
--> line 163 mCameraManager = (CameraManager)getSystemService(Context.CAMERA_SERVICE);
}
else{
Toast.makeText(context, "You need to run Android version "+
Build.VERSION_CODES.M+" or above",
Toast.LENGTH_SHORT).show();
return;
}
It looks like somewhere inside your current class (this) it's own context gets nulled, and that's why you get your NPE.
But since you have a 100% non-null context in a variable (if(context == null) return;), why don;t you use it instead of this's own context?:
mCameraManager = (CameraManager)context.getSystemService(Context.CAMERA_SERVICE);
Related
I've looked at multiple questions, haven't found solution yet.
I've youtube player SDK imported and a webview. One is in Live_fragment and another Article_Fragment.
This is the onBackPressed code that causes the crash:
#Override
override fun onBackPressed() {
if (webViewE.canGoBack() || youTubePlayer.isFullScreen()) {
youTubePlayer.exitFullScreen()
webViewE.goBack()
} else {
super.onBackPressed()
}
}
Now, webViewE.canGoBack and youTubePlayer.isFullScreen() alone works fine (if I only put in one of them), but if they're both together in the function, I get:
Attempt to invoke virtual method 'boolean android.webkit.WebView.canGoBack()' on a null object reference" and app crashes
This means your WebView variable is null at the time of the onBackPressed invocation. You need to make sure you properly initialise it and ensure it hasn't been nullified somehow up until possible calls to onBackPressed. If you want to axe this condition in the event that the WebView may be null, you can just add a check for null alongside your current check, i.e.:
#Override
override fun onBackPressed() {
if ((webViewE != null && webViewE.canGoBack()) || youTubePlayer.isFullScreen()) {
youTubePlayer.exitFullScreen()
webViewE.goBack()
} else {
super.onBackPressed()
}
}
Starting Android Pie (API 28), Google isn't allowing using a single WebView instance in 2 different processes.
Documentation: https://developer.android.com/reference/android/webkit/WebView.html#setDataDirectorySuffix(java.lang.String)
As required, I called WebView.setDataDirectorySuffix("dir_name_no_separator") but unfortunately, I get an exception.
I tried to call this method inside the 2nd process Service onCreate().
java.lang.RuntimeException: Unable to create service com.myapp.service.MyService: java.lang.IllegalStateException: Can't set data directory suffix: WebView already initialized
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3544)
at android.app.ActivityThread.access$1300(ActivityThread.java:199)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1666)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.IllegalStateException: Can't set data directory suffix: WebView already initialized
at android.webkit.WebViewFactory.setDataDirectorySuffix(WebViewFactory.java:136)
at android.webkit.WebView.setDataDirectorySuffix(WebView.java:2165)
at com.myapp.service.MyService.onCreate(MyService.java:134)
I couldn't find any reason for that exception. I didn't call this method twice nor I called it in my main process. Any ideas?
Solved.
My project hosts AdMob ads and I call the MobileAds.initialize() method inside my Application class onCreate(). The ads initializer loads a WebView which is now forbidden to do in a new process before you call the WebView.setDataDirectorySuffix("dir_name_no_separator") method.
When the second process is created, it also goes through the same application create flow, meaning it calls the same onCreate() inside the Application class, which calls the MobileAds.initialize() that tries to create a new WebView instance and by that causes the crash.
IllegalStateException: Can't set data directory suffix: WebView already initialized
How I solved this?
I get the process name using the below method and check if it's my main process - call the MobileAds.initialize() method and if it's my second process, call the
WebView.setDataDirectorySuffix("dir_name_no_separator") method.
Get process name:
public static String getProcessName(Context context) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
if (processInfo.pid == android.os.Process.myPid()) {
return processInfo.processName;
}
}
return null;
}
Application class onCreate():
if (!Utils.getProcessName(this).equals("YOUR_SECOND_PROCESS_NAME")) {
MobileAds.initialize(this);
} else {
WebView.setDataDirectorySuffix("dir_name_no_separator")
}
To summarize the fix with all the improvements, this is the code in Kotlin:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (packageName != Application.getProcessName()) {
WebView.setDataDirectorySuffix(Application.getProcessName())
}
}
Add it to your Application class to onCreate() method.
Note this is will only fix problem with maximum 2 processes. If your app is using more, you have to provide different WebView suffix for each of them.
when error due to ads, then in application class
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val process = getProcessName()
if (packageName != process) WebView.setDataDirectorySuffix(process)
}
MobileAds.initialize(this)
AudienceNetworkAds.initialize(this)
} catch (e: Error) {
Timber.e(e)
} catch (e: Exception) {
Timber.e(e)
}
I have a music player application and untill now, it was working smoothly.
So, i learnt about Android Focus from android documentation and i thought i would try this on my app for learning purposes.
App: minimum api level :16; Maximum:26;
I basically implemented the AudioManager.OnAudioFocusChangeListener in my service class.
In it i included this code:
if(Build.VERSION.SDK_INT>=26){
mAudioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(mAudioAttributes)
.setAcceptsDelayedFocusGain(true)
.setOnAudioFocusChangeListener(this)
.build();
int res = mAudioManager.requestAudioFocus(mAudioFocusRequest);
synchronized(mFocusLock) {
if (res == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
mPlaybackNowAuthorized = false;
} else if (res == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mPlaybackNowAuthorized = true;
playSong();
} else if (res == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
mPlaybackDelayed = true;
mPlaybackNowAuthorized = false;
}
}
} else if(Build.VERSION.SDK_INT<26){
int result = 0;
if (mAudioManager != null) {
result = mAudioManager.requestAudioFocus(this,AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN);
}
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mPlaybackNowAuthorized = true;
playSong();
}
}
My onAudioFocusChange(int focusChange) looks something like this:
if(Build.VERSION.SDK_INT<26){
//<26 code
}else {
//26 and above api level
}
I tried implementing audiofocus in my application and this is how i did it. The issue is when i try to run my app now , it gives me this error
unable to create a service
What's the problem with it? i think i read the documentation clearly.
Am i missing out something?
Update:
Removing the below code does make it work
else if(Build.VERSION.SDK_INT<26){
int result = 0;
if (mAudioManager != null) {
result = mAudioManager.requestAudioFocus(this,AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN);
}
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mPlaybackNowAuthorized = true;
playSong();
}
Stacktrace:
12-18 16:27:47.740 30183-30183/com.example.tilak.imusicplay E/AndroidRuntime:
12-18 16:27:47.740 30183-30183/com.example.tilak.imusicplay E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.tilak.imusicplay, PID: 30183
java.lang.RuntimeException: Unable to create service com.example.tilak.imusicplay.MusicService: java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.List.get(int)' on a null object reference
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2920)
at android.app.ActivityThread.access$2000(ActivityThread.java:153)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1458)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:5529)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.List.get(int)' on a null object reference
at com.example.tilak.imusicplay.MusicService.playSong(MusicService.java:239)
at com.example.tilak.imusicplay.MusicService.initMusicPlayer(MusicService.java:115)
at com.example.tilak.imusicplay.MusicService.onCreate(MusicService.java:66)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2910)
at android.app.ActivityThread.access$2000(ActivityThread.java:153)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1458)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:5529)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
12-18 16:27:47.742 30183-30183/com.example.tilak.imusicplay E/MQSEventManagerDelegate: failed to get MQSService.
Whole Class Code
look your Error Msg!this is a NullPointerException. List is a null object! check you code
java.lang.RuntimeException: Unable to create service com.example.tilak.imusicplay.MusicService: java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.List.get(int)' on a null object
The problem is that your application does not initialise songs. (Sure, there is a setSongs method, but you don't call it!)
Solution: add code to initialize songs in the appropriate place. That will fix this error ...
I strongly advise you to read the Question and Answers for:
What is a NullPointerException, and how do I fix it?
I am trying to use sinch an i am having erros i dont know why an i seem to have set it well.
and it is pointing me to this part of the code which
public void that(final String name) {
call.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if ((getSinchServiceInterface() == null) || (!getSinchServiceInterface().isStarted())) {
getSinchServiceInterface().startClient(name);
}
}
});
}
the "getSinchServiceInterface().startClient(name);"
this is my error
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.obi.thinker.logins.call.SinchService$SinchServiceInterface.startClient(java.lang.String)' on a null object reference
at com.obi.thinker.logins.tabs.Chatting$caller$1.onClick(Chatting.java:386)
at android.view.View.performClick(View.java:5265)
at android.view.View$PerformClick.run(View.java:21534)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5683)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
I dont understand
if ((getSinchServiceInterface() != null && !getSinchServiceInterface().isStarted())) {
getSinchServiceInterface().startClient(name);
}
the callstack says:
getSinchServiceInterface() is null
And would suggest to read this:
https://stackoverflow.com/a/41477703/1979882
I was facing this issue for weeks. I literally rewrote my SinchService from scratch, removed Sinch altogether and tried starting fresh but all to no avail. It turns out I was simply initialising my call too early.
I recommend you move the code block:
if ((getSinchServiceInterface() != null || !getSinchServiceInterface().isStarted())) {
getSinchServiceInterface().startClient(name);
}
I moved mine to the very end of my onResume method and it seems to all work fine now. The reason this doesn't continually keep starting the client is because we are adding the 'if' statement to make sure it isn't already initialised.
If you find that the issue is still thrown, which was the case for me at one point, try calling it at the very end of the launch of your activity. It simply comes down to being called before your BaseActivity has a chance to initialise mSinchServiceInterface
I have been working to resolve this problem for the last three days and cannot get it working. These are the steps of my app:
Open file browser to select and audio file
Audio file is selected
Selected audio file is added to the database
from a list of items the added file is selected
a play button is pressed to play the sound file
at this point the sound file will play, however if I close the app then open it again and attempt to play the same sound file the app crashes with the following error:
FATAL EXCEPTION: main
Process: com.arcitech.developer.ultimatesoundboard, PID: 22967
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.media.MediaPlayer.start()' on a null object reference
at com.arcitech.developer.ultimatesoundboard.activities.ItemDetailFragment$4.onClick(ItemDetailFragment.java:153)
at android.view.View.performClick(View.java:5156)
at android.view.View$PerformClick.run(View.java:20755)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5835)
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:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
the filepath(uri) I am saving to the database is:
Content://com.android.providers.media.documents/document/audio%3A15790
and the code I am using is located in the onCreateView of a fragment:
MediaPlayer m;
playSound.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (m != null) {
m.stop();
m.release();
m = null;
}
m = MediaPlayer.create(getActivity(), Uri.parse(mItem.filePath));
m.start();
m.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer m) {
countdownTimerHandler.removeCallbacks(countdownTimerRunnable);
}
});
}
});
According to the doc for MediaPlayer.create(), it can return null if for some reason MediaPlayer cannot be created. You should be checking the return value for null every time unless you are very confident that it will not return null (but even then, do it for safety).
You may also want to check the log at the time create() is called to see if Android is leaving any clues as to why creation failed.