2017-02-06 11 views
4

私はユーザーが写真を撮ってサーバーに送ることを許可しようとしています。私はアンドロイドの騒ぎのビットですので、私はthisのチュートリアルに従っています。私は似たような質問をいくつか見たことがありますが、全く同じではありません。アプリはカメラアプリを起動して写真を撮ることができます。画像を受け入れる「チェック」を押すと「残念ながらカメラが停止しました」というメッセージが表示され、アプリはアクティビティに戻ります私はサムネイルや画像を黙って取得しません。 Logcatは、カメラが起動してから停止するまで何も表示しません。ここに私のコードは次のとおりです。カメラの意図で「残念なことにカメラが停止しました」

活動

package com.example.ignacio.androidchat; 


import android.content.Intent; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.location.LocationManager; 
import android.net.Uri; 
import android.os.Environment; 
import android.provider.MediaStore; 
import android.support.v4.content.FileProvider; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Base64; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 

import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.File; 
import java.io.IOException; 
import java.net.URI; 
import java.text.SimpleDateFormat; 
import java.util.ArrayList; 
import java.util.Date; 


public class TaskCompletionForm extends AppCompatActivity{ 

    private static final String TAG = "TaskCompletionForm"; 
    private static int REQUEST_IMAGE_CAPTURE = 1; 
    ImageView formImageView; 
    private String currImagePath; 

    private final boolean submitTime = false; 
    private final boolean submitGPS = false; 
    private final boolean requestImage = true; 
    private final boolean requestQRRead = false; 
    private final boolean requestRFID = false; 

    private LinearLayout formContainer; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_task_completion_form); 

     formContainer = (LinearLayout) findViewById(R.id.ll_formContainer); 

     final Button b_submit = (Button) findViewById(R.id.b_submit); 
     b_submit.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       submitForm(); 
      } 
     }); 

     final Button b_takePicture = (Button) findViewById(R.id.b_takePicture); 
     b_takePicture.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       dispatchPhotographIntent(); 
      } 
     }); 

     formImageView = (ImageView) findViewById(R.id.formImageView); 

    } 

    private void submitForm() { 
     final int childCount = formContainer.getChildCount() - 1; 
     JSONObject jsonObject = new JSONObject(); 
     try { 
      // add text fields 
      int textFieldCount = 0; 
      ArrayList<String> entries = new ArrayList<>(); 
      for (int i = 0; i < childCount; i++) { 
       View v = formContainer.getChildAt(i); 
       if (v instanceof EditText) { 
        entries.add(((EditText) v).getText().toString()); 
        textFieldCount++; 
       } 
      } 
      jsonObject.put("fieldCount", textFieldCount); 
      jsonObject.put("fields", new JSONArray(entries)); 

      // add image 
      if (requestImage && !currImagePath.equals("")) 
      { 
       Bitmap bitmap = BitmapFactory.decodeFile(currImagePath); 
       ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
       bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream); 
       byte[] byteArray = byteArrayOutputStream.toByteArray(); 
       String encodedImage = Base64.encodeToString(byteArray, Base64.DEFAULT); 
       jsonObject.put("image", encodedImage); 
      } 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 

     WebSocket.getInstance().submitCompletionForm(jsonObject); 
    } 

    private void dispatchPhotographIntent() 
    { 
     Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
     if (takePictureIntent.resolveActivity(getPackageManager()) != null) 
     { 
      File photoFile = null; 
      try{ 
       photoFile = createImageFile(); 
      } catch (IOException e) 
      { 
       e.printStackTrace(); 
       // handle exeption 
      } 

      // continue only if the file was successfully created 
      if (photoFile != null) 
      { 
       Uri photoURI = FileProvider.getUriForFile(this, 
         "com.example.ignacio.androidchat.fileprovider", 
         photoFile); 
       takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); 
       startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); 
      } 
     } 
    } 

    private File createImageFile() throws IOException 
    { 
     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
     String imageFileName = "JPEG_" + timeStamp + "_"; 
     File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); 
     File image = File.createTempFile(imageFileName, ".jpg", storageDir); 
     if (!image.exists()) 
     { 
      image.getParentFile().mkdirs(); 
      image.createNewFile(); 
     } 
     currImagePath = image.getAbsolutePath(); 
     return image; 
    } 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { 
      Bundle extras = data.getExtras(); 
      Bitmap imageBitmap = (Bitmap) extras.get("data"); 
      formImageView.setImageBitmap(imageBitmap); 
     } 
    } 
} 

マニフェスト

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.ignacio.androidchat"> 

    <uses-permission android:name="android.permission.INTERNET" /> 

    <!-- To auto-complete the email text field in the login form with the user's emails 
    <uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
    <uses-permission android:name="android.permission.READ_PROFILE" /> 
    <uses-permission android:name="android.permission.READ_CONTACTS" />--> 

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
    <uses-permission android:name="android.permission.CAMERA" 
     android:required = "true"/> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
     <activity android:name=".MainActivity"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
     <activity android:name=".HomeScreen" 
      android:launchMode="singleTask"/> 
     <activity android:name=".TaskDescription" /> 
     <activity android:name=".TaskCompletionForm" 
      android:configChanges="keyboardHidden|orientation"/> 

     <service android:name=".WebSocketIntentService" /> 
     <meta-data 
      android:name="com.google.android.gms.version" 
      android:value="@integer/google_play_services_version"/> 

     <provider 
      android:name="android.support.v4.content.FileProvider" 
      android:authorities="com.example.ignacio.androidchat.fileprovider" 
      android:exported="false" 
      android:grantUriPermissions="true"> 
      <meta-data 
       android:name="android.support.FILE_PROVIDER_PATHS" 
       android:resource="@xml/file_paths" /> 
     </provider> 
    </application> 

</manifest> 

file_paths.xml


<?xml version="1.0" encoding="utf-8"?> 
<paths xmlns:android="http://schemas.android.com/apk/res/android"> 
    <external-path name="my_images" 
     path="Android/data/com.example.ignacio.androidchat/files/Pictures/" /> 
</paths> 
+0

私は画像を受け入れるために「チェック」を押すと、これはどういう意味ですか?どのようにコードに関連している?詳細を説明してください –

+0

logcatからエラートレースを追加してください!! – W4R10CK

+0

ああ、私はあなたがそれを受け入れるか、別のイメージを取るために戻ることができるプレビューを示すイメージを取るときです。しかし、カメラの意図は単にデフォルトでそれを行います。 logcatについては、エラーは表示されません。残念ながら、カメラがオンスクリーンメッセージ以外の動作を停止すると、フィードバックはありません。 –

答えて

3

私は解決策を見つけましたが、問題はまだ分かりません。どのような私のために働いたことは、以下に「dispatchPhotographIntent」を変更することでした。ここでは

private void dispatchPhotographIntent() 
{ 
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    imageFile = createImageFile(); 
    Uri uri = Uri.fromFile(imageFile); 
    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); 
    startActivityForResult(intent, REQUEST_IMAGE_CAPTURE); 
} 

は、私は、ファイル・プロバイダーを使用しても機能「createImageFile」によって生成されたファイルのURIを追跡するわけではありません。代わりに私はファイルを生成し、そこから直接Uriを取得します。私はこれがまだ私の興味をそそられているので、誰かにとって有用であるか、誰かが問題そのものを見つけたことを願っています。

誰でもお礼を言い、助けてくれてありがとう!

4

古いサムスンのAndroidデバイス(私の場合はapi 17)のカメラアプリケーションは、"file:///....."という形式のuriを必要とすると仮定します。問題は、ファイルuri形式により、Android Nougat(api 24以降)がFileUriExposedExceptionを投げてしまうことです。

私は仕事にこれを得た:

Uri imageUri; 
// N is for Nougat Api 24 Android 7 
if (Build.VERSION_CODES.N <= android.os.Build.VERSION.SDK_INT) { 
    // FileProvider required for Android 7. Sending a file URI throws exception. 
    imageUri = FileProvider.getUriForFile(getContext(),"com.<your name here>.fileprovider",imageFile); 
} else { 
    // For older devices: 
    // Samsung Galaxy Tab 7" 2 (Samsung GT-P3113 Android 4.2.2, API 17) 
    // Samsung S3 
    imageUri = Uri.fromFile(imageFile); 
} 

理想的なだけヌガーでFileProvider以上を使用することです。
Build.VERSION_CODESのAPIバージョンを下げることができます。 YMMV、あなたのファイルへのあなたの許容範囲に依存します。

を参照してください。Android Documentationについては、FileUriExposedExceptionのAndroid Nougatをご覧ください。

関連する問題