android本地相冊
❶ android的相冊在哪個文件夾里
/image
/camara
或者
/photo
/photos
應該就在主文件夾的根目錄里邊 沒有改動過的話目錄不會太深
❷ Android 保存圖片到本地。
這里只介紹按下「保存」後如何將一個Bitmap對象保存為圖片文件的執行步驟,對圖片的下載,圖片到Bitmap對象的轉換,Bitmap對象的格式轉換和壓縮,以及界面設計部分全部都忽略了。
確定存儲路徑
獲取外部存儲許可權
確定外部存儲狀態
確定文件名
保存到文件中
發送廣播,通知系統掃描保存後的文件
Stringdir=Environment.getExternalStorageDirectory().getAbsolutePath()+"/tencent/MicroMsg/WeiXin/"
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
//獲取內部存儲狀態
Stringstate=Environment.getExternalStorageState();
//如果狀態不是mounted,無法讀寫
if(!state.equals(Environment.MEDIA_MOUNTED)){
return;
}
隨機命名
這種命名規則是隨機生成一個字元串或一組數字來對圖片命名。
字元串可以通過UUID來生成,數字可以通過Random()類來生成,例如:[java]view plain
//通過UUID生成字元串文件名
StringfileName1=UUID.randomUUID().toString();
//通過Random()類生成數組命名
Randomrandom=newRandom();
StringfileName2=String.valueOf(random.nextInt(Integer.MAX_VALUE));
這種命名規則是按照數字從小到大的順序來對圖片命名。
在程序啟動時先獲取圖片文件名中當前最大數字的文件名,之後每保存一張圖片就將數字加1即可。時間命名
這種命名規則是根據保存圖片的當前系統時間來對圖片命名。
系統時間可以通過System.currentTimeMillis()來獲取,不過System.currentTimeMillis()獲取到的時間是一個long型的整數,如果用它做文件名,無法通過文件名直接看出文件的具體保存時間。可以通過SimpleDateFormat先對當前時間做格式化,然後再將其作為文件名來使用。例如:[java]view plain
使用這種命名規則來命名需要注意的是同一秒鍾可能會有多張圖片需要保存,在得到當前系統時間對應的文件名後,需要判斷該文件是否存在。如果文件已經存在,需要重新生成文件名。重新生成的文件名可以在之前的文件名後加上一個隨機數後綴,或者是用毫秒數做後綴。
Calendarnow=newGregorianCalendar();
SimpleDateFormatsimpleDate=newSimpleDateFormat("yyyyMMddHHmmss",Locale.getDefault());
StringfileName=simpleDate.format(now.getTime());
文件URL命名
每張網路圖片都有一個對應的圖片URL,可以根據圖片的URL來對圖片命名。
不過URL中會包含一些不能用作文件名的特殊字元,此外直接用URL來命名可能會帶來安全問題。為了避免這兩個問題,可以將圖片URL的MD5值作為文件名來使用。由於MD5是不可逆的,也就無法通過MD5值反向得到圖片URL,同時MD5值對應的字元串只包含[0-9A-Z],不包含特殊字元,可是作為文件名使用。
由於每張圖片的URL是唯一的,其對應的文件名也就是唯一的。如果需要每張網路圖片只能生成一個文件,不允許保存為多份拷貝,可以用這種命名規則。在得到URL對應的文件名後,先判斷文件是否已經存在,如果已經存在,直接覆蓋或不處理。try{
Filefile=newFile(dir+fileName+".jpg");
FileOutputStreamout=newFileOutputStream(file);
mBitmap.compress(Bitmap.CompressFormat.JPEG,100,out);
out.flush();
out.close();
}catch(Exceptione){
e.printStackTrace();
}
try{
Filefile=newFile(dir+fileName+".jpg");
FileOutputStreamout=newFileOutputStream(file);
mBitmap.compress(Bitmap.CompressFormat.JPEG,100,out);
out.flush();
out.close();
//保存圖片後發送廣播通知更新資料庫
Uriuri=Uri.fromFile(file);
sendBroadcast(newIntent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,uri));
}catch(Exceptione){
e.printStackTrace();
}
確定存儲路徑
在Android中文件存儲路徑包括內部存儲和外部存儲兩種類型。
對內部存儲,當一個app被安裝到手機後,Android系統會在內部存儲的/data/data/目錄下創建一個以包名稱命名的文件夾。例如/data/data/com.sohu.inputmethod.sogou/。一個應用對內部存儲的所有訪問都被限制在這個文件夾中,也就是說Android應用只能在該目錄中讀取,創建,修改文件。對該目錄之外的其他內部存儲中的目錄都沒有任何操作的許可權。因此,如果將圖片保存在內部存儲中,只能被應用自身讀取,其他應用均無法讀取。如果需要讓系統圖庫,相冊或其他應用能夠找到保存的圖片,必須將圖片保存到外部存儲中。
對外部存儲,當一個app被安裝到手機後,Android系統會在外部存儲的/Android/data/目錄下創建一個以包名命名的文件夾(這里第一個/不是根路徑,而是相對外部存儲所掛載路徑的相對路徑)。例如/storage/emulated/0/Android/data/com.sohu.inputmethod/。這個路徑同樣只能被應用自身讀取,其他應用不能訪問。因此,也不能將圖片保存在這個目錄中。
除外部存儲的/Android目錄之外的其他目錄一般都是可以被其他應用訪問的。目前,大多數應用都會在外部存儲的根路徑下建立一個類似包名的多層目錄,以存儲需要共享的文件。例如/storage/emulated/0/sogou/image/。還需要注意的是,很多查看圖片的應用都支持按照文件夾來查看圖片。如果將圖片所在的文件夾取名為image,photo之類的,就無法和其他文件夾區分開,用戶也不能識別該文件夾的用途。因此最好取一個有區分度的文件夾名字,例如網路貼吧就保存在/tieba目錄,微信是保存在/tencent/MicroMsg/WeiXin目錄。
由於Android系統的碎片化問題,不同設備上外部存儲的路徑很可能會不同,因此,不能直接使用/storage/emulated/0/作為外部存儲的根路徑。
Android SDK中 Environment類 提供了getExternalStorageDirectory()方法來獲取外部存儲的根路徑。示例如下:
[java]view plain
需要注意的是Environment.getExternalStorageDirectory()返回的路徑中最後一個字元不是/,如果需要創建子目錄,需要在子目錄的前後都加上/。
獲取外部存儲許可權
由於需要在外部存儲中寫文件,需要在AndroidManifest.xml中增加如下的許可權聲明。
[java]view plain
確定外部存儲狀態
由於外部存儲需要被掛載,也可以被卸載,在寫入文件之前,需要先判斷外部存儲的狀態是否正常。只有狀態正常情況下才可以執行保存文件的操作。獲取外部存儲狀態同樣是通過Environment類,通過Environment.getExternalStorageState()可以得到一個字元串,來表示外部存儲的狀態。同時在Environment類中定義了一系列的String常量表示不同的狀態。在所有的狀態中只有內部存儲處於Environment.MEDIA_MOUNTED狀態時才可以讀寫文件,因此,需要將獲取到的狀態和Environment.MEDIA_MOUNTED做比較,如果不是Environment.MEDIA_MOUNTED狀態,就返回保存失敗。示例如下。
[java]view plain
確定文件名
保存的圖片文件名可以由應用根據自身需要自行確定,一般來說需要有一個命名規則,然後根據命名規則計算得到文件名。
這里列舉幾種常見的命名規則。
保存到文件中
保存圖片文件時,通過Bitmap的compress()方法將Bitmap對象壓縮到一個文件輸出流中,然後flush()即可。示例如下。
[java]view plain
發送廣播,通知系統掃描保存後的文件
至此,已經實現將Bitmap對象保存成外部存儲中的一個jpg格式的文件。但此時該文件只是保存在外部存儲的一個目錄中,必須進入其所在的目錄中才可以看到。在系統圖庫,相冊和其他應用中無法看到新建的圖片文件。為了讓其他應用能夠知道圖片文件被創建,必須通知MediaProvider服務將新建的文件添加到圖片資料庫中。
Android系統中常駐一個MediaProvider服務,對應的進程名為android.process.media,此服務用來管理本機上的媒體文件,提供媒體管理服務。在系統開機或者收到外部存儲的掛載消息後,MediaProvider會調用MediaScanner,MediaScanner會掃描外部存儲中的所有文件,根據文件類型的後綴將文件信息保存到對應的資料庫中,供其他APP使用。
MediaScannerReceiver是一個廣播接收者,當它接收到特定的廣播請求後,就會去掃描指定的文件,並根據文件信息將其添加到資料庫中。當圖片文件被創建後,就可以發送廣播給MediaScannerReceiver,通知其掃描新建的圖片文件。示例如下。
[java]view plain
圖片的非同步保存
保存圖片文件時,如果圖片很大,或需要同時保存多張圖片時,就需要較多的時間。為了避免阻塞UI線程,出現幀率下降或ANR,通常需要將圖片保存操作放到線程中去執行。當圖片保存完畢後通過sendMessage()方法通知UI線程保存結果。
將圖片保存放到後台線程去執行需要增加一些同步機制避免一些多線程問題。例如有兩張圖片需要保存,分別放到兩個線程中去執行,保存圖片時文件名以數字順序增加。第一個線程選中文件名為125.jpg,但此時文件還未創建,第二個線程判斷125.jpg不存在,於是也選取125.jpg作為文件名,兩張圖片就保存到同一個文件中了。
❸ Android WebView 調用系統拍照和相冊
由於業務需要,APP內嵌H5,需要調去系統相冊和拍照,網上找了點資料,整理一下,供大家參考:
private static final int REQUEST_CAMERA =1;
private static final int REQUEST_CHOOSE =2;
private ValueCallbackmUploadMessage;
private ;
private UricameraUri;
//5.0以後的方法
webView.setWebChromeClient(new WebChromeClient() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) {
if (mUploadMessagesAboveL !=null) {
mUploadMessagesAboveL.onReceiveValue(null);
mUploadMessagesAboveL =null;
}else {
mUploadMessagesAboveL = filePathCallback;
selectImage();
}
return true;
}
});
//選擇圖片和拍照,對應的string文件,可以自己寫死:拍照,相冊,取消
private void selectImage() {
ActionSheet.createBuilder(this, getSupportFragmentManager()).
setOtherButtonTitles(new String[]{getResources().getString(R.string.common_tip_photos), getResources().getString(R.string.common_picture)}).
setCancelButtonTitle(getResources().getString(R.string.common_cancel)).setCancelableOnTouchOutside(true).setListener(new ActionSheet.ActionSheetListener() {
public void onDismiss(ActionSheet actionSheet, boolean isCancel) {
if (mUploadMessage !=null) {
mUploadMessage.onReceiveValue(null);
mUploadMessage =null;
}
if (mUploadMessagesAboveL !=null) {
mUploadMessagesAboveL.onReceiveValue(null);
mUploadMessagesAboveL =null;
}
actionSheet.dismiss();
}
@RequiresApi(api = Build.VERSION_CODES.M)
public void onOtherButtonClick(ActionSheet actionSheet, int index) {
switch (index) {
case 0:
chosePicture();
break;
case 1:
setRequestCamera();
}
}
}).show();
}
//拍照,添加許可權申請 這個可以自己寫下,我這邊是項目中寫好的,直接拿過來用了
public void setRequestCamera() {
permissionsBuilder =new YXTPermissionsBuilder.Builder(this)
.setOnGrantedListener((requestCode, perms) -> {
openCamera();
})
.setRationale4NeverAskAgain(LanguageUtils.isEnglish() ? String.format(getString(R.string.permission_tips), getString(R.string.common_camera), getString(R.string.app_name), getString(R.string.app_name)) :
String.format(getString(R.string.permission_tips), getString(R.string.app_name), getString(R.string.common_camera), getString(R.string.app_name)))
//必需
.setRequestCode(ConstantsData.GET_CAMERA)
.build();
permissionsBuilder.requestPermissions(Manifest.permission.CAMERA);
}
/**
* 本地相冊選擇圖片
*/
private void chosePicture() {
Intent innerIntent =new Intent(Intent.ACTION_GET_CONTENT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
innerIntent.setType("image/*");
Intent wrapperIntent = Intent.createChooser(innerIntent, null);
startActivityForResult(wrapperIntent, REQUEST_CHOOSE);
}
/**
* 打開照相機
*/
private void openCamera() {
Intent intent =new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String imagePaths = Environment.getExternalStorageDirectory().getPath() +"/pbccrc/Images/" + (System.currentTimeMillis() +".jpg");
// 必須確保文件夾路徑存在,否則拍照後無法完成回調
File vFile =new File(imagePaths);
if (!vFile.exists()) {
File vDirPath = vFile.getParentFile();
vDirPath.mkdirs();
}else {
if (vFile.exists()) {
vFile.delete();
}
}
cameraUri = FileProvider.getUriForFile(
this,
getPackageName() +".fileprovider",
vFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri);
startActivityForResult(intent, REQUEST_CAMERA);
}
/**
* 選擇照片後結束
*
* @param data
*/
private UriafterChosePic(Intent data) {
if (data !=null) {
final String path = data.getData().getPath();
if (path !=null && (path.endsWith(".png") || path.endsWith(".PNG") || path.endsWith(".jpg") || path.endsWith(".JPG"))) {
return data.getData();
}else {
Toast.makeText(this, "上傳的圖片僅支持png或jpg格式", Toast.LENGTH_SHORT).show();
}
}
return null;
}
/**
* 返迴文件選擇
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (mUploadMessagesAboveL !=null) {
onActivityResultAboveL(requestCode, resultCode, intent);
}
if (mUploadMessage ==null)return;
Uri uri =null;
if (requestCode ==REQUEST_CAMERA && resultCode ==RESULT_OK) {
uri =cameraUri;
Log.e("onActivityResult: " + uri.toString());
}
if (requestCode ==REQUEST_CHOOSE && resultCode ==RESULT_OK) {
uri = afterChosePic(intent);
}
mUploadMessage.onReceiveValue(uri);
mUploadMessage =null;
super.onActivityResult(requestCode, resultCode, intent);
}
/**
* 5.0以後機型 返迴文件選擇
*
* @param requestCode
* @param resultCode
* @param data
*/
private void onActivityResultAboveL(int requestCode, int resultCode, Intent data) {
Uri[] results =null;
if (requestCode ==REQUEST_CAMERA && resultCode ==RESULT_OK) {
results =new Uri[]{cameraUri};
}
if (requestCode ==REQUEST_CHOOSE && resultCode ==RESULT_OK) {
if (data !=null) {
String dataString = data.getDataString();
if (dataString !=null)
results =new Uri[]{Uri.parse(dataString)};
}
}
mUploadMessagesAboveL.onReceiveValue(results);
mUploadMessagesAboveL =null;
return;
}
基本都可以拿去用了,希望有幫助
❹ android中怎麼調取手機本地相冊
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
// 開啟一個帶有返回值的Activity,請求碼為100
startActivityForResult(intent, 100);
❺ Android開發中怎麼將照片存儲到系統相冊中
//創建輸出流,指向SD卡的Pictures文件夾
finalFiledirectory=Environment.(Environment.DIRECTORY_DCIM);
//創建保存的文件
Filefile=newFile(directory,"test.png");
FileOutputStreamout=null;
try{
out=newFileOutputStream(file);
}catch(FileNotFoundExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}finally{
}
//bitmap就是你的圖片
bitmap.compress(Bitmap.CompressFormat.PNG,100,out);
❻ 如何調用android的拍照或本地相冊選取,然後再實現相片上傳伺服器
首先是拍照:使用Intent即可,
[java] view plainprint?
01.final String start = Environment.getExternalStorageState();
02.private static final String PHOTOPATH = "/photo/";
03.
04.if(start.equals(Environment.MEDIA_MOUNTED)){
05.Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
06.File file = new File(Environment.getExternalStorageDirectory()+PHOTOPATH);
07.if(!file.exists()){
08.file.mkdirs();
09.}
10.tempphontname = System.currentTimeMillis()+".jpg";
11.buffer.append(Environment.getExternalStorageDirectory()+PHOTOPATH).append(tempphontname);
12.intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(buffer.toString())));
13.startActivityForResult(intent, 1);
14.}
final String start = Environment.getExternalStorageState();
private static final String PHOTOPATH = "/photo/";
if(start.equals(Environment.MEDIA_MOUNTED)){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory()+PHOTOPATH);
if(!file.exists()){
file.mkdirs();
}
tempphontname = System.currentTimeMillis()+".jpg";
buffer.append(Environment.getExternalStorageDirectory()+PHOTOPATH).append(tempphontname);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(buffer.toString())));
startActivityForResult(intent, 1);
}
其次是從本地相冊選:依舊是Intent.
如下代碼:
[java] view plainprint?
01.if(start.equals(Environment.MEDIA_MOUNTED)){
02. Intent getImage = new Intent(Intent.ACTION_GET_CONTENT);
03. getImage.addCategory(Intent.CATEGORY_OPENABLE);
04. getImage.setType("image/jpeg");
05. startActivityForResult(getImage, 0);
06.}
if(start.equals(Environment.MEDIA_MOUNTED)){
Intent getImage = new Intent(Intent.ACTION_GET_CONTENT);
getImage.addCategory(Intent.CATEGORY_OPENABLE);
getImage.setType("image/jpeg");
startActivityForResult(getImage, 0);
}
接下來是主要的:因為調用完系統的方法後,回返回到回調方法onActivityResult(int, int, Intent)中,
在裡面進行主要的照片上傳伺服器的操作,
見代碼:
[java] view plainprint?
01.@Override
02. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
03. ContentResolver resolver = getContentResolver();
04. if(requestCode==1)//
05. {
06. if(resultCode==Activity.RESULT_OK)
07. {
08. if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
09. {
10.ew Thread(new Runnable()
11. {
12. @Override
13. public void run() {
14.//進行上傳操作
15.}
16.}.start();
轉載
❼ Android手機相冊在哪裡 我是ST18I 平時拍的相片在哪個 文件夾裡面
一般是在內存卡上:如:我的手機連上電腦,顯示是J盤,那麼相機文件夾就是
J:\DCIM\100ANDRO
也就是說是在內存卡的DCIM這個文件家內!
❽ Android 使用系統相機拍照和讀取相冊照片
1.拍照 (對於7.0以上的版本,不在允許直接訪問uri)
`
若不指定輸出路徑intent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri(srcActivity)); 在onActivityResult()中,通過
`
可以拿到uri,但獲得的圖片是被壓縮過的。若指定intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);輸出路徑,則此處的intent為null,但可以使用我們存的uri讀取照片,此時的照片沒有被壓縮。
2.從相冊中讀取照片, 方法:
`
`
即使設置 intent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri(srcActivity));輸出路徑,仍然不能從此路徑中讀取,只能在onActivityForResult()中通過event.uri = intent.getData();方式獲得圖片uri。
此種現象也好理解,拍照時產生新的圖片,自然可根據設置的uri進行圖片保存,而讀取相冊時,圖片已經在目錄中不能轉移到自己設定的uri中。
Androidmanifest.xml中
`
在 res/xml/provider_paths.xml
`
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="JDTobs" path=""/>
<files-path name="name" path="path" />
<cache-path name="name" path="path" /> <external-path name="name" path="path" />
<external-files-path name="name" path="path" />
<external-cache-path name="name" path="path" /> </paths> `
讀取uri