使用 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();
}
}
更新:添加了临时文件和直接数据缓冲的解决方案以支持上传大文件。
我一直在尝试使用特定网络发送图片,当我没有提到任何网络时图片发送成功。我已经尝试过使用异步任务和 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();
}
}
更新:添加了临时文件和直接数据缓冲的解决方案以支持上传大文件。