J'essaie de créer un bouton qui ouvre l'appareil photo et prend une photo. mon code est ici
//for imports check on bottom of this code block
public class HomeProfileActivity extends AppCompatActivity {
//Button camera
public static final String TAG = HomeProfileActivity.class.getSimpleName();
public static final int REQUEST_TAKE_PHOTO = 0;
public static final int REQUEST_TAKE_VIDEO = 1;
public static final int REQUEST_PICK_PHOTO = 2;
public static final int REQUEST_PICK_VIDEO = 3;
public static final int MEDIA_TYPE_IMAGE = 4;
public static final int MEDIA_TYPE_VIDEO = 5;
private Uri mMediaUri;
private ImageView photobutton;
private Button buttonUploadImage, buttonTakeImage;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_profile);
ButterKnife.bind(this);
}
@OnClick(R.id.buttonTakeImage)
void takePhoto() {
mMediaUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
if (mMediaUri == null) {
Toast.makeText(this,
"There was a problem accessing your device's external storage.",
Toast.LENGTH_LONG).show();
}
else {
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, mMediaUri);
startActivityForResult(takePhotoIntent, REQUEST_TAKE_PHOTO);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK){
if (requestCode == REQUEST_TAKE_PHOTO) {
Intent intent = new Intent(this, ViewImageActivity.class);
intent.setData(mMediaUri);
startActivity(intent);
}
}
else if (resultCode != RESULT_CANCELED){
Toast.makeText(this, "Sorry, there was an error", Toast.LENGTH_SHORT).show();
}
}
private Uri getOutputMediaFileUri(int mediaType) {
// check for external storage
if (isExternalStorageAvailable()) {
// get the URI
// 1. Get the external storage directory
File mediaStorageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
// 2. Create a unique file name
String fileName = "";
String fileType = "";
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
if (mediaType == MEDIA_TYPE_IMAGE) {
fileName = "IMG_" + timeStamp;
fileType = ".jpg";
} else if (mediaType == MEDIA_TYPE_VIDEO) {
fileName = "VID_" + timeStamp;
fileType = ".mp4";
} else {
return null;
}
// 3. Create the file
File mediaFile;
try {
mediaFile = File.createTempFile(fileName, fileType, mediaStorageDir);
Log.i(TAG, "File: " + Uri.fromFile(mediaFile));
// 4. Return the file's URI
return Uri.fromFile(mediaFile);
}
catch (IOException e) {
Log.e(TAG, "Error creating file: " +
mediaStorageDir.getAbsolutePath() + fileName + fileType);
}
}
// something went wrong
return null;
}
private boolean isExternalStorageAvailable(){
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)){
return true;
}
else {
return false;
}
}
import Android.content.Intent;
import Android.content.SharedPreferences;
import Android.net.Uri;
import Android.os.Bundle;
import Android.os.Environment;
import Android.provider.MediaStore;
import Android.support.annotation.NonNull;
import Android.support.design.widget.BottomNavigationView;
import Android.support.v7.app.AppCompatActivity;
import Android.util.Log;
import Android.view.MenuItem;
import Android.view.View;
import Android.widget.Button;
import Android.widget.EditText;
import Android.widget.ImageView;
import Android.widget.TextView;
import Android.widget.Toast;
import Java.io.File;
import Java.io.IOException;
import Java.text.SimpleDateFormat;
import Java.util.Date;
import butterknife.ButterKnife;
import butterknife.OnClick;
J'ai également un problème avec startActivityForResult
dans la méthode onclick Et l'import Java.text.SimpleDateFormat;
également dans l'exécution à l'exception Je travaille avec buildtoolsversion sdk 25
Outre la solution utilisant FileProvider, il existe un autre moyen de contourner ce problème. Tout simplement
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
dans la méthode Application.onCreate (). De cette manière, le VM ignore l'exposition du fichier URI.
Cette information provient de: FileUriExposedException
Ceci n'est émis que pour les applications ciblant N ou plus . Les applications ciblant des versions antérieures du SDK sont autorisées à partager file: // Uri, mais c'est fortement déconseillé.
Ainsi, si la variable compileSdkVersion
(cible de génération) de votre fichier app/build.gradle
est Android N (niveau 24 de l'API) ou plus, cette erreur est générée si vous écrivez un fichier auquel d'autres applications peuvent éventuellement accéder. Plus important encore, voici comment vous êtes censé le faire pour aller de l'avant:
pris à partir d'ici: FileProvider
Changement:
return Uri.fromFile(mediaFile);
être
return FileProvider.getUriForFile(getApplicationContext(), getPackageName()+".fileprovider", mediaFile);
Remarque: si vous contrôlez mydomain.com
, vous pouvez également remplacer getPackageName()+".fileprovider"
par "com.mydomain.fileprovider"
(il en va de même pour votre AndroidManifest.xml
ci-dessous.
De plus, vous devez ajouter ce qui suit dans votre fichier AndroidManifest.xml
juste avant votre balise </application>
<provider
Android:name="Android.support.v4.content.FileProvider"
Android:authorities="${applicationId}.fileprovider"
Android:grantUriPermissions="true"
Android:exported="false">
<meta-data
Android:name="Android.support.FILE_PROVIDER_PATHS"
Android:resource="@xml/filepaths" />
</provider>
Ensuite, vous devez ajouter un fichier nommé filepaths.xml
à votre répertoire app/src/main/res/xml
avec le contenu suivant.
<paths>
<external-files-path name="Pictures" path="Pictures" />
</paths>
Remarque: pour quiconque, nous avons utilisé external-files-path
ci-dessus, car Omer a utilisé getExternalFilesDir(Environment.DIRECTORY_PICTURES)
dans le code. Pour tout autre emplacement, veuillez vérifier FileProvider dans la section "Spécification des fichiers disponibles" et remplacez external-files-path
par l'un des éléments suivants en fonction de l'emplacement de vos fichiers:
files-path
cache-path
external-path
external-files-path
external-cache-path
En outre, remplacez Pictures
ci-dessus par votre nom de dossier.
Un anti-motif important à éviter est que ET NON utilise if (Build.VERSION.SDK_INT < 24) {
pour vous permettre de le faire à l'ancienne, car ce n'est pas leur version Android qui le nécessite, c'est votre build version (j'ai raté ça la première fois que je l'ai codé).
Je sais que cela représente plus de travail, cependant, cela permet à Android d'autoriser uniquement l'accès temporaire au fichier de l'autre application avec laquelle vous partagez l'accès, ce qui est plus sécurisé pour la confidentialité de l'utilisateur.
Add the below code where the SharingIntent called:-
if(Build.VERSION.SDK_INT>=24){
try{
Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
m.invoke(null);
shareImage(Uri.fromFile(new File(Path)));
}catch(Exception e){
e.printStackTrace();
}
}