2017-04-12 90 views
0

我有问题,我一直在寻找整整一周。我正在创建将照片和一些数据发送到服务器的应用程序。问题是,当我开始活动时,相机必须启动,但对于某些设备应用程序崩溃。我无法描述错误,因为设备位于其他城市。我在LG G3和HUAWEI P7上都能正常工作。我认为这可能是权限有问题,但我不确定。启动相机活动,应用程序崩溃

package com.fishingtournaments.ZvejysZvejui; 

import android.content.ContentValues; 
import android.content.Context; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Matrix; 
import android.media.ExifInterface; 
import android.os.Environment; 
import android.provider.DocumentsContract; 
import android.support.v4.os.EnvironmentCompat; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.KeyEvent; 
import android.view.View; 


import android.Manifest; 
import android.content.Intent; 
import android.content.pm.PackageManager; 
import android.database.Cursor; 
import android.graphics.Bitmap; 
import android.net.Uri; 
import android.provider.MediaStore; 
import android.support.annotation.NonNull; 
import android.support.v4.app.ActivityCompat; 
import android.support.v4.content.ContextCompat; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.TextView; 
import android.widget.Toast; 

import net.gotev.uploadservice.MultipartUploadRequest; 
import net.gotev.uploadservice.UploadNotificationConfig; 

import java.io.ByteArrayOutputStream; 
import java.io.File; 
import java.io.IOException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.UUID; 
import java.util.concurrent.Semaphore; 


public class SendImageActivity extends AppCompatActivity implements View.OnClickListener { 

    public static final int CAMERA_PERMISSION_REQUEST_CODE = 8675809; 
    TextView fish_n, fish_s, points; 
    public static final int REQUEST_CAPTURE = 1; 
    public static String path; 

    public String fish_name, fish_length, fish_points, colleague_id, fish_size, fish_photo, fish_id, 
      user_id, user_name = ""; 


    //Declaring views 
    private Button buttonUpload; 
    private ImageView imageView; 

    //storage permission code 
    private static final int STORAGE_PERMISSION_CODE = 123; 

    //Bitmap to get image from gallery 

    //Uri to store the image uri 
    private Uri imageUri; /*, uriSavedImage*/ 
    private File imagesFolder, image; 
    private String fixedURI; 


    //----------------------------------// 

    // Storage for camera image URI components 
    private final static String CAPTURED_PHOTO_PATH_KEY = "mCurrentPhotoPath"; 
    private final static String CAPTURED_PHOTO_URI_KEY = "uriSavedImage"; 

    // Required for camera operations in order to save the image file on resume. 
    private String mCurrentPhotoPath = null; 
    private Uri uriSavedImage = null; 


    @Override 
    public void onSaveInstanceState(Bundle savedInstanceState) { 
     if (mCurrentPhotoPath != null) { 
      savedInstanceState.putString(CAPTURED_PHOTO_PATH_KEY, mCurrentPhotoPath); 
     } 
     if (uriSavedImage != null) { 
      savedInstanceState.putString(CAPTURED_PHOTO_URI_KEY, uriSavedImage.toString()); 
     } 
     super.onSaveInstanceState(savedInstanceState); 
    } 

    @Override 
    protected void onRestoreInstanceState(Bundle savedInstanceState) { 

     if (savedInstanceState.containsKey(CAPTURED_PHOTO_PATH_KEY)) { 
      mCurrentPhotoPath = savedInstanceState.getString(CAPTURED_PHOTO_PATH_KEY); 
     } 
     if (savedInstanceState.containsKey(CAPTURED_PHOTO_URI_KEY)) { 
      uriSavedImage = Uri.parse(savedInstanceState.getString(CAPTURED_PHOTO_URI_KEY)); 
     } 
     super.onRestoreInstanceState(savedInstanceState); 
    } 


    //-++-+-+-+-+-+-+-+-+-+-+-+-+---// 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     //Requesting storage permission 
     //TODO INTERFACE, 
     //TODO CHECK PERMISSIONS 
     //TODO TEST ON OTHER PHONES 
     super.onCreate(savedInstanceState); 

     if (savedInstanceState != null) { 
      setContentView(R.layout.activity_send_image); 
      buttonUpload = (Button) findViewById(R.id.buttonUpload); 
      imageView = (ImageView) findViewById(R.id.imageView); 

      buttonUpload.setOnClickListener(this); 
     } else { 
      setContentView(R.layout.activity_send_image); 
      if (ContextCompat.checkSelfPermission(SendImageActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { 
       Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
//    Intent i = new Intent("android.media.action.IMAGE_CAPTURE"); 

       String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 

       imagesFolder = new File(Environment.getExternalStorageDirectory(), "FishingTournament"); 
       image = new File(imagesFolder, "QR_" + timeStamp + ".png"); 
       uriSavedImage = Uri.fromFile(image); 

       i.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage); 
       startActivityForResult(i, REQUEST_CAPTURE); 
      } else { 
       String[] permissionRequest = {Manifest.permission.CAMERA}; 
       ActivityCompat.requestPermissions(SendImageActivity.this, permissionRequest, CAMERA_PERMISSION_REQUEST_CODE); 
      } 


      buttonUpload = (Button) findViewById(R.id.buttonUpload); 
      imageView = (ImageView) findViewById(R.id.imageView); 

      buttonUpload.setOnClickListener(this); 
     } 
    } 


    /* 
    * This is the method responsible for image upload 
    * We need the full image path and the name for the image in this method 
    * */ 
    public void uploadMultipart() { 

     try { 
      String uploadId = UUID.randomUUID().toString(); 

      //Creating a multi part request 
      new MultipartUploadRequest(this, uploadId, Constants.UPLOAD_URL) 
        .addFileToUpload(path, "image") //Adding file 
        .addParameter("name", "asd") //Adding text parameter to the request 
        .addParameter("colleague_id", colleague_id) 
        .addParameter("fish_length", fish_size) 
        .addParameter("fish_points", fish_points) 
        .addParameter("fish_photo", fish_photo) 
        .addParameter("fish_id", fish_id) 
        .setNotificationConfig(new UploadNotificationConfig()) 
        .setMaxRetries(2) 
        .startUpload(); //Starting the upload 

     } catch (Exception exc) { 
      Toast.makeText(this, exc.getMessage(), Toast.LENGTH_SHORT).show(); 
     } 
    } 


    //handling the image chooser activity result 
    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 

     if (resultCode == RESULT_OK && requestCode == REQUEST_CAPTURE) { 
      if (data != null) { 
       fixedURI = String.valueOf(uriSavedImage); 
       fixedURI = fixedURI.replace("file://", ""); 
       path = fixedURI; 
//    Bitmap bitmap = ImageUtils.getInstant().getCompressedBitmap(path); 
//    imageView.setImageBitmap(bitmap); 

      } else { 

       fixedURI = String.valueOf(uriSavedImage); 
       fixedURI = fixedURI.replace("file://", ""); 
       path = fixedURI; 
//    Bitmap bitmap = ImageUtils.getInstant().getCompressedBitmap(path); 
//    imageView.setImageBitmap(bitmap); 

      } 

     } 

    } 


    public String getRealPathFromURI(Uri contentUri) { 
     String[] proj = {MediaStore.Images.Media.DATA}; 
     Cursor cursor = managedQuery(contentUri, proj, null, null, null); 
     int column_index = cursor 
       .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
     cursor.moveToFirst(); 
     return cursor.getString(column_index); 
    } 


    //Requesting permission 
    private void requestStorageReadPermission() { 
     if (ContextCompat.checkSelfPermission(SendImageActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) 
      return; 

     if (ActivityCompat.shouldShowRequestPermissionRationale(SendImageActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)) { 
      //If the user has denied the permission previously your code will come to this block 
      //Here you can explain why you need this permission 
      //Explain here why you need this permission 
      Toast.makeText(SendImageActivity.this, "Norint siųsti nuotrauką reikalingas leidimas prie failų saugyklos", Toast.LENGTH_SHORT).show(); 
     } 
     //And finally ask for the permission 
     ActivityCompat.requestPermissions(SendImageActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE); 
    } 

    //This method will be called when the user will tap on allow or deny 
    @Override 
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 

     //Checking the request code of our request 
     if (requestCode == STORAGE_PERMISSION_CODE) { 

      //If permission is granted 
      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       //Displaying a toast 
       Toast.makeText(this, "Permission granted now you can read the storage", Toast.LENGTH_LONG).show(); 
      } else { 
       //Displaying another toast if permission is not granted 
       Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show(); 
      } 
     } 
    } 


    @Override 
    public void onClick(View v) { 
     if (v == buttonUpload) { 
      uploadMultipart(); 
     } 
    } 

    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     if ((keyCode == KeyEvent.KEYCODE_BACK)) { 
      onBackPressed(); 
     } 

     return false; 
    } 

    @Override 
    public void onBackPressed() { 
     super.onBackPressed(); 
     final String user_name = getIntent().getStringExtra("user_name"); 
     final String colleague_id = getIntent().getStringExtra("colleague_id"); 
     final String user_id = getIntent().getStringExtra("user_id"); 
     Intent intent = new Intent(SendImageActivity.this, ChooseFishActivity.class); 
     intent.putExtra("colleague_id", colleague_id); 
     intent.putExtra("user_name", user_name); 
     intent.putExtra("user_id", user_id); 
     startActivity(intent); 
     finish(); 

    } 

} 

它看起来愚蠢,为什么我如果onCreate()方法,这是因为在我的LG G3相机上重新启动拍照。这就是为什么我的onActivityResult()方法看起来很奇怪。

AndroidManifest.xml中

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

    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" /> 

    <uses-feature 
     android:name="android.hardware.camera" 
     android:required="true" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/descicon" 
     android:label="Žvejys žvejui" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
     <activity 
      android:name=".LoginActivity" 
      android:configChanges="orientation" 
      android:screenOrientation="portrait"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
     <activity 
      android:name=".ChooseFishActivity" 
      android:configChanges="orientation" 
      android:parentActivityName=".LoginActivity" 
      android:screenOrientation="portrait" /> 
     <activity 
      android:name=".ResultActivity" 
      android:configChanges="orientation" 
      android:parentActivityName=".ChooseFishActivity" 
      android:screenOrientation="portrait" /> 
     <activity 
      android:name=".ShowResultsActivity" 
      android:configChanges="orientation" 
      android:parentActivityName=".LoginActivity" 
      android:screenOrientation="portrait" /> 
     <activity android:name=".SendImageActivity" 
      android:configChanges="orientation" 
      android:parentActivityName=".LoginActivity" 
      android:screenOrientation="portrait" /> 
    </application> 

</manifest> 

附:我的代码可能看起来不太清楚,为此感到遗憾,我一直在做所有事情并测试一切来解决这个问题。

顺便说一句我要求在我的LoginActivity存储权限,在那里我创建照片文件夹。

LoginActivity

package com.fishingtournaments.ZvejysZvejui; 

import android.Manifest; 
import android.app.Activity; 
import android.content.Intent; 
import android.content.pm.PackageManager; 
import android.os.Environment; 
import android.support.v4.app.ActivityCompat; 
import android.support.v4.content.ContextCompat; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.Toast; 

import com.android.volley.RequestQueue; 
import com.android.volley.Response; 
import com.android.volley.toolbox.Volley; 
import com.google.zxing.integration.android.IntentIntegrator; 
import com.google.zxing.integration.android.IntentResult; 

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

import java.io.File; 

public class LoginActivity extends AppCompatActivity { 

    private static final int STORAGE_PERMISSION_CODE = 123; 


    EditText qrCode_edit; 
    Button check_button; 
// Button result_button; 
    public String colleague_id; 
    public String colleague_name; 
    public String user_id, user_name; 



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

     if(ContextCompat.checkSelfPermission(LoginActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) 
     { 
      Toast.makeText(LoginActivity.this, "Užklausa permissionų", Toast.LENGTH_SHORT).show(); 

      if (ActivityCompat.shouldShowRequestPermissionRationale(LoginActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)) { 
       Toast.makeText(LoginActivity.this, "Norint siųsti nuotrauką reikalingas leidimas prie failų saugyklos", Toast.LENGTH_SHORT).show(); 
      } 
      //And finally ask for the permission 
      ActivityCompat.requestPermissions(LoginActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE); 
     }else{ 
      Toast.makeText(LoginActivity.this, "Teisės suteiktos", Toast.LENGTH_SHORT).show(); 

     } 

     File direct = new File(Environment.getExternalStorageDirectory()+"/FishingTournament"); 
     if(!direct.exists()) { 
      if (direct.mkdir()) 
       Toast.makeText(LoginActivity.this, "Direktorija sukurta", Toast.LENGTH_SHORT).show(); 
     }else{ 
      Toast.makeText(LoginActivity.this, "Nesukurta direktorija, nes ji jau egzistuoja", Toast.LENGTH_SHORT).show(); 
     } 
// it will create two folder in your internal storage first is specifyfoldername and another one inside the mentioned folder which is nestedfoldername 


     qrCode_edit = (EditText) findViewById(R.id.qrCode_editText); 
     check_button = (Button) findViewById(R.id.check_button); 
//  result_button = (Button) findViewById(R.id.results); 
     //QR Code 
     final Activity activity = this; 

     /** 
     * Button for scanning QR code 
     * 
     */ 
     check_button.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       check_button.setEnabled(false); 
       String qrCode = qrCode_edit.getText().toString(); 

       //QR Code 
       IntentIntegrator integrator = new IntentIntegrator(activity); 
       integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE_TYPES); 
       integrator.setPrompt("Užveskite kamerą ant QR kodo"); 
       integrator.setCameraId(0); 
       integrator.setBeepEnabled(false); 
       integrator.setBarcodeImageEnabled(false); 
       integrator.initiateScan(); 
       check_button.setEnabled(true); 
       //--- 

       /*Response.Listener<String> responseListener = new Response.Listener<String>() { 
        @Override 
        public void onResponse(String response) { 

         try { 
          JSONObject jsonResponse = new JSONObject(response); 
          boolean success = jsonResponse.getBoolean("success"); 

          if (success){ 
           Intent intent = new Intent(LoginActivity.this, ChooseFishActivity.class); 
           colleague_id = jsonResponse.getString("colleague_id"); 
           colleague_name = jsonResponse.getString("colleague_name"); 
           user_id = jsonResponse.getString("user_id"); 
           intent.putExtra("colleague_id",colleague_id); 
           intent.putExtra("user_name",colleague_name); 
           intent.putExtra("user_id",user_id); 
           startActivity(intent); 
//        finish(); 
           //startActivity(new Intent(LoginActivity.this, ChooseFishActivity.class)); 
          }else{ 
           String message = jsonResponse.getString("message"); 
           Toast.makeText(getApplicationContext(),message,Toast.LENGTH_SHORT).show(); 
           *//*ats.setText(message);*//* 

          } 
         } catch (JSONException e) { 
          e.printStackTrace(); 
         } 

        } 
       }; 


       LoginRequest loginRequest = new LoginRequest(qrCode, responseListener); 
       RequestQueue queue = Volley.newRequestQueue(LoginActivity.this); 
       queue.add(loginRequest);*/ 

      } 
     }); 

     /** 
     * Button for launching ShowResultsActivity 
     */ 
     /*result_button.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Intent intent = new Intent(LoginActivity.this, ShowResultsActivity.class); 
       startActivity(intent); 
       finish(); 
      } 
     });*/ 

    } 


    protected void onActivityResult(int requestCode, int resultCode, Intent data){ 
     IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); 
     if(result != null){ 
      if(result.getContents()==null){ 
       Toast.makeText(this, "Atšaukėte skanavimą", Toast.LENGTH_LONG).show(); 
      }else{ 

       Response.Listener<String> responseListener = new Response.Listener<String>() { 
        @Override 
        public void onResponse(String response) { 

         try { 
          JSONObject jsonResponse = new JSONObject(response); 
          boolean success = jsonResponse.getBoolean("success"); 

          /*If correct QR-code*/ 
          if (success){ 
           Intent intent = new Intent(LoginActivity.this, ChooseFishActivity.class); 
           colleague_id = jsonResponse.getString("colleague_id"); 
           colleague_name = jsonResponse.getString("colleague_name"); 
           user_id = jsonResponse.getString("user_id"); 
           user_name = jsonResponse.getString("user_name"); 
           intent.putExtra("colleague_id",colleague_id); 
           intent.putExtra("user_name",colleague_name); 
           intent.putExtra("user_id",user_id); 
           Toast.makeText(getApplicationContext(),"Sveiki, " + user_name,Toast.LENGTH_SHORT).show(); 
           startActivity(intent); 
           finish(); 

          }else{ 
           String message = jsonResponse.getString("message"); 
           Toast.makeText(getApplicationContext(),message,Toast.LENGTH_SHORT).show(); 
          } 
         } catch (JSONException e) { 
          e.printStackTrace(); 
         } 

        } 
       }; 


       LoginRequest loginRequest = new LoginRequest(result.getContents(), responseListener); 
       RequestQueue queue = Volley.newRequestQueue(LoginActivity.this); 
       queue.add(loginRequest); 


      } 
     }else { 
      super.onActivityResult(requestCode, resultCode, data); 
     } 
    } 
} 
+0

解决方案展示你的错误的logcat – shmakova

+1

它很难搞清楚没有日志 –

+0

就像我说的,在我个人的手机,它工作正常,但是当我在我的应用程序发送给其他人,并且他们试图测试它,它在相机意图上崩溃。 – Speconaz

回答

0

所以我想问题出在哪里了。 错误是exposed beyond app through ClipData.Item.getUri()。基本上问题出现在这一行i.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);。寻找这个错误后,我发现在这个post