@ -15,21 +15,7 @@
* /
package net.micode.notes.ui ;
import android.Manifest ;
import android.annotation.SuppressLint ;
import android.content.ContentResolver ;
import android.content.ContentValues ;
import android.database.Cursor ;
import android.graphics.Bitmap ;
import android.graphics.BitmapFactory ;
import android.net.Uri ;
import android.os.Build ;
import android.os.Environment ;
import android.provider.DocumentsContract ;
import android.provider.MediaStore ;
import android.speech.tts.TextToSpeech.OnInitListener ;
import android.app.AlarmManager ;
import android.app.AlertDialog ;
import android.app.Dialog ;
@ -44,8 +30,6 @@ import android.content.SharedPreferences;
import android.graphics.Paint ;
import android.os.Bundle ;
import android.preference.PreferenceManager ;
import android.speech.tts.TextToSpeech ;
import android.support.v4.app.ActivityCompat ;
import android.support.v7.app.AppCompatActivity ;
import android.text.Editable ;
import android.text.Spannable ;
@ -54,7 +38,6 @@ import android.text.TextUtils;
import android.text.TextWatcher ;
import android.text.format.DateUtils ;
import android.text.style.BackgroundColorSpan ;
import android.text.style.ImageSpan ;
import android.util.Log ;
import android.view.LayoutInflater ;
import android.view.Menu ;
@ -69,7 +52,6 @@ import android.widget.CheckBox;
import android.widget.CompoundButton ;
import android.widget.CompoundButton.OnCheckedChangeListener ;
import android.widget.EditText ;
import android.widget.ImageButton ;
import android.widget.ImageView ;
import android.widget.LinearLayout ;
import android.widget.TextView ;
@ -83,15 +65,17 @@ import net.micode.notes.model.WorkingNote.NoteSettingChangedListener;
import net.micode.notes.tool.DataUtils ;
import net.micode.notes.tool.ResourceParser ;
import net.micode.notes.tool.ResourceParser.TextAppearanceResources ;
import net.micode.notes.ui.AlarmReceiver ;
import net.micode.notes.ui.DateTimePickerDialog ;
import net.micode.notes.ui.DateTimePickerDialog.OnDateTimeSetListener ;
import net.micode.notes.ui.NoteEditText ;
import net.micode.notes.ui.NoteEditText.OnTextViewChangeListener ;
import net.micode.notes.ui.NotesPreferenceActivity ;
import net.micode.notes.widget.NoteWidgetProvider_2x ;
import net.micode.notes.widget.NoteWidgetProvider_4x ;
import java.io.FileNotFoundException ;
import java.util.HashMap ;
import java.util.HashSet ;
import java.util.Locale ;
import java.util.Map ;
import java.util.regex.Matcher ;
import java.util.regex.Pattern ;
@ -110,10 +94,6 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
public ImageView ibSetBgColor ;
}
//使用Map实现数据存储
final String [ ] mPermissionList = new String [ ] {
Manifest . permission . WRITE_EXTERNAL_STORAGE ,
Manifest . permission . READ_EXTERNAL_STORAGE } ;
private static final Map < Integer , Integer > sBgSelectorBtnsMap = new HashMap < Integer , Integer > ( ) ;
static {
sBgSelectorBtnsMap . put ( R . id . iv_bg_yellow , ResourceParser . YELLOW ) ;
@ -155,7 +135,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
private static final String TAG = "NoteEditActivity" ;
private HeadViewHolder mNoteHeaderHolder ;
private TextToSpeech mTTS ;
private View mHeadViewPanel ;
//私有化一个界面操作mHeadViewPanel, 对表头的操作
private View mNoteBgColorSelector ;
@ -178,8 +158,6 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
private static final int SHORTCUT_ICON_TITLE_MAX_LEN = 10 ;
private static final int PHOTO_REQUEST = 1 ;
public static final String TAG_CHECKED = String . valueOf ( '\u221A' ) ;
public static final String TAG_UNCHECKED = String . valueOf ( '\u25A1' ) ;
@ -191,7 +169,6 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
//字符数量计数显示
private TextView textView ;
@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState ) ;
@ -203,25 +180,6 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
}
initResources ( ) ;
count ( ) ;
read ( ) ;
//根据id获取添加图片按钮
final ImageButton add_img_btn = ( ImageButton ) findViewById ( R . id . add_img_btn ) ;
//为点击图片按钮设置监听器
add_img_btn . setOnClickListener ( new View . OnClickListener ( ) {
@Override
public void onClick ( View view ) {
Log . d ( TAG , "onClick: click add image button" ) ;
//ACTION_GET_CONTENT: 允许用户选择特殊种类的数据,并返回(特殊种类的数据:照一张相片或录一段音)
Intent loadImage = new Intent ( Intent . ACTION_GET_CONTENT ) ;
//Category属性用于指定当前动作( Action) 被执行的环境.
//CATEGORY_OPENABLE; 用来指示一个ACTION_GET_CONTENT的intent
loadImage . addCategory ( Intent . CATEGORY_OPENABLE ) ;
loadImage . setType ( "image/*" ) ;
startActivityForResult ( loadImage , PHOTO_REQUEST ) ;
}
} ) ;
}
/ * *
@ -342,7 +300,8 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
}
private void initNoteScreen ( ) {
//对界面的初始化操作
//对便签的初始化操作
mNoteEditor . setTextAppearance ( this , TextAppearanceResources
. getTexAppearanceResource ( mFontSizeId ) ) ;
//设置外观
@ -367,7 +326,6 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
* TODO : Add the menu for setting alert . Currently disable it because the DateTimePicker
* is not ready
* /
convertToImage ( ) ;
showAlertHeader ( ) ;
}
//设置闹钟的显示
@ -448,26 +406,12 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
}
private void initResources ( ) {
mTTS = new TextToSpeech ( this , new OnInitListener ( ) {
@Override
public void onInit ( int status ) {
if ( status = = TextToSpeech . SUCCESS ) {
int result = mTTS . setLanguage ( Locale . US ) ;
if ( result ! = TextToSpeech . LANG_COUNTRY_AVAILABLE & & result ! = TextToSpeech . LANG_AVAILABLE ) {
//Toast. makeText( CodeView. this, " TTS暂时不支持这种语言朗读" , 50000) . show();
}
}
}
} ) ;
mHeadViewPanel = findViewById ( R . id . note_title ) ;
mNoteHeaderHolder = new HeadViewHolder ( ) ;
mNoteHeaderHolder . tvModified = ( TextView ) findViewById ( R . id . tv_modified_date ) ;
mNoteHeaderHolder . ivAlertIcon = ( ImageView ) findViewById ( R . id . iv_alert_icon ) ;
mNoteHeaderHolder . tvAlertDate = ( TextView ) findViewById ( R . id . tv_alert_date ) ;
mNoteHeaderHolder . ibSetBgColor = ( ImageView ) findViewById ( R . id . btn_set_bg_color ) ;
mNoteHeaderHolder . ibSetBgColor = ( ImageView ) findViewById ( R . id . image_button ) ;
mNoteHeaderHolder . ibSetBgColor . setOnClickListener ( this ) ;
mNoteEditor = ( EditText ) findViewById ( R . id . note_edit_view ) ;
mNoteEditorPanel = findViewById ( R . id . sv_note_edit ) ;
@ -525,13 +469,11 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
public void onClick ( View v ) {
int id = v . getId ( ) ;
if ( id = = R . id . btn_set_bg_color ) {
if ( id = = R . id . image_button ) {
mNoteBgColorSelector . setVisibility ( View . VISIBLE ) ;
findViewById ( sBgSelectorSelectionMap . get ( mWorkingNote . getBgColorId ( ) ) ) . setVisibility (
View . VISIBLE ) ;
findViewById ( sBgSelectorSelectionMap . get ( mWorkingNote . getBgColorId ( ) ) ) . setVisibility ( View . VISIBLE ) ;
} else if ( sBgSelectorBtnsMap . containsKey ( id ) ) {
findViewById ( sBgSelectorSelectionMap . get ( mWorkingNote . getBgColorId ( ) ) ) . setVisibility (
View . GONE ) ;
findViewById ( sBgSelectorSelectionMap . get ( mWorkingNote . getBgColorId ( ) ) ) . setVisibility ( View . GONE ) ;
mWorkingNote . setBgColorId ( sBgSelectorBtnsMap . get ( id ) ) ;
mNoteBgColorSelector . setVisibility ( View . GONE ) ;
} else if ( sFontSizeBtnsMap . containsKey ( id ) ) {
@ -547,8 +489,6 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
TextAppearanceResources . getTexAppearanceResource ( mFontSizeId ) ) ;
}
mFontSizeSelector . setVisibility ( View . GONE ) ;
} else if ( id = = R . id . read_note ) {
mTTS . speak ( mNoteEditor . getText ( ) . toString ( ) , TextToSpeech . QUEUE_FLUSH , null ) ;
}
} //************************存在问题
@ -603,15 +543,11 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
menu . findItem ( R . id . menu_alert ) . setVisible ( false ) ;
} else {
menu . findItem ( R . id . menu_delete_remind ) . setVisible ( false ) ;
} if ( mWorkingNote . getTopId ( ) = = 1 ) {
menu . findItem ( R . id . menu_top ) . setTitle ( "Cancel top" ) ;
} else {
menu . findItem ( R . id . menu_top ) . setTitle ( "Top" ) ;
}
return true ;
}
@Override
/ *
* 函 数 功 能 : 动 态 改 变 菜 单 选 项 内 容
@ -620,6 +556,16 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
public boolean onOptionsItemSelected ( MenuItem item ) {
switch ( item . getItemId ( ) ) {
//根据菜单的id来编剧相关项目
case R . id . bk_pic1 : {
mNoteEditorPanel . setBackground ( getResources ( ) . getDrawable ( R . drawable . pic_one ) ) ;
findViewById ( sBgSelectorSelectionMap . get ( mWorkingNote . getBgColorId ( ) ) ) . setVisibility ( View . GONE ) ;
break ;
}
case R . id . bk_pic2 : {
mNoteEditorPanel . setBackground ( getResources ( ) . getDrawable ( R . drawable . pic2 ) ) ;
findViewById ( sBgSelectorSelectionMap . get ( mWorkingNote . getBgColorId ( ) ) ) . setVisibility ( View . GONE ) ;
break ;
}
case R . id . locker :
//为便签上锁
final AlertDialog . Builder create_password = new AlertDialog . Builder ( this ) ;
@ -670,9 +616,9 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
mWorkingNote . setPassword ( "" , "" ) ;
Toast . makeText ( NoteEditActivity . this , "Password unlocked successfully" , Toast . LENGTH_SHORT ) . show ( ) ;
break ;
case R . id . menu_ top :
// 置顶 便签
mWorkingNote. setTop ( ( mWorkingNote . getTopId ( ) ) = = 1 ? "0" : "1" ) ;
case R . id . menu_ new_note :
// 创建一个新的 便签
createNewNote( ) ;
break ;
case R . id . menu_delete :
//删除便签
@ -741,7 +687,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
* 函 数 实 现 : 如 下 注 释
* /
private void setReminder ( ) {
net. micode . notes . ui . DateTimePickerDialog d = new net. micode . notes . ui . DateTimePickerDialog( this , System . currentTimeMillis ( ) ) ;
DateTimePickerDialog d = new DateTimePickerDialog( this , System . currentTimeMillis ( ) ) ;
// 建立修改时间日期的对话框
d . setOnDateTimeSetListener ( new OnDateTimeSetListener ( ) {
public void OnDateTimeSet ( AlertDialog dialog , long date ) {
@ -833,7 +779,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
* 函 数 实 现 : 直 接 看 NotesPreferenceActivity 中 同 步 名 称 是 否 为 空
* /
private boolean isSyncMode ( ) {
return net. micode . notes . ui . NotesPreferenceActivity. getSyncAccountName ( this ) . trim ( ) . length ( ) > 0 ;
return NotesPreferenceActivity. getSyncAccountName ( this ) . trim ( ) . length ( ) > 0 ;
}
/ *
@ -850,7 +796,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
saveNote ( ) ;
}
if ( mWorkingNote . getNoteId ( ) > 0 ) {
Intent intent = new Intent ( this , net. micode . notes . ui . AlarmReceiver. class ) ;
Intent intent = new Intent ( this , AlarmReceiver. class ) ;
intent . setData ( ContentUris . withAppendedId ( Notes . CONTENT_NOTE_URI , mWorkingNote . getNoteId ( ) ) ) ;
//若有有运行的便签就是建立一个链接器将标签id都存在uri中
PendingIntent pendingIntent = PendingIntent . getBroadcast ( this , 0 , intent , 0 ) ;
@ -893,19 +839,19 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
}
//没有编辑框的话直接返回
for ( int i = index + 1 ; i < childCount ; i + + ) {
( ( net. micode . notes . ui . NoteEditText) mEditTextList . getChildAt ( i ) . findViewById ( R . id . et_edit_text ) )
( ( NoteEditText) mEditTextList . getChildAt ( i ) . findViewById ( R . id . et_edit_text ) )
. setIndex ( i - 1 ) ;
//通过id把编辑框存在便签编辑框中
}
mEditTextList . removeViewAt ( index ) ;
//删除特定位置的视图
net. micode . notes . ui . NoteEditText edit = null ;
NoteEditText edit = null ;
if ( index = = 0 ) {
edit = ( net. micode . notes . ui . NoteEditText) mEditTextList . getChildAt ( 0 ) . findViewById (
edit = ( NoteEditText) mEditTextList . getChildAt ( 0 ) . findViewById (
R . id . et_edit_text ) ;
} else {
edit = ( net. micode . notes . ui . NoteEditText) mEditTextList . getChildAt ( index - 1 ) . findViewById (
edit = ( NoteEditText) mEditTextList . getChildAt ( index - 1 ) . findViewById (
R . id . et_edit_text ) ;
}
//通过id把编辑框存在空的NoteEditText中
@ -931,11 +877,11 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
View view = getListItem ( text , index ) ;
mEditTextList . addView ( view , index ) ;
//建立一个新的视图并添加到编辑文本框内
net. micode . notes . ui . NoteEditText edit = ( net. micode . notes . ui . NoteEditText) view . findViewById ( R . id . et_edit_text ) ;
NoteEditText edit = ( NoteEditText) view . findViewById ( R . id . et_edit_text ) ;
edit . requestFocus ( ) ; //请求优先操作
edit . setSelection ( 0 ) ; //定位到起始位置
for ( int i = index + 1 ; i < mEditTextList . getChildCount ( ) ; i + + ) {
( ( net. micode . notes . ui . NoteEditText) mEditTextList . getChildAt ( i ) . findViewById ( R . id . et_edit_text ) )
( ( NoteEditText) mEditTextList . getChildAt ( i ) . findViewById ( R . id . et_edit_text ) )
. setIndex ( i ) ;
//遍历子文本框并设置对应对下标
}
@ -1000,7 +946,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
private View getListItem ( String item , int index ) {
View view = LayoutInflater . from ( this ) . inflate ( R . layout . note_edit_list_item , null ) ;
//创建一个视图
final net. micode . notes . ui . NoteEditText edit = ( net. micode . notes . ui . NoteEditText) view . findViewById ( R . id . et_edit_text ) ;
final NoteEditText edit = ( NoteEditText) view . findViewById ( R . id . et_edit_text ) ;
edit . setTextAppearance ( this , TextAppearanceResources . getTexAppearanceResource ( mFontSizeId ) ) ;
//创建一个文本编辑框并设置可见性
CheckBox cb = ( ( CheckBox ) view . findViewById ( R . id . cb_edit_item ) ) ;
@ -1087,7 +1033,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
for ( int i = 0 ; i < mEditTextList . getChildCount ( ) ; i + + ) {
View view = mEditTextList . getChildAt ( i ) ;
//遍历所有子编辑框的视图
net. micode . notes . ui . NoteEditText edit = ( net. micode . notes . ui . NoteEditText) view . findViewById ( R . id . et_edit_text ) ;
NoteEditText edit = ( NoteEditText) view . findViewById ( R . id . et_edit_text ) ;
if ( ! TextUtils . isEmpty ( edit . getText ( ) ) ) {
//若文本不为空
if ( ( ( CheckBox ) view . findViewById ( R . id . cb_edit_item ) ) . isChecked ( ) ) {
@ -1215,8 +1161,8 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
int flag1 = - 1 ;
int flag2 = - 1 ;
do { //不计入表示图片的字符
flag1 = stringBuffer . indexOf ( " [local] ") ;
flag2 = stringBuffer . indexOf ( " [/local]") + 7 ;
flag1 = stringBuffer . indexOf ( " <img ") ;
flag2 = stringBuffer . indexOf ( " >") ;
if ( flag1 ! = - 1 & & flag2 ! = - 1 ) {
stringBuffer = stringBuffer . replace ( flag1 , flag2 + 1 , "" ) ;
}
@ -1261,215 +1207,6 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
public void afterTextChanged ( Editable s ) {
textView . setText ( "字符数: " + currentLength ) ;
}
} ) ;
}
public void read ( ) {
ImageButton read = findViewById ( R . id . read_note ) ;
read . setOnClickListener ( new OnClickListener ( ) {
@Override
public void onClick ( View v ) {
mTTS . speak ( TextChange ( mNoteEditor . getText ( ) . toString ( ) ) , TextToSpeech . QUEUE_FLUSH , null ) ;
}
} ) ;
}
// final String[] mPermissionList = new String[]{
// Manifest.permission.WRITE_EXTERNAL_STORAGE,
// Manifest.permission.READ_EXTERNAL_STORAGE};
// findViewById(R.id.action_insert_image).setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
////绑定按钮的点击响应, 获取危险权限, 这里的100是申请码, 可以自己定义, 整数即可
// ActivityCompat.requestPermissions(NoteEditActivity.this, mPermissionList, 100);
////用于获取焦点,否则插入图片时没有响应
// mNoteEditor.focusEditor();
// }
// });
//路径字符串格式 转换为 图片image格式
private void convertToImage ( ) {
net . micode . notes . ui . NoteEditText noteEditText = ( net . micode . notes . ui . NoteEditText ) findViewById ( R . id . note_edit_view ) ; //获取当前的edit
Editable editable = noteEditText . getText ( ) ; //1.获取text
String noteText = editable . toString ( ) ; //2.将note内容转换为字符串
int length = editable . length ( ) ; //内容的长度
//3.截取img片段 [local]+uri+[local], 提取uri
for ( int i = 0 ; i < length ; i + + ) {
for ( int j = i ; j < length ; j + + ) {
String img_fragment = noteText . substring ( i , j + 1 ) ; //img_fragment: 关于图片路径的片段
if ( img_fragment . length ( ) > 15 & & img_fragment . endsWith ( "[/local]" ) & & img_fragment . startsWith ( "[local]" ) ) {
int limit = 7 ; //[local]为7个字符
//[local][/local]共15个字符, 剩下的为真正的path长度
int len = img_fragment . length ( ) - 15 ;
//从[local]之后的len个字符就是path
String path = img_fragment . substring ( limit , limit + len ) ; //获取到了图片路径
Bitmap bitmap = null ;
Log . d ( TAG , "图片的路径是:" + path ) ;
try {
bitmap = BitmapFactory . decodeFile ( path ) ; //将图片路径解码为图片格式
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
if ( bitmap ! = null ) { //若图片存在
Log . d ( TAG , "图片不为null" ) ;
ImageSpan imageSpan = new ImageSpan ( NoteEditActivity . this , bitmap ) ;
//4.创建一个SpannableString对象, 以便插入用ImageSpan对象封装的图像
String ss = "[local]" + path + "[/local]" ;
SpannableString spannableString = new SpannableString ( ss ) ;
//5.将指定的标记对象附加到文本的开始...结束范围
spannableString . setSpan ( imageSpan , 0 , ss . length ( ) , Spannable . SPAN_EXCLUSIVE_EXCLUSIVE ) ;
Log . d ( TAG , "Create spannable string success!" ) ;
Editable edit_text = noteEditText . getEditableText ( ) ;
edit_text . delete ( i , i + len + 15 ) ; //6.删掉图片路径的文字
edit_text . insert ( i , spannableString ) ; //7.在路径的起始位置插入图片
}
}
}
}
}
//重写onActivityResult()来处理返回的数据
protected void onActivityResult ( int requestCode , int resultCode , Intent intent ) {
super . onActivityResult ( requestCode , resultCode , intent ) ;
ContentResolver resolver = getContentResolver ( ) ;
switch ( requestCode ) {
case PHOTO_REQUEST :
Uri originalUri = intent . getData ( ) ; //1.获得图片的真实路径
Bitmap bitmap = null ;
try {
bitmap = BitmapFactory . decodeStream ( resolver . openInputStream ( originalUri ) ) ; //2.解码图片
} catch ( FileNotFoundException e ) {
Log . d ( TAG , "onActivityResult: get file_exception" ) ;
e . printStackTrace ( ) ;
}
if ( bitmap ! = null ) {
//3.根据Bitmap对象创建ImageSpan对象
Log . d ( TAG , "onActivityResult: bitmap is not null" ) ;
ImageSpan imageSpan = new ImageSpan ( NoteEditActivity . this , bitmap ) ;
String path = getPath ( this , originalUri ) ;
//4.使用[local][/local]将path括起来, 用于之后方便识别图片路径在note中的位置
String img_fragment = "[local]" + path + "[/local]" ;
//创建一个SpannableString对象, 以便插入用ImageSpan对象封装的图像
SpannableString spannableString = new SpannableString ( img_fragment ) ;
spannableString . setSpan ( imageSpan , 0 , img_fragment . length ( ) , Spannable . SPAN_EXCLUSIVE_EXCLUSIVE ) ;
//5.将选择的图片追加到EditText中光标所在位置
net . micode . notes . ui . NoteEditText e = ( net . micode . notes . ui . NoteEditText ) findViewById ( R . id . note_edit_view ) ;
int index = e . getSelectionStart ( ) ; //获取光标所在位置
Log . d ( TAG , "Index是: " + index ) ;
Editable edit_text = e . getEditableText ( ) ;
edit_text . insert ( index , spannableString ) ; //将图片插入到光标所在位置
mWorkingNote . mContent = e . getText ( ) . toString ( ) ;
//6.把改动提交到数据库中,两个数据库表都要改的
ContentResolver contentResolver = getContentResolver ( ) ;
ContentValues contentValues = new ContentValues ( ) ;
final long id = mWorkingNote . getNoteId ( ) ;
contentValues . put ( "snippet" , mWorkingNote . mContent ) ;
contentResolver . update ( Uri . parse ( "content://micode_notes/note" ) , contentValues , "_id=?" , new String [ ] { "" + id } ) ;
ContentValues contentValues1 = new ContentValues ( ) ;
contentValues1 . put ( "content" , mWorkingNote . mContent ) ;
contentResolver . update ( Uri . parse ( "content://micode_notes/data" ) , contentValues1 , "mime_type=? and note_id=?" , new String [ ] { "vnd.android.cursor.item/text_note" , "" + id } ) ;
} else {
Toast . makeText ( NoteEditActivity . this , "获取图片失败" , Toast . LENGTH_SHORT ) . show ( ) ;
}
break ;
default :
break ;
}
}
//获取文件的real path
@SuppressLint ( "NewApi" )
public static String getPath ( final Context context , final Uri uri ) {
if ( uri = = null ) {
return null ;
}
// 判斷是否為Android 4.4之後的版本
final boolean after44 = Build . VERSION . SDK_INT > = 19 ;
if ( after44 & & DocumentsContract . isDocumentUri ( context , uri ) ) {
// 如果是Android 4.4之後的版本, 而且屬於文件URI
final String authority = uri . getAuthority ( ) ;
// 判斷Authority是否為本地端檔案所使用的
if ( "com.android.externalstorage.documents" . equals ( authority ) ) {
// 外部儲存空間
final String docId = DocumentsContract . getDocumentId ( uri ) ;
final String [ ] divide = docId . split ( ":" ) ;
final String type = divide [ 0 ] ;
if ( "primary" . equals ( type ) ) {
String path = Environment . getExternalStorageDirectory ( ) . getAbsolutePath ( ) . concat ( "/" ) . concat ( divide [ 1 ] ) ;
return path ;
} else {
String path = "/storage/" . concat ( type ) . concat ( "/" ) . concat ( divide [ 1 ] ) ;
return path ;
}
} else if ( "com.android.providers.downloads.documents" . equals ( authority ) ) {
// 下載目錄
final String docId = DocumentsContract . getDocumentId ( uri ) ;
if ( docId . startsWith ( "raw:" ) ) {
final String path = docId . replaceFirst ( "raw:" , "" ) ;
return path ;
}
final Uri downloadUri = ContentUris . withAppendedId ( Uri . parse ( "content://downloads/public_downloads" ) , Long . parseLong ( docId ) ) ;
String path = queryAbsolutePath ( context , downloadUri ) ;
return path ;
} else if ( "com.android.providers.media.documents" . equals ( authority ) ) {
// 圖片、影音檔案
final String docId = DocumentsContract . getDocumentId ( uri ) ;
final String [ ] divide = docId . split ( ":" ) ;
final String type = divide [ 0 ] ;
Uri mediaUri = null ;
if ( "image" . equals ( type ) ) {
mediaUri = MediaStore . Images . Media . EXTERNAL_CONTENT_URI ;
} else if ( "video" . equals ( type ) ) {
mediaUri = MediaStore . Video . Media . EXTERNAL_CONTENT_URI ;
} else if ( "audio" . equals ( type ) ) {
mediaUri = MediaStore . Audio . Media . EXTERNAL_CONTENT_URI ;
} else {
return null ;
}
mediaUri = ContentUris . withAppendedId ( mediaUri , Long . parseLong ( divide [ 1 ] ) ) ;
String path = queryAbsolutePath ( context , mediaUri ) ;
return path ;
}
} else {
// 如果是一般的URI
final String scheme = uri . getScheme ( ) ;
String path = null ;
if ( "content" . equals ( scheme ) ) {
// 內容URI
path = queryAbsolutePath ( context , uri ) ;
} else if ( "file" . equals ( scheme ) ) {
// 檔案URI
path = uri . getPath ( ) ;
}
return path ;
}
return null ;
}
public static String queryAbsolutePath ( final Context context , final Uri uri ) {
final String [ ] projection = { MediaStore . MediaColumns . DATA } ;
Cursor cursor = null ;
try {
cursor = context . getContentResolver ( ) . query ( uri , projection , null , null , null ) ;
if ( cursor ! = null & & cursor . moveToFirst ( ) ) {
final int index = cursor . getColumnIndexOrThrow ( MediaStore . MediaColumns . DATA ) ;
return cursor . getString ( index ) ;
}
} catch ( final Exception ex ) {
ex . printStackTrace ( ) ;
if ( cursor ! = null ) {
cursor . close ( ) ;
}
}
return null ;
}
}