使用 IntentService 在特定网络上发送图像

Image sending on a particular network using IntentService

我一直在尝试使用特定网络发送图片,当我没有提到任何网络时图片发送成功。我已经尝试过使用异步任务和 IntentService。此外,如果我没有提及任何网络并且应用程序的状态为 运行,当我尝试关闭 wifi 然后再次打开它时,图像不会被发送。

提前致谢

服务class

public class ImageService extends IntentService {

    public ImageService() {
        super("HelloIntentService");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    protected void onHandleIntent(@Nullable final Intent intent) {

        new Thread(new Runnable() {
            @Override
            public void run () {
                byte[] bytesss=intent.getByteArrayExtra("byte");
                try {
                Socket socket = new Socket("ip_address", 8888);
                OutputStream out = socket.getOutputStream();
                DataOutputStream dataOutputStream = new DataOutputStream(out);
                dataOutputStream.write(bytesss);
                dataOutputStream.close();
                out.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            }

        }).start();

    }


    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

MainActivity.java

    private WifiManager wifiManager;

    String networkSSID="network";
    String networkPassword="pass123";
     int netId;

   wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); 
    networkConfiguration();


}
    private void networkConfiguration(){

        WifiConfiguration configuration=new WifiConfiguration();
        configuration.SSID="\""+networkSSID+"\""; 
        configuration.preSharedKey="\""+networkPassword+"\"";  

        wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); 

        netId=wifiManager.addNetwork(configuration); 
        wifiManager.disconnect();
        wifiManager.enableNetwork(netId,true);
        wifiManager.reconnect();
    }

    private BroadcastReceiver wifiStateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
                final String action=intent.getAction();

              if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)){
                if (intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED,false)){

                    Toast.makeText(context, "wifi connected", Toast.LENGTH_SHORT).show();
                    sendingImage();

                }else{

                    Toast.makeText(context, "Please Check Your Internet Connection", Toast.LENGTH_SHORT).show();

                }
            }

        }
    };

  @Override
    protected void onStart() { 
        super.onStart();
        networkConfiguration();
        IntentFilter intentFilter = new IntentFilter(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
        registerReceiver(wifiStateReceiver, intentFilter);
}

   @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(wifiStateReceiver);
        stopService(new Intent(this, SendImageClientService.class));
    }


    private void sendingImage() {

        drawable = (BitmapDrawable) imageView.getDrawable();
        bitmap = drawable.getBitmap();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
        byte[] array = byteArrayOutputStream.toByteArray();

        Intent serviceIntent=new Intent(this,ImageService.class);
        serviceIntent.putExtra("byte",array);
       this.startService(serviceIntent);


    }

这应该会让您了解如何使用 WorkManager 实现它。假定 this 继承自 Context(Activity、Service 等)。 UploadWorker 也可以是完全独立的 class.

我还没有测试过,但理论上应该可以。

您将需要 WorkManager 作为依赖项。所以在你的应用程序的 build.gradle 中你需要添加它:

dependencies {
    ...

    def work_version = "2.3.4" // current version at time of answer
    // (Java only)
    implementation "androidx.work:work-runtime:$work_version"

}

这里是 java 代码:

public void entry() {

    // Create temporary file
    // Use some kind of numbering system if you need multiple at once
    // Should use some method of cleaning up files if they never get uploaded
    File outputFile = new File(getNoBackupFilesDir(), "upload_image.jpg");


    // Save ImageView to file
    BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
    Bitmap bitmap = drawable.getBitmap();
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    try (FileOutputStream fileOutputStream = new FileOutputStream(outputFile)) {
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
    } catch (IOException e) {
        e.printStackTrace();
        return;
    }

    Data inputData = new Data.Builder()
            .putString("imagePath", outputFile.getAbsolutePath())
            .build();

    OneTimeWorkRequest uploadWork = new OneTimeWorkRequest.Builder(UploadWorker.class)
            .setConstraints(new Constraints.Builder()
                    .setRequiredNetworkType(NetworkType.UNMETERED)
                    .build())
            .setInputData(inputData)
            .build();

    WorkManager.getInstance(this).enqueue(uploadWork);

}


public static class UploadWorker extends Worker {

    public UploadWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        String imagePath = getInputData().getString("imagePath");
        File imageFile = new File(imagePath);

        try {
            Socket socket = new Socket("ip_address", 8888);
            OutputStream out = socket.getOutputStream();
            DataOutputStream dataOutputStream = new DataOutputStream(out);
            FileInputStream fis = new FileInputStream(imageFile);
            BufferedInputStream bis = new BufferedInputStream(fis);

            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = bis.read(buffer, 0, buffer.length)) != -1) {
                dataOutputStream.write(buffer, 0, bytesRead);
            }

            bis.close();
            dataOutputStream.close();
            out.close();
            socket.close();

            imageFile.delete();
        } catch (IOException e) {
            e.printStackTrace();
            return Result.failure();
        }

        return Result.success();
    }
}

更新:添加了临时文件和直接数据缓冲的解决方案以支持上传大文件。