質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

SSL

SSL(Secure Sockets Layer)とは、暗号化されたプロトコルで、インターネット上での通信セキュリティを提供しています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

0回答

1712閲覧

証明書付きのサーバに画像を送信できない場合がある

front_sea

総合スコア8

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

SSL

SSL(Secure Sockets Layer)とは、暗号化されたプロトコルで、インターネット上での通信セキュリティを提供しています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2020/02/10 04:56

編集2022/01/12 10:55

お初にお目にかかります。
会社にてアプリを作成している者で、何かあればここで検索しており非常に助かっております。
この度はどうしても解決できない問題があり、皆様のお力を借りたく質問を投稿いたしました。
何卒、お力添えいただきたく存じます。

前提・実現したいこと

実現したいこと:
SSL証明書を使用しているAzureサーバに、スマホ(Android)で撮影した写真をアップロードする

発生している問題・エラーメッセージ

問題:
撮影した写真の容量が大きい場合、送信に失敗することがある

容量は100kb(Mbではないです)を超えると必ず失敗します。
ただし、証明書を使用しない環境には問題なく送信ができております。

失敗時のエラー内容:
・ W/System.err: javax.net.ssl.SSLException: Write error
・ W/System.err: javax.net.ssl.SSLException: Read error
・connect pear
・タイムアウト

該当のソースコード

全部で3種類
・SendPic.java(写真撮影)
・AsyncHttps.java(送信用非同期処理)
・pic_upload.php(画像復元用)

流れ:
SendPicで撮影、byte配列に変換しAsyncHttpsに渡す(元のデータは残さない)
→AsyncHttpsでAzure web apps(SSL適用)上のphpファイルに送信
→phpファイルにて画像を復元

SendPic

1public class SendPic extends AppCompatActivity 2{ 3 static final int REQUEST_CAPTURE_IMAGE = 100; 4 5 File mediaFile; 6 private Uri imageUri; 7 8 9 @Override 10 protected void onCreate(Bundle savedInstanceState) 11 { 12 super.onCreate(savedInstanceState); 13 setContentView(R.layout.activity_main); 14 ImageButton btn_camera = findViewById(R.id.btn_camera); 15 16 17 //ボタンを押されたこと検知するリスナーを設置 18 btn_camera.setOnClickListener(BtnClickListener); 19 20 21 } 22 23 public View.OnClickListener BtnClickListener = new View.OnClickListener() 24 { 25 public void onClick(View v) 26 { 27 28 switch (v.getId()) 29 { 30 default: 31 return; 32 33 //承認された時用カメラボタン 34 case R.id.btn_camera: 35 Intent intent_c = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 36 File mediaStorageDir = new File 37 (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"MyApp"); 38 //カメラ画像を保存するディレクトリ 39 if(!mediaStorageDir.exists()) 40 { 41 if(!mediaStorageDir.mkdirs()) 42 {break;} 43 } 44 45 //現在日時を取得 46 String timeStamp = new SimpleDateFormat( 47 "yyyy_MM_dd_HH_mm_ss").format(new Date()); 48 49 //取得した現在日時をファイル名に 50 mediaFile = new File(mediaStorageDir.getPath() + File.separator 51 + timeStamp +".jpg"); 52 53 imageUri = Uri.fromFile(mediaFile); 54 55 Uri uri = FileProvider.getUriForFile( 56 SendPic.this 57 ,getApplicationContext().getPackageName() + ".provider" 58 , mediaFile); 59 intent_c.putExtra(MediaStore.EXTRA_OUTPUT, uri); 60 61 startActivityForResult(intent_c,REQUEST_CAPTURE_IMAGE); 62 break; 63 }; 64 }; 65 }; 66 67 @Override 68 public void onActivityResult(int requestCode, int resultCode, Intent resultData) 69 { 70 //写真撮った時 71 if(REQUEST_CAPTURE_IMAGE == requestCode && resultCode == Activity.RESULT_OK) 72 { 73 try 74 { 75 Bitmap bitmap= getBitmapFromUri(imageUri); 76 if(bitmap == null) 77 {return;} 78 79 iv1.setScaleType(ImageView.ScaleType.MATRIX); 80 iv1.setImageBitmap(bitmap); 81 //画像のサイズを今の1/3に変更し 82 final Bitmap changeScale = Bitmap.createScaledBitmap(bitmap,bitmap.getWidth()/3,bitmap.getHeight()/3,true); 83 84 if(changeScale == null) 85 {return;} 86 87 //画像は保存しなくていいので削除 88 mediaFile.delete(); 89 90 byte[] bytes; 91 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 92 //成功率と画質の兼ね合いで30とする 93 changeScale.compress(Bitmap.CompressFormat.JPEG, 30, byteArrayOutputStream); 94 bytes = byteArrayOutputStream.toByteArray(); 95 byteArrayOutputStream.close(); 96 97 //送信 98 AsyncHttps.url_id = 0; 99 new AsyncHttps(SendPic.this).execute(bytes); 100 101 } 102 catch (IOException e) 103 { 104 e.printStackTrace(); 105 Log.d("失敗:",String.valueOf(e)); 106 } 107 } 108 109 } 110 //Uriから画像(Bitmap形式)を取得する 111 private Bitmap getBitmapFromUri(Uri uri) throws IOException 112 { 113 ParcelFileDescriptor parcelFileDescriptor = 114 getContentResolver().openFileDescriptor(uri,"r"); 115 FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); 116 Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor); 117 parcelFileDescriptor.close(); 118 return image; 119 } 120} 121

AsyncHttps

1public class AsyncHttps extends AsyncTask<byte[], Void, String> 2{ 3 private Context mContext; 4 public AsyncHttps(Context context) 5 {mContext = context;} 6 7 public static String res=null; 8 public static StringBuilder stblX = new StringBuilder(); 9 10 // 非同期処理 11 @Override 12 protected String doInBackground(byte[]... params) 13 { 14 String urlSt = "https://example/pic_upload.php"; //組織の名前が入っているので便宜上のURLです 15 16 HttpURLConnection con = null; 17 final StringBuilder stbl = new StringBuilder(); 18 try 19 {this.registerClientCert(mContext );} 20 catch ( Exception e ) 21 {e.printStackTrace();} 22 23 try 24 { 25 // URL設定 26 URL url = new URL(urlSt); 27 // HttpURLConnection 28 con = (HttpsURLConnection) url.openConnection(); 29 // no Redirects 30 con.setInstanceFollowRedirects(false); 31 // データを書き込む 32 con.setDoOutput(true); 33 // 時間制限 34 con.setReadTimeout(10000); 35 con.setConnectTimeout(20000); 36 // 接続 37 con.connect(); 38 // データ送信処理 39 OutputStream out = null; 40 try 41 { 42 out = con.getOutputStream(); 43 byte[] word = params[0]; 44 out.write(word); 45 out.flush(); 46 } 47 catch (IOException e) 48 {e.printStackTrace();} 49 finally 50 { 51 if (out != null) 52 {out.close(); } 53 } 54 55 final int status = con.getResponseCode(); 56 if (status == HttpURLConnection.HTTP_OK) 57 { 58 //レスポンス処理(検索とか) 59 final InputStream in = con.getInputStream(); 60 String encoding = con.getContentEncoding(); 61 if(encoding == null) 62 {encoding="UTF-8";} 63 final InputStreamReader inReader = new InputStreamReader(in,encoding); 64 final BufferedReader bufReader = new BufferedReader(inReader); 65 66 while ((res = bufReader.readLine()) != null) 67 {stbl.append(res);} 68 bufReader.close(); 69 inReader.close(); 70 in.close(); 71 72 } 73 else 74 {Log.d("接続失敗", String.valueOf(status));} 75 } 76 catch (IOException e) 77 {Log.d("接続失敗", String.valueOf(e)); } 78 finally { 79 if (con != null) { 80 con.disconnect(); 81 } 82 } 83 return res; 84 } 85 //証明書の設定。通信するために必要 86 private void registerClientCert(Context context) throws Exception 87 { 88 KeyManagerFactory keyManagerFactory; 89 //証明書作成したときのパス 90 final char[] PASSWORD = "***PASSWORD***".toCharArray(); 91 InputStream inputStream; 92 try 93 { 94 inputStream = context.getResources().getAssets().open("certificate.pfx"); 95 KeyStore keyStore = KeyStore.getInstance("PKCS12"); 96 keyStore.load(inputStream,PASSWORD); 97 keyManagerFactory = KeyManagerFactory.getInstance("X509"); 98 keyManagerFactory.init(keyStore,PASSWORD); 99 SSLContext sslContext = SSLContext.getInstance("TLS"); 100 sslContext.init(keyManagerFactory.getKeyManagers(),null,null); 101 HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); 102 }catch (IOException e) 103 {throw new Exception(e);} 104 catch (NoSuchAlgorithmException e) 105 {throw new Exception(e);} 106 } 107}

pic_upload

1<?php 2 //受信したbody部分を取り出す 3 $bin = file_get_contents("php://input"); 4 $path = dirname(__FILE__); 5 6 //日本時間に設定(ファイル名用) 7 date_default_timezone_set('Asia/Tokyo'); 8 $now = microtime(true); 9 $ms = (int)($now - ((int)$now) * 1000); 10 $msStr = str_pad($ms, 3, 0, STR_PAD_LEFT); 11 $dtStr = date("Ymd_His"). "_" . substr(explode(".", (microtime(true) . ""))[1], 0, 3); 12 13 //ファイル名を設定 14 $fname = $path . "\". $dtStr . ".jpg"; 15 $picname = $dtStr . ".jpg"; 16 17 unlink($fname); 18 19 $fp = fopen($fname, 'wb'); 20 fwrite($fp, $bin); 21 fclose($fp); 22?> 23

試したこと

画像を分割し、複数回に分けて送信
→合体時に後に送信した画像が復元されず失敗

タイムアウトの時間を変更
→待ち時間最大まで使用するが、timeoutやconnect pearが発生し失敗

補足情報

AndroidStudioバージョン:3.1.4
スマホのAndroidバージョン:8.0.0

見よう見まねの拙いコードではございますが、
何卒宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/02/10 05:39

urlSt が有効なドメインじゃないからじゃね。しらんけど
front_sea

2020/02/10 06:02

閲覧ありがとうございます。 URLに関しましては所属する組織の名前が入っていたため、便宜上の物として記載したつもりでしたが、説明がないと分からないですね… こちら修正いたします
退会済みユーザー

退会済みユーザー

2020/02/10 06:26

基本例示ドメインを使ってください
front_sea

2020/02/10 06:33 編集

ありがとうございます。 urlStを例示アドレスに修正いたしました。
hoshi-takanori

2020/02/18 10:24

サーバーの設定の問題って可能性も…。他のクライアントから巨大なファイル送ったらどうなりますか?
front_sea

2020/02/21 01:21

ありがとうございます。 他のクライアントでも試してみたいと思います。 後日試した結果を記載いたします。
front_sea

2020/07/06 06:47

ようやく別の端末が手に入り試すことができました。 結果はやはりエラーが発生、エラー内容は以下の通りでした。 Caused by: java.net.SocketException: socket is closed
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問