android套接字在模拟器上工作,但在我的真实设备上不工作

Posted

技术标签:

【中文标题】android套接字在模拟器上工作,但在我的真实设备上不工作【英文标题】:android sockets work on emulator but not on my real device 【发布时间】:2021-10-07 10:28:55 【问题描述】:

这是我的源代码的一部分,它在模拟器上完美运行,但在真手机上却不行。有一些答案说这是关于服务器的防火墙设置。请问如何设置一个允许android数据通过的合适的防火墙?

【问题讨论】:

【参考方案1】:
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Build;
import android.os.IBinder;
import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;

import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.security.Provider;

public class LocationService extends Service 

    public class sendLocation extends AsyncTask<String,Void,Void>

//        public static final String SERVER_IP_ADDRESS = "10.50.xx.xx";
        public static final String SERVER_IP_ADDRESS = "10.152.xx.xx";
        public static final int PORT = 8000;
        /**
         * send the data to the server
         * @param strings
         * @return
         */

        @Override
        protected Void doInBackground(String... strings) 
            String location_info = strings[0];
            try 
                Socket socket = new Socket(SERVER_IP_ADDRESS,PORT);
//                    Toast.makeText(LocationService.this, "Connected to the Server", Toast.LENGTH_SHORT).show();
                PrintWriter pw = new PrintWriter(socket.getOutputStream());
                pw.write(location_info);
                pw.flush();
                pw.close();
                socket.close();
             catch (IOException e) 
                e.printStackTrace();
            
            return null;
        
    

    private LocationCallback locationCallback = new LocationCallback() 
        @Override
        public void onLocationResult(@NonNull LocationResult locationResult) 
            super.onLocationResult(locationResult);
            if (locationResult != null && locationResult.getLastLocation() != null)
                double latitude = locationResult.getLastLocation().getLatitude();
                double longitude = locationResult.getLastLocation().getLongitude();
//                Log.d("LOCATION_UPDATE",latitude + " , " + longitude);
                String androidId = Settings.Secure.getString(getContentResolver(),
                        Settings.Secure.ANDROID_ID);
                Toast.makeText(LocationService.this, "Device ID:" + androidId + " \nLOCATION_UPDATE" + latitude + " , " + longitude, Toast.LENGTH_SHORT).show();

                new sendLocation().execute("Device ID:" + androidId + " ; Latitude:" + latitude + " ; Longitude:" + longitude);
            

        
    ;

    @Nullable
    @Override
    public IBinder onBind(Intent intent)
        throw  new UnsupportedOperationException("Not implement yet!");
    

    private void startLocationService()
        String channelId = "location_notification_channel";
        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        Intent resultIntent = new Intent();
        PendingIntent pendingIntent = PendingIntent.getActivity(
                getApplicationContext(),
                0,
                resultIntent,
                PendingIntent.FLAG_UPDATE_CURRENT
        );
        NotificationCompat.Builder builder = new NotificationCompat.Builder(
                getApplicationContext(),
                channelId
        );
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setContentTitle("Location Service");
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        builder.setContentText("Running");
        builder.setContentIntent(pendingIntent);
        builder.setAutoCancel(false);
        builder.setPriority(NotificationCompat.PRIORITY_MAX);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            if (notificationManager != null
                    && notificationManager.getNotificationChannel(channelId) == null)
                NotificationChannel notificationChannel = new NotificationChannel(
                        channelId,
                        "Location Service",
                        NotificationManager.IMPORTANCE_HIGH
                );
                notificationChannel.setDescription("This channel is used by location service");
                notificationManager.createNotificationChannel(notificationChannel);
            

        

        LocationRequest locationRequest = new LocationRequest();
        locationRequest.setInterval(4000);
        locationRequest.setFastestInterval(2000);
        locationRequest.setPriority(locationRequest.PRIORITY_HIGH_ACCURACY);

        LocationServices.getFusedLocationProviderClient(this)
                .requestLocationUpdates(locationRequest,locationCallback, Looper.getMainLooper());
        startForeground(Constants.LOCATION_SERVICE_ID,builder.build());
    

    private void stopLocationService()
        LocationServices.getFusedLocationProviderClient(this)
                .removeLocationUpdates(locationCallback);
        stopForeground(true);
        stopSelf();
    

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
        if (intent != null)
            String action = intent.getAction();
            if (action != null)
                if (action.equals(Constants.ACTION_START_LOCATION_SERVICE))
                    startLocationService();
                 else if (action.equals(Constants.ACTION_STOP_LOCATION_SERVICE))
                    stopLocationService();
                
            
        
        return  super.onStartCommand(intent,flags,startId);
    

【讨论】:

以上是关于android套接字在模拟器上工作,但在我的真实设备上不工作的主要内容,如果未能解决你的问题,请参考以下文章

我无法在Android模拟器上打开文件

当我在真实设备中打开活动时应用程序崩溃

Xamarin表单,在Visual Studio Android Emulator上运行的应用程序但在真实设备上崩溃

在真实设备模式下模拟或运行时未处理 http 请求,但在模拟器上运行良好

C# 推送通知在模拟器上工作但在真实设备上不工作

Android:应用程序在模拟器上运行,但在我的手机上崩溃