I'm developing a multiplayer game with libGDX and my problem is that the code that works on desktop. It causes a crash on android. When I start the server's thread on android, the following error occurs:
FATAL EXCEPTION: YellowServer
com.badlogic.gdx.utils.GdxRuntimeException: Cannot create a server socket at port 4444.
at com.badlogic.gdx.net.NetJavaServerSocketImpl.<init>(NetJavaServerSocketImpl.java:63)
at com.badlogic.gdx.backends.android.AndroidNet.newServerSocket(AndroidNet.java:60)
at hu.hundevelopers.yellow.net.NetServer.<init>(NetServer.java:41)
at hu.hundevelopers.yellow.YellowServer.create(YellowServer.java:32)
at hu.hundevelopers.yellow.YellowServer.run(YellowServer.java:61)
Caused by: java.net.SocketException: socket failed: EACCES (Permission denied)
at libcore.io.IoBridge.socket(IoBridge.java:583)
at java.net.PlainSocketImpl.create(PlainSocketImpl.java:201)
at java.net.PlainServerSocketImpl.create(PlainServerSocketImpl.java:38)
at java.net.ServerSocket.<init>(ServerSocket.java:59)
at com.badlogic.gdx.net.NetJavaServerSocketImpl.<init>(NetJavaServerSocketImpl.java:46)
... 4 more
Caused by: libcore.io.ErrnoException: socket failed: EACCES (Permission denied)
at libcore.io.Posix.socket(Native Method)
at libcore.io.BlockGuardOs.socket(BlockGuardOs.java:181)
at libcore.io.IoBridge.socket(IoBridge.java:568)
... 8 more
It looks like that I forgot the permissions from the manifest xml file but they're there:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
NetServer.java:
package hu.hundevelopers.yellow.net;
import java.util.ArrayList;
import java.util.List;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Net;
import com.badlogic.gdx.net.ServerSocket;
import hu.hundevelopers.yellow.YellowServer;
import hu.hundevelopers.yellow.net.packet.Packet;
public class NetServer {
public class ListenThread extends Thread {
public NetServer net;
public ListenThread(NetServer net) {
super("ListenThread");
this.net = net;
}
#Override
public void run() {
try {
while (this.net.server.game.isHosting) {
NetServerClient client = new NetServerClient(this.net, this.net.socket.accept(this.net.server.game.socketHints));
this.net.clients.add(client);
}
} catch (Exception e) {
}
}
}
public YellowServer server;
public ServerSocket socket;
public List<NetServerClient> clients;
public NetServer(YellowServer server, int port) {
this.server = server;
this.socket = Gdx.net.newServerSocket(Net.Protocol.TCP, port, this.server.game.serverSocketHints);
this.clients = new ArrayList<NetServerClient>();
new ListenThread(this).start();
}
public void sendToAll(Packet pkt) {
for (NetServerClient client : this.clients)
client.send(pkt);
}
public void sendToAllAndDispose(Packet pkt) {
this.sendToAll(pkt);
pkt.dispose();
}
public void update() {
for (int i = 0; i < this.clients.size(); i++) {
this.clients.get(i).update();
if (!this.clients.get(i).connection) {
this.clients.get(i).dispose();
this.clients.remove(i--);
}
}
}
public void dispose() {
for(NetServerClient client : this.clients)
client.dispose();
this.socket.dispose();
}
}
Edit:
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="hu.hundevelopers.yellow.android"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/GdxTheme" >
<activity
android:name="hu.hundevelopers.yellow.android.AndroidLauncher"
android:label="#string/app_name"
android:screenOrientation="landscape"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
AndroidLauncher.java:
package hu.hundevelopers.yellow.android;
import android.content.pm.PackageManager;
import android.os.Bundle;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import hu.hundevelopers.yellow.Yellow;
public class AndroidLauncher extends AndroidApplication {
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
initialize(new Yellow(new String[]{}), config);
if(getContext().checkCallingOrSelfPermission("android.permission.INTERNET") == PackageManager.PERMISSION_GRANTED) {
Gdx.app.log("INFO", "PERMISSION GRANTED");
} else {
Gdx.app.log("ERROR", "PERMISSION DENIED");
}
}
}
I solved the problem. I changed the minimum required android version from 8 to 10 and now everything works.
The exception indicates its a permission problem. So, there may be something going amiss in your packaging or deployment steps (or the manifest isn't doing what you intend).
You can add a bit of debugging code to verify that you do not have the permission. See How permission can be checked at runtime without throwing SecurityException? That should help narrow the problem down.
Related
Hello I'm working on programming a Google Maps WebView. I was trying to track and display my own location. When I press the button, it loads for a while and it said that Google Maps couldn't determine my precise location. I tried running it on Android 5.1 Api 22 Lollipop, it still doesnt work.
MainActivity.java:
package com.example.ali.bellsolution;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends Activity {
private static final int REQUEST_FINE_LOCATION = 0;
WebView myWebView;
String mapPath = "https://www.google.co.uk/maps/#51.5112044,-0.2712415,14z";
/**
* WebViewClient subclass loads all hyperlinks in the existing WebView
*/
public class GeoWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// When user clicks a hyperlink, load in the existing WebView
view.loadUrl(url);
return true;
}
}
/**
* WebChromeClient subclass handles UI-related calls
* Note: think chrome as in decoration, not the Chrome browser
*/
public class GeoWebChromeClient extends WebChromeClient {
#Override
public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback) {
// Always grant permission since the app itself requires location
// permission and the user has therefore already granted it
callback.invoke(origin, true, false);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadPermissions(Manifest.permission.ACCESS_COARSE_LOCATION, REQUEST_FINE_LOCATION);
setContentView(R.layout.activity_main);
myWebView = (WebView) this.findViewById(R.id.mapview);
myWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
myWebView.getSettings().setBuiltInZoomControls(true);
myWebView.setWebViewClient(new GeoWebViewClient());
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.getSettings().setGeolocationEnabled(true);
myWebView.setWebChromeClient(new GeoWebChromeClient());
myWebView.loadUrl(mapPath);
}
#Override
public void onBackPressed() {
// Pop the browser back stack or exit the activity
if (myWebView.canGoBack()) {
myWebView.goBack();
}
else {
super.onBackPressed();
}
}
private void loadPermissions(String perm, int requestCode) {
if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, perm)) {
ActivityCompat.requestPermissions(this, new String[]{perm}, requestCode);
}
}
}
}
Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.ali.bellsolution" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="WebViewApp"
android:supportsRtl="true"
android:theme="#style/AppTheme" >
<activity android:name=".MainActivity"
android:label="WebViewApp"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I am implementing a simple application executing a background service, I am not able to start the service, following is my Manifest & Code, the service class is properly resolved ( reading resources ), inheriting from IntentService ( and implementing the req methods ) doesn't resolve the problem as-well...
Why does the Background service doesn't start?
any help will be appreciated.
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.newcomp.vagent"
android:versionCode="1"
android:versionName="1.0"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="20" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name="com.newcomp.Infrastructure.BootStarter" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".CaptureService"
android:exported="true"
android:process=":captureService" >
</service>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
Service code:
package com.newcomp.vagent;
import android.app.IntentService;
import android.app.Service;
import android.content.Intent;
import android.R.*;
import android.os.IBinder;
import java.io.IOException;
import fi.iki.elonen.NanoHTTPD;
public class CaptureService extends Service {
public CaptureService() {
//super("Capture Service");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
}
Activity code:
package com.newcomp.vagent;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
final String strSvcName = getResources().getString(R.string.startup_service);
//setContentView(R.layout.main);
Toast.makeText(getBaseContext(), String.format("Hello from '%s'", strSvcName), Toast.LENGTH_LONG).show();
Class cls = null;
try {
cls = getClassLoader().loadClass(strSvcName);
startService(new Intent(this, cls));// Starts the service
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//finish();
}
}
The problem was simple, the service was actually starting but since android:process=":captureService" was specified it was starting on a separate process, one that is not connected by the debugger, either specifcally connecting to the service process, OR, omitting android:process=":captureService" resolve the problem.
I am trying to create very basic network application, which will connect to google through socket, and send "GET" and print the output in a text view. but it appears that socket never connects... what am I doing wrong ??
here is the code
MainActiviy:
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import java.io.*;
import java.net.*;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tva = (TextView) this.findViewById(R.id.tv);
String str = "";
try {
Socket sock = new Socket("www.google.com", 80);
str = sock.getRemoteSocketAddress().toString();
tva.setText("Connected to: " + str);
DataOutputStream out = new DataOutputStream(sock.getOutputStream());
out.writeUTF("GET //");
BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
str = br.readLine();
while(str != null) {
tva.setText(str);
str = br.readLine();
}
out.close();
br.close();
sock.close();
} catch(Exception ex) {
}
}
}
manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.onik.netw"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.onik.netw.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>
you are trying to use sockets on main UI thread, you will get exception android.os.NetworkOnMainThreadException
Move the try {} block into a separate thread. Since this will run on non-UI thread you cant access UI elements, so you need to pass the data back to main thread may be via Handler, so it can display the data received.
For a quick test, enclose that entire try block inside an anonymous thread
new Thread() {
public void run() {
// your try block goes here
}
}.start();
replace tva.setText with Log.d("test", str)
I want to make an application with can say a text with a TextToSpeach when I receive a SMS.
For that I have a Service, a Receiver and a class SaidThis.
See my code :
My service :
package fr.dabernat.smsreceiver;
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
public class Service extends IntentService {
private Handler handler;
public static String text;
public Service() {
super("Service");
}
#Override
public void onCreate() {
super.onCreate();
handler = new Handler();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
if (!extras.isEmpty()) {
SaidThis test = new SaidThis();
test.SpeakText();
//showNotification();
//SaidThis test = new SaidThis(this);
//test.text("J'ai honte de moi");
}
Receiver.completeWakefulIntent(intent);
}
}
My Receiver :
package fr.dabernat.smsreceiver;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
public class Receiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that Service will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
Service.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
My class SaidThis :
package fr.dabernat.smsreceiver;
import android.speech.tts.TextToSpeech;
import java.util.Locale;
/**
* Created by Damien on 19/09/2014.
*/
public class SaidThis extends Service implements TextToSpeech.OnInitListener, TextToSpeech.OnUtteranceCompletedListener {
TextToSpeech tts;
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
tts.setLanguage(Locale.FRANCE);
}
}
#Override
public void onUtteranceCompleted(String s) {
stopSelf();
}
public void SpeakText(){
tts.speak(text,TextToSpeech.QUEUE_FLUSH, null);
}
}
My Android Manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="fr.dabernat.smsreceiver" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".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>
<receiver
android:name=".Receiver" >
<intent-filter>
<!-- A CHANGER POUR "ECOUTER" UN AUTRE BROADCAST -->
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<service android:name=".Service" />
</application>
</manifest>
Errors :
10-08 10:44:51.980 1371-1371/fr.dabernat.smsreceiver E/dalvikvm﹕ >>>>> Normal User
10-08 10:44:51.980 1371-1371/fr.dabernat.smsreceiver E/dalvikvm﹕ >>>>> fr.dabernat.smsreceiver [ userId:0 | appId:10309 ]
10-08 10:44:52.080 1371-1412/fr.dabernat.smsreceiver E/AndroidRuntime﹕ FATAL EXCEPTION: IntentService[Service]
Process: fr.dabernat.smsreceiver, PID: 1371
java.lang.NullPointerException
at fr.dabernat.smsreceiver.SaidThis.SpeakText(SaidThis.java:34)
at fr.dabernat.smsreceiver.Service.onHandleIntent(Service.java:36)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.os.HandlerThread.run(HandlerThread.java:61)
I think the problem come from my service but I don't know where.
I try to find some answer on the web before but I don't find any solution to my problem.
Your tts object is not initialized anywhere, therefore it's null.
You have to initialize it: tts = new TextToSpeech() somewhere, before you use it in your SpeakText() method.
I assume onInit() method would be a good fit for initializing your object.
i am unable to get the the front facing camera (camera id 1). open cam #1 failed appears on screen when i try to run the following code.
enclosed a snippet. any help will be appreciated (i am trying it on nexus 4).
Tester.java
package com.example.cam;
import java.util.HashMap;
import java.util.Iterator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.Menu;
import android.widget.Toast;
public class Tester extends Activity {
private static final int[] camIds = { Camera.CameraInfo.CAMERA_FACING_BACK, Camera.CameraInfo.CAMERA_FACING_FRONT };
#SuppressLint("UseSparseArrays")
private final HashMap<Integer, Camera> camMap = new HashMap<Integer, Camera>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
#Override
protected void onResume() {
super.onResume();
if (!checkCameraHardware())
finish();
getCameras();
releaseCamera();
}
#Override
protected void onPause() {
super.onPause();
releaseCamera();
}
#Override
protected void onStop() {
super.onStop();
releaseCamera();
}
#Override
protected void onDestroy() {
super.onDestroy();
releaseCamera();
}
private final void doToast(final String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
private final void getCameras() {
for (int camId : camIds)
try {
camMap.put(camId, Camera.open(camId));
doToast("open cam #" + camId + " succeeded");
} catch (Exception e) {
doToast("open cam #" + camId + " failed");
}
}
private final void releaseCamera() {
final Iterator<Integer> iter = camMap.keySet().iterator();
while (iter.hasNext())
camMap.remove(iter.next()).release();
}
private final boolean checkCameraHardware() {
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))
return camIds.length <= Camera.getNumberOfCameras();
else
return false;
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.cam"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" />
<uses-permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT" />
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.cam.Tester"
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>
</manifest>