我编写了一个应用程序,该应用程序应该拍照并录制视频,然后将其显示在屏幕上。在手机上尝试使用相机时,相机无法使用,但可以在模拟器中使用。
在执行应用程序时,这就是实际发生的情况:
每次我单击按钮打开相机时,应用程序都会停止,并且显示的错误是应用程序名称已停止,再次打开应用程序
当我点击再次打开应用时,它会返回正常状态
我已经在程序中授予了摄像头许可
下面是我的代码:
public class EventActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{
public static final String KEY_MENU_TYPE = "menutype";
//public static final String KEY_PREF_USER_DETAILS = "prefUserDetails";
private static final String TAG = EventActivity.class.getSimpleName();
private static final String SERVER_IMAGE_PATH = "http://edo.com/imageupload/";
private static final String SERVER_PATH = "http://edo.com/";
String[] PERMISSIONS = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
private LocationRequest mLocationRequest;
private EditText event, eventDescription, name;
private TextView attachmentStatus;
private static final int TAKE_PICTURE = 1;
private static final int PERMISSION_ALL = 3;
private Uri capturedImageUri;
private Uri videoUri;
private String mediaFile;
private String videoFile;
private static final int MY_SOCKET_TIMEOUT_MS = 5000;
private String[] serverData;
private static final int REQUEST_VIDEO_CAPTURE = 300;
private boolean isImage;
private String locationResult;
String menutype = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event);
Intent intent = getIntent();
/* ActionBar mBar = getSupportActionBar();
if(mBar != null){
mBar.setDisplayHomeAsUpEnabled(true);
}*/
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addApi(LocationServices.API)
.build();
}
mLocationRequest = createLocationRequest();
Button photoVideoButton = (Button)findViewById(R.id.take_image_video);
photoVideoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showOptionDialog();
}
});
attachmentStatus = (TextView)findViewById(R.id.file_status);
event = (EditText)findViewById(R.id.enter_event);
eventDescription =(EditText)findViewById(R.id.enter_event_description);
name = (EditText)findViewById(R.id.name);
Button cancelUploadButton = (Button) findViewById(R.id.cancel_upload);
assert cancelUploadButton != null;
cancelUploadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
resetViewControls();
}
});
Button sendToServerButton = (Button) findViewById(R.id.send_to_server);
assert sendToServerButton != null;
sendToServerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String eventValue = event.getText().toString().trim();
String eventDescriptionValue = eventDescription.getText().toString();
String nameValue = name.getText().toString();
String locationValue = "";
if(TextUtils.isEmpty(eventValue) || TextUtils.isEmpty(eventDescriptionValue) || TextUtils.isEmpty(nameValue)){
Toast.makeText(EventActivity.this, getString(R.string.send_to_server_error), Toast.LENGTH_LONG).show();
return;
}
if(locationResult == null || locationResult.equals("")){
locationValue = "";
}else{
locationValue = locationResult;
}
if(TextUtils.isEmpty(mediaFile) && TextUtils.isEmpty(videoFile)){
Toast.makeText(EventActivity.this, "Please attach a photo or video", Toast.LENGTH_LONG).show();
return;
}
if(!TextUtils.isEmpty(mediaFile) && isImage){
// send the information to remote server
Bitmap storeBitmap = BitmapFactory.decodeFile(mediaFile);
Bitmap resizedBitmap = Bitmap.createScaledBitmap(storeBitmap, 640, 420, true);
String imageBasedString = convertBitmapToBaseImageString(resizedBitmap);
serverData = new String[]{eventValue, eventDescriptionValue, nameValue, imageBasedString, locationValue};
sendCapturedImageToServer(serverData);
//move stored video to a new folder
String photoPath = getMovedFilePath(mediaFile, eventValue);
moveFileToNewDestination(mediaFile, photoPath);
}else if(!TextUtils.isEmpty(mediaFile) && !isImage){
//Store the video to your server
uploadVideoToServer(videoFile, eventValue, eventDescriptionValue, nameValue, locationValue);
//move stored video to a new folder
String photoPath = getMovedFilePath(videoFile, eventValue);
moveFileToNewDestination(videoFile, photoPath);
}else{
// Image or video is missing. Show message to user
Toast.makeText(EventActivity.this, getString(R.string.upload_image_or_video), Toast.LENGTH_LONG).show();
}
}
});
this.menutype = intent.getStringExtra(KEY_MENU_TYPE);
if (this.menutype == null) {
this.menutype = "";
}
}
public void goBack(View view) {
Intent intent;
if (this.menutype.equals("PRE")) {
intent = new Intent(this, PreElectionMenuActivity.class);
} else if (this.menutype.equals("ACC")) {
intent = new Intent(this, AccreditationMenuActivity.class);
} else if (this.menutype.equals("ELE")) {
intent = new Intent(this, VotingMenuActivity.class);
} else if (this.menutype.equals("INC")) {
intent = new Intent(this, IncidentMenuActivity.class);
} else {
intent = new Intent(this, HomeActivity.class);
}
startActivity(intent);
}
private String getMovedFilePath(String filePath, String eventName){
int indexPosition = filePath.lastIndexOf(".");
String fileExtension = filePath.substring(indexPosition, filePath.length());
String newFilename = eventName + fileExtension;
return getFileDestinationPath(newFilename);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == TAKE_PICTURE) {
capturedImageUri = data.getData();
if (!hasPermissions(this, PERMISSIONS)){
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}else {
mediaFile = "";
mediaFile = getRealPathFromURIPath(capturedImageUri, EventActivity.this);
Log.d(TAG, "Capture image path" + mediaFile);
attachmentStatus.setText("Image file has been attached");
isImage = true;
}
}
if (requestCode == REQUEST_VIDEO_CAPTURE) {
videoUri = data.getData();
if (!hasPermissions(this, PERMISSIONS)){
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}else{
videoFile = getRealPathFromURIPath(videoUri, EventActivity.this);
Log.d(TAG, "Captured video path " + videoUri);
Log.d(TAG, "New path " + videoFile);
attachmentStatus.setText("Video file has been attached");
isImage = false;
}
}
}
}
private void resetViewControls(){
event.setText("");
eventDescription.setText("");
name.setText("");
attachmentStatus.setText(R.string.attached_file);
}
@Override
protected void onResume() {
super.onResume();
if(capturedImageUri != null){
if (!hasPermissions(this, PERMISSIONS)){
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}else {
mediaFile = getRealPathFromURIPath(capturedImageUri, EventActivity.this);
}
}
}
private String getRealPathFromURIPath(Uri contentURI, Activity activity) {
Cursor cursor = activity.getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) {
return contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
}
private String convertBitmapToBaseImageString(Bitmap bitmap){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 50, stream);
byte[] byte_arr = stream.toByteArray();
return Base64.encodeToString(byte_arr, 0);
}
private void sendCapturedImageToServer(String[] photoDetails){
Map<String, String> params = new HashMap<String,String>();
params.put("EVENT", photoDetails[0]);
params.put("EVENT_DESCRIPTION", photoDetails[1]);
params.put("NAME", photoDetails[2]);
params.put("CAPTURE_IMAGE", photoDetails[3]);
params.put("EVENT_LOCATION", photoDetails[4]);
GsonRequest<ServerObject> serverRequest = new GsonRequest<ServerObject>(
Request.Method.POST,
SERVER_IMAGE_PATH,
ServerObject.class,
params,
createRequestSuccessListener(),
createRequestErrorListener());
serverRequest.setRetryPolicy(new DefaultRetryPolicy(
MY_SOCKET_TIMEOUT_MS,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
VolleySingleton.getInstance(EventActivity.this).addToRequestQueue(serverRequest);
}
private Response.Listener<ServerObject> createRequestSuccessListener() {
return new Response.Listener<ServerObject>() {
@Override
public void onResponse(ServerObject response) {
try {
Log.d(TAG, "Json Response " + response.getSuccess());
if(!TextUtils.isEmpty(response.getSuccess()) && response.getSuccess().equals("1")){
Toast.makeText(EventActivity.this, getString(R.string.successful_upload), Toast.LENGTH_LONG).show();
resetViewControls();
}else{
Toast.makeText(EventActivity.this, getString(R.string.server_error), Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
};
};
}
private Response.ErrorListener createRequestErrorListener() {
return new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
};
}
public static void getAddressFromLocation(final double lat, final double lon, final Context context, final Handler handler) {
Thread thread = new Thread() {
@Override public void run() {
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
String result = null;
try {
List<Address> list = geocoder.getFromLocation(lat, lon, 1);
if (list != null && list.size() > 0) {
Address address = list.get(0);
// sending back first address line and locality
result = address.getAddressLine(0) + ", " + address.getLocality() + ", " + address.getCountryName() ;
Log.d(TAG, "The converted Address " + result);
}
} catch (IOException e) {
Log.e(TAG, "Impossible to connect to GeoCoder", e);
} finally {
Message msg = Message.obtain();
msg.setTarget(handler);
if (result != null) {
msg.what = 1;
Bundle bundle = new Bundle();
bundle.putString("address", result);
msg.setData(bundle);
} else
msg.what = 0;
msg.sendToTarget();
}
}
};
thread.start();
}
@SuppressLint("HandlerLeak")
private class GeoCoderHandler extends Handler {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case 1:
Bundle bundle = message.getData();
locationResult = bundle.getString("address");
Log.d(TAG, "Location Result " + locationResult);
break;
default:
locationResult = null;
}
}
}
@Override
public void onConnected(@Nullable Bundle bundle) {
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(@NonNull LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
Log.d(TAG, "Connection method has been called");
if(!hasPermissions(EventActivity.this, PERMISSIONS)){
ActivityCompat.requestPermissions(EventActivity.this, PERMISSIONS, PERMISSION_ALL);
}
else{
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastLocation != null){
getAddressFromLocation(mLastLocation.getLatitude(), mLastLocation.getLongitude(), EventActivity.this, new GeoCoderHandler());
}
}
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
break;
}
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSION_ALL: {
// If request is cancelled, the result arrays are empty.
if(grantResults[0] == PackageManager.PERMISSION_DENIED){
Toast.makeText(EventActivity.this, "Sorry!!!, you can't use this app without granting this permission", Toast.LENGTH_LONG).show();
finish();
}
if (grantResults[1] == PackageManager.PERMISSION_DENIED || grantResults[2] == PackageManager.PERMISSION_DENIED) {
// permission was denied, show alert to explain permission
showPermissionAlert();
}else{
//permission is granted. Get current location values
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}
}
}
}
}
private void showPermissionAlert(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.permission_request_title);
builder.setMessage(R.string.app_permission_notice);
builder.create();
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(!hasPermissions(EventActivity.this, PERMISSIONS)){
ActivityCompat.requestPermissions(EventActivity.this, PERMISSIONS, PERMISSION_ALL);
}
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(EventActivity.this, R.string.permission_refused, Toast.LENGTH_LONG).show();
}
});
builder.show();
}
protected LocationRequest createLocationRequest() {
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(3000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
return mLocationRequest;
}
@Override
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
@Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
public static boolean hasPermissions(Context context, String... permissions) {
if (android.os.Build.VERSION.SDK_INT >= M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
private boolean isLocationEnabled(){
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
}catch (Exception ex){}
try{
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}catch (Exception ex){}
if(!gps_enabled && !network_enabled){
return false;
}
return true;
}
private void showLocationAlert(){
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setMessage(getResources().getString(R.string.gps_enable));
dialog.setPositiveButton(getResources().getString(R.string.network_location), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
Intent myIntent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS);
EventActivity.this.startActivity(myIntent);
}
});
dialog.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
}
});
dialog.show();
}
private void moveFileToNewDestination(String fromPath, String toPath){
File fromFile = new File(fromPath);
File toFile = new File(toPath);
if(!toFile.exists()){
try {
toFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
FileInputStream fromStream = null;
FileOutputStream toStream = null;
try {
fromStream = new FileInputStream(fromFile);
toStream = new FileOutputStream(toFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
byte[] sourceByte = new byte[1024];
int index;
try {
while((index = fromStream.read(sourceByte)) > 0){
if (toStream != null) {
toStream.write(sourceByte, 0, index);
}
}
Log.d(TAG, "Video successfully moved to a new location");
} catch (IOException e) {
e.printStackTrace();
}
}
private String getFileDestinationPath(String filename){
String filePathEnvironment = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
File directoryFolder = new File(filePathEnvironment + "/events/");
if(!directoryFolder.exists()){
directoryFolder.mkdir();
}
Log.d(TAG, "Full path " + filePathEnvironment + "/events/" + filename);
return filePathEnvironment + "/events/" + filename;
}
private void uploadVideoToServer(String pathToVideoFile, String eventName, String eventDescription, String eventCoverage, String eventLocation){
File videoFile = new File(pathToVideoFile);
RequestBody videoBody = RequestBody.create(MediaType.parse("video/*"), videoFile);
MultipartBody.Part vFile = MultipartBody.Part.createFormData("video", videoFile.getName(), videoBody);
RequestBody event = RequestBody.create(MediaType.parse("text/plain"), eventName);
RequestBody description = RequestBody.create(MediaType.parse("text/plain"), eventDescription);
RequestBody name = RequestBody.create(MediaType.parse("text/plain"), eventCoverage);
RequestBody location = RequestBody.create(MediaType.parse("text/plain"), eventLocation);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(SERVER_PATH)
.addConverterFactory(GsonConverterFactory.create())
.build();
VideoInterface vInterface = retrofit.create(VideoInterface.class);
Call<ResultObject> serverCom = vInterface.uploadVideoToServer(vFile, event, description, name, location);
serverCom.enqueue(new Callback<ResultObject>() {
@Override
public void onResponse(Call<ResultObject> call, retrofit2.Response<ResultObject> response) {
ResultObject result = response.body();
if(!TextUtils.isEmpty(result.getSuccess()) && result.getSuccess().equals("1")){
Toast.makeText(EventActivity.this, getString(R.string.successful_upload), Toast.LENGTH_LONG).show();
resetViewControls();
}else{
Toast.makeText(EventActivity.this, getString(R.string.server_error), Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<ResultObject> call, Throwable t) {
Log.d(TAG, "Error message " + t.getMessage());
}
});
}
private void showOptionDialog(){
final Dialog dialog = new Dialog(EventActivity.this);
dialog.setTitle("SELECT ACTION TO COMPLETE");
dialog.setContentView(R.layout.image_video_layout);
final TextView takePhoto = (TextView)dialog.findViewById(R.id.take_photo);
final TextView recordVideo = (TextView)dialog.findViewById(R.id.record_video);
dialog.show();
takePhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "Take a picture");
if(isLocationEnabled()){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, TAKE_PICTURE);
}else{
showLocationAlert();
}
dialog.dismiss();
}
});
recordVideo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "Record a video");
Intent videoCaptureIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
if(videoCaptureIntent.resolveActivity(getPackageManager()) != null){
startActivityForResult(videoCaptureIntent, REQUEST_VIDEO_CAPTURE);
}
dialog.dismiss();
}
});
}
private boolean gps_enabled;
private boolean network_enabled;