Android Studio 2.3.3 (LATEST)
Cocos2d-x 3.15.1 (LATEST)
I tested on Debug.
It's my first experience with Cocos2d-x Game Engine, I developed an Android Game using Cocos2d-x, all it's fine but when I tried to show the achievements it shows me an error like this :
java.lang.NullPointerException
at sonar.systems.framework.SonarFrameworkFunctions.showAchievements(SonarFrameworkFunctions.java:432)
at org.cocos2dx.lib.Cocos2dxRenderer.nativeTouchesEnd(Native Method)
at org.cocos2dx.lib.Cocos2dxRenderer.handleActionUp(Cocos2dxRenderer.java:129)
at org.cocos2dx.lib.Cocos2dxGLSurfaceView$10.run(Cocos2dxGLSurfaceView.java:311)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1486)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1263)
My Code when I click to show the achievements :
SonarCocosHelper::GooglePlayServices::showAchievements();
When I want To sign In :
java.lang.NullPointerException
at sonar.systems.framework.SonarFrameworkFunctions.isSignedIn(SonarFrameworkFunctions.java:277)
at org.cocos2dx.lib.Cocos2dxRenderer.nativeRender(Native Method)
at org.cocos2dx.lib.Cocos2dxRenderer.onDrawFrame(Cocos2dxRenderer.java:105)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1557)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1263)
My Code for Sign In :
if(!SonarCocosHelper::GooglePlayServices::isSignedIn())
SonarCocosHelper::GooglePlayServices::signIn();
My Manifest File :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ilyo.test"
android:installLocation="auto">
<supports-screens android:anyDensity="true"
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"/>
<uses-feature android:glEsVersion="0x00020000" />
<!-- Basic permission for Internet and don't allow turn of the screen -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:label="#string/app_name"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="#mipmap/ic_launcher">
<!-- Tell Cocos2dxActivity the name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="MyGame" />
<!-- Required for Google Play Services -->
<meta-data android:name="com.google.android.gms.games.APP_ID"
android:value="#string/app_id" />
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"/>
<activity
android:name="org.cocos2dx.cpp.AppActivity"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Build Gradle File :
Cocos Helper Frameworks Used :
My Google Play Achievement (I removed the ID from this photo):
I searched already for solutions in relationship with Android Studio but the results are very rare, I don't know what is the solution and what this the reason for this error.
Thank you,
I founded a solution but now I guess it's just a dirty fix, first the problem is in the GooglePlayServices.java and exactly in onStart method : Null pointer Exception because mHelper is Null.
#Override
public void onStart()
{
mHelper.onStart((Activity) ctx);
}
Let us a little further why it generates null, so :
1. SonarFrameworkFunctions.java
when we want to call GooglePlayServices constructor from SonarFrameworkFunctions.java :
//GOOGLE PLAY SERVICES
if (SonarFrameworkSettings.USE_GOOGLE_PLAY_GAME_SERVICES)
{
String packageName = "sonar.systems.frameworks.GooglePlayServices.GooglePlayServices";
googlePlayServices = (InstantiateFramework(packageName) != null) ? InstantiateFramework(packageName) : new Framework();
}
2. Method : InstantiateFramework in SonarFrameworkFunctions.java
public static Framework InstantiateFramework(String packageName)
{
Framework tmp = null;
try
{
tmp = (Framework) Class.forName(packageName).getConstructor().newInstance();
tmp.SetActivity(((SonarFrameworkActivity) app));
} catch (InstantiationException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e)
{
e.printStackTrace();
Log.e("Class not found", "class doesn't exist or bad package name " + packageName);
}
return tmp;
}
The constructor is empty so there is only a method called onCreate that instantiate and prepare the mHelper to access to all functionalities of Google Play Services.
Solution (Dirty Fix):
GooglePlayServices.java
public GooglePlayServices()
{
mHelper=getGameHelper();
mHelper.setup(this);
}
Related
I'm writing an acessibility service in Android which relies on getting the view id of the currently selected view, however on some devices (Nexus 6P 6.0.1, Samsung Galaxy S6 edge+ 5 + 6.0.1) I get no view id through and on others (HTC One M8 5.0.1) it comes through fine. Because it works fine on some devices, I'm sure there's not a problem with my code, however I've posted a minimal test case below.
Can anyone can help me get my service reporting ids across all devices?
The A11y service
public class ViewIdLoggingAccessibilityService extends AccessibilityService {
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
AccessibilityNodeInfo source = event.getSource();
if (source == null) {
Log.d("onAccessibilityEvent", "source was null for: " + event);
} else {
String viewIdResourceName = source.getViewIdResourceName();
Log.d("onAccessibilityEvent", "viewid: " + viewIdResourceName);
}
}
#Override
public void onInterrupt() {
Log.d("!# onInterrupt", "called");
}
}
The AndroidManifest.xml
<manifest package="com.example.a11yservice"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
>
<service
android:name=".ViewIdLoggingAccessibilityService"
android:label="#string/view_id_logging_service_label"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
>
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/serviceconfig"
/>
</service>
</application>
</manifest>
serviceconfig.xml
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagReportViewIds"
android:canRetrieveWindowContent="true"
android:notificationTimeout="100" />
It's known issue and was posted to AOSP issue tracker some time ago. You can check status of issue here: "Accessibility Issue: flagReportViewIds has no effect on real devices in Android M".
Unfortunately issue exists even on latest Android 7.0 but I found simple workaround. You can call refresh() method on AccessibilityNodeInfo object to refresh it and collect all missed data including id.
Something like that:
public void onAccessibilityEvent(AccessibilityEvent event) {
AccessibilityNodeInfo ani = event.getSource();
if (ani != null) {
ani.refresh(); // to fix issue with viewIdResName = null on Android 6+
}
}
I found that if the viewId isn't available, querying the focused element seems to work:
AccessibilityNodeInfo source = findFocus(AccessibilityNodeInfo.FOCUS_INPUT);
viewIdResourceName = source.getViewIdResourceName();
returns the correct view id
I am using reflection to called a method in my NumberPicker, here is my code:
try {
// reflection call for
method = numberPicker.getClass().getDeclaredMethod("changeValueByOne", boolean.class);
method.setAccessible(true);
method.invoke(numberPicker, increment);
//TODO: Before finalizing should there be back-up code in one of these cases?
} catch (final NoSuchMethodException e) {
e.printStackTrace();
} catch (final IllegalArgumentException e) {
e.printStackTrace();
} catch (final IllegalAccessException e) {
e.printStackTrace();
} catch (final InvocationTargetException e) {
e.printStackTrace();
}
In case the changeValueByOne method does not exist in the NumberPicker (I'm under the impression it doesn't exist in older APIs) can I put some code like numberPicker.setValue(numberPicker.getValue() - 1); and remove the e.printStackTrace(); from the NoSuchMethodException catch block to make it handle this gracefully?
In other words, instead of using the changeValueByOne method if it doesn't exist it will default to the setValue. I'd rather use changeValueByOne if it is available because it plays the rotation animation of the NumberPicker where I don't believe setValue does.
Here is my AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.skytbest.intervaltrainer.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
and my build.gradle
apply plugin: 'android'
android {
compileSdkVersion 19
buildToolsVersion "19.0.3"
defaultConfig {
minSdkVersion 14
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard- rules.txt'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
NumberPicker requires an API >=11 and your minimum required is greater than that. Therefore, you don't get a compile error for NumberPicker because devices with API < 11 can't install it. So you shouldn't need to worry.
If you wanted to change that minimum API then you would do something like
if (android.os.Build.VERSION.SDK_INT<= android.os.Build.VERSION_CODES.HONEYCOMB)
{
// use this method
}
else
{
// use this method
}
I have a little app that I made that have worked for months, but suddenly I get a
android.os.NetworkOnMainThreadException
I havent changed any code, this is the line that crashes
try {
endPoint = InetAddress.getByName(target.getToIp());
port = target.getPort();
socket = new DatagramSocket();
}
catch(Exception e) {
}
Note that I'm not sending anything I'm just creating the instances, it breaks already on the InetAddress row.
It wored as late as last night, all I have done on the phone is run update on Google play, it updated to latest version of Google Maps, but that cant have anything todo with it?
It works in the emulator, only my HTC One X that breaks
Full code here
https://github.com/AndersMalmgren/FreePIE/tree/master/Lib/Android/FreePIE%20Android%20IMU
edit:
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.freepie.android.imu"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Tried to move the problem code to the thread instead, now it wont break, but the socket is set to null.
running = true;
worker = new Thread(new Runnable() {
public void run(){
try {
endPoint = InetAddress.getByName(target.getToIp());
port = target.getPort();
socket = new DatagramSocket();
}
catch(Exception e) {
Exception err = e;
}
while(running) {
try {
sync.await();
} catch(Exception e) {}
Send();
}
try {
socket.disconnect();
}
catch(Exception e) {}
}
});
worker.start();
update:
Solution was to add some failback if user types a DNS instead of a IP
https://github.com/AndersMalmgren/FreePIE/commit/e8017e02a7893d9df41e4ed67a037f016b6a7d39
You will get NetworkOnMainThreadException on Android 4.0+ by default if you attempt to do network I/O on the main application thread. getByName() does a DNS lookup if you provide a domain name (instead of dotted-IP notation), and that will trigger NetworkOnMainThreadException.
You must put your code in AsyncTask like this:
new AsyncTask<Void,Void,Void>(){
doInBackground(){
endPoint = InetAddress.getByName(target.getToIp());
port = target.getPort();
socket = new DatagramSocket();
}
}.execute();
Note this code is not a working one, please read more about AsyncTasks here
Use Network on main thread is not allowed from the Android 4.0. If you run the code at Android 2.3 or other, it will not throw any exception.
I'm a begginer android programmer and I have a problem with the camera. What I'm trying to do is to get a preview on the camera. The problem is, Camera.open() always returns null. The code goes like this:
CameraPreview.java
public class CameraPreview extends Activity implements SurfaceHolder.Callback
{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_preview);
SurfaceHolder holder;
SurfaceView preview = (SurfaceView) findViewById(R.id.surface1);
holder = preview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Camera camera = Camera.open();
if(camera!=null)
{
try
{
camera.setPreviewDisplay(holder);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
camera.startPreview();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.paparazzi"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".CameraPreview"> </activity>
</application>
emulator config:
hw.lcd.density=240
hw.cpu.arch=arm
skin.name=WVGA800
sdcard.size=64M
abi.type=armeabi-v7a
hw.camera.back=emulated
image.sysdir.1=system-images\android-16\armeabi-v7a\
hw.gpu.enabled=yes
hw.camera.front=emulated
skin.path=platforms\android-16\skins\WVGA800
hw.cpu.model=cortex-a8
vm.heapSize=48
hw.ramSize=512
I use eclipse with android plugin and the newest sdk. I would really appreciate any suggestions.
before API version 14, the emulator doesn't support camera simulation. Even after the update the documentation doesn't really talk about it.
there is a workaround to this - check it out here.
http://www.tomgibara.com/android/camera-source
You haven't given following feature in the Manifest. Give it and run it again.
<uses-feature android:name="android.hardware.camera" android:required="true"/>
If still getting the Exception, put your Logcat output here.
Updated:
private static Camera camera;
public static Camera getCameraInstance(){
try {
camera = Camera.open();
}
catch (Exception e){
// Camera is not available (in use or does not exist)
Toast.makeText(context, "Camera is occupied by another program" , Toast.LENGTH_SHORT).show();
}
return camera; // returns null if camera is unavailable
}
Use above code in your's and try to extract the exception if it getting again and again.
Call
CameraPreview.getCameraInstance();
inside your surfaceCreated method
Thanks #alextsc to remind me about the uses-feature
using android’s inbuilt camera app, launching the camera and taking the picture can done with very few lines of code using the power of Intent
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
Using the guide on JSoup's website I wrote the following code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
Document doc = Jsoup.connect("http://google.com").get();
Elements links = doc.getElementsByTag("a");
for(Element ele : links){
Log.i("Menu", ele.text());
}
} catch (IOException e) {
}
setContentView(R.layout.main);
}
I added the internet permission in my manifest file but it keeps throwing an IOException!
I tested your code and it should work fine... I would imagine your permission was put in the wrong spot. It goes BEFORE your application definition in your manifest:
here are the first few lines of my manifest that runs your code:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application android:icon="#drawable/icon" android:label="#string/app_name">