@ -33,6 +33,8 @@ import android.database.Cursor;
import android.graphics.Bitmap ;
import android.graphics.Bitmap ;
import android.graphics.BitmapFactory ;
import android.graphics.BitmapFactory ;
import android.graphics.Paint ;
import android.graphics.Paint ;
import android.graphics.drawable.BitmapDrawable ;
import android.graphics.drawable.Drawable ;
import android.net.Uri ;
import android.net.Uri ;
import android.os.Build ;
import android.os.Build ;
import android.os.Bundle ;
import android.os.Bundle ;
@ -48,12 +50,14 @@ import android.text.style.BackgroundColorSpan;
import android.text.style.ImageSpan ;
import android.text.style.ImageSpan ;
import android.util.Log ;
import android.util.Log ;
import android.view.LayoutInflater ;
import android.view.LayoutInflater ;
import android.view.KeyEvent ;
import android.view.Menu ;
import android.view.Menu ;
import android.view.MenuItem ;
import android.view.MenuItem ;
import android.view.MotionEvent ;
import android.view.MotionEvent ;
import android.view.View ;
import android.view.View ;
import android.view.View.OnClickListener ;
import android.view.View.OnClickListener ;
import android.view.WindowManager ;
import android.view.WindowManager ;
import android.view.inputmethod.InputMethodManager ;
import android.widget.CheckBox ;
import android.widget.CheckBox ;
import android.widget.CompoundButton ;
import android.widget.CompoundButton ;
import android.widget.CompoundButton.OnCheckedChangeListener ;
import android.widget.CompoundButton.OnCheckedChangeListener ;
@ -79,6 +83,7 @@ import net.micode.notes.widget.NoteWidgetProvider_4x;
import java.io.File ;
import java.io.File ;
import java.io.FileNotFoundException ;
import java.io.FileNotFoundException ;
import java.io.InputStream ;
import java.util.ArrayList ;
import java.util.ArrayList ;
import java.util.HashMap ;
import java.util.HashMap ;
import java.util.HashSet ;
import java.util.HashSet ;
@ -169,7 +174,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private final int PHOTO_REQUEST = 1 ;
private final int PHOTO_REQUEST = 1 ;
@Override
@Override
protected void onCreate ( Bundle savedInstanceState ) {
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState ) ;
super . onCreate ( savedInstanceState ) ;
this . setContentView ( R . layout . note_edit ) ;
this . setContentView ( R . layout . note_edit ) ;
@ -180,6 +184,9 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
}
initResources ( ) ;
initResources ( ) ;
// 初始化字体大小
mNoteEditor . setTextAppearance ( this , ResourceParser . TextAppearanceResources . getTexAppearanceResource ( mFontSizeId ) ) ;
//根据id获取添加图片按钮
//根据id获取添加图片按钮
final ImageButton add_img_btn = ( ImageButton ) findViewById ( R . id . add_img_btn ) ;
final ImageButton add_img_btn = ( ImageButton ) findViewById ( R . id . add_img_btn ) ;
//为点击图片按钮设置监听器
//为点击图片按钮设置监听器
@ -187,13 +194,27 @@ public class NoteEditActivity extends Activity implements OnClickListener,
@Override
@Override
public void onClick ( View view ) {
public void onClick ( View view ) {
Log . d ( TAG , "onClick: click add image button" ) ;
Log . d ( TAG , "onClick: click add image button" ) ;
//ACTION_GET_CONTENT: 允许用户选择特殊种类的数据,并返回(特殊种类的数据:照一张相片或录一段音)
// 隐藏输入法
Intent loadImage = new Intent ( Intent . ACTION_GET_CONTENT ) ;
InputMethodManager imm = ( InputMethodManager ) getSystemService ( Context . INPUT_METHOD_SERVICE ) ;
//Category属性用于指定当前动作( Action) 被执行的环境.
if ( imm ! = null ) {
//CATEGORY_OPENABLE; 用来指示一个ACTION_GET_CONTENT的intent
imm . hideSoftInputFromWindow ( view . getWindowToken ( ) , 0 ) ;
loadImage . addCategory ( Intent . CATEGORY_OPENABLE ) ;
}
loadImage . setType ( "image/*" ) ;
startActivityForResult ( loadImage , PHOTO_REQUEST ) ;
// 延迟启动图片选择器,等待输入法完全隐藏
view . postDelayed ( new Runnable ( ) {
@Override
public void run ( ) {
try {
Intent loadImage = new Intent ( Intent . ACTION_GET_CONTENT ) ;
loadImage . addCategory ( Intent . CATEGORY_OPENABLE ) ;
loadImage . setType ( "image/*" ) ;
startActivityForResult ( loadImage , PHOTO_REQUEST ) ;
} catch ( Exception e ) {
Log . e ( TAG , "启动图片选择器失败" , e ) ;
Toast . makeText ( NoteEditActivity . this , "启动图片选择器失败" , Toast . LENGTH_SHORT ) . show ( ) ;
}
}
} , 100 ) ; // 延迟100毫秒
}
}
} ) ;
} ) ;
}
}
@ -297,6 +318,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
protected void onResume ( ) {
protected void onResume ( ) {
super . onResume ( ) ;
super . onResume ( ) ;
initNoteScreen ( ) ;
initNoteScreen ( ) ;
// 转换文本中的图片标记为实际图片
convertToImage ( ) ;
}
}
private void initNoteScreen ( ) {
private void initNoteScreen ( ) {
@ -449,17 +472,14 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
}
mFontSizeSelector = findViewById ( R . id . font_size_selector ) ;
mFontSizeSelector = findViewById ( R . id . font_size_selector ) ;
for ( int id : sFontSizeBtnsMap . keySet ( ) ) {
// 为字体大小选择器的每个选项设置点击事件
View view = findViewById ( id ) ;
findViewById ( R . id . ll_font_small ) . setOnClickListener ( this ) ;
view . setOnClickListener ( this ) ;
findViewById ( R . id . ll_font_normal ) . setOnClickListener ( this ) ;
} ;
findViewById ( R . id . ll_font_large ) . setOnClickListener ( this ) ;
findViewById ( R . id . ll_font_super ) . setOnClickListener ( this ) ;
mSharedPrefs = PreferenceManager . getDefaultSharedPreferences ( this ) ;
mSharedPrefs = PreferenceManager . getDefaultSharedPreferences ( this ) ;
mFontSizeId = mSharedPrefs . getInt ( PREFERENCE_FONT_SIZE , ResourceParser . BG_DEFAULT_FONT_SIZE ) ;
mFontSizeId = mSharedPrefs . getInt ( PREFERENCE_FONT_SIZE , ResourceParser . BG_DEFAULT_FONT_SIZE ) ;
/ * *
* HACKME : Fix bug of store the resource id in shared preference .
* The id may larger than the length of resources , in this case ,
* return the { @link ResourceParser # BG_DEFAULT_FONT_SIZE }
* /
if ( mFontSizeId > = TextAppearanceResources . getResourcesSize ( ) ) {
if ( mFontSizeId > = TextAppearanceResources . getResourcesSize ( ) ) {
mFontSizeId = ResourceParser . BG_DEFAULT_FONT_SIZE ;
mFontSizeId = ResourceParser . BG_DEFAULT_FONT_SIZE ;
}
}
@ -494,43 +514,75 @@ public class NoteEditActivity extends Activity implements OnClickListener,
setResult ( RESULT_OK , intent ) ;
setResult ( RESULT_OK , intent ) ;
}
}
@Override
public void onClick ( View v ) {
public void onClick ( View v ) {
int id = v . getId ( ) ;
int id = v . getId ( ) ;
if ( id = = R . id . btn_set_bg_color ) {
if ( id = = R . id . btn_set_bg_color ) {
mNoteBgColorSelector . setVisibility ( View . VISIBLE ) ;
if ( mNoteBgColorSelector . getVisibility ( ) = = View . VISIBLE ) {
findViewById ( sBgSelectorSelectionMap . get ( mWorkingNote . getBgColorId ( ) ) ) . setVisibility (
mNoteBgColorSelector . setVisibility ( View . GONE ) ;
View . VISIBLE ) ;
} else {
mNoteBgColorSelector . setVisibility ( View . VISIBLE ) ;
mFontSizeSelector . setVisibility ( View . GONE ) ;
}
} else if ( sBgSelectorBtnsMap . containsKey ( id ) ) {
} else if ( sBgSelectorBtnsMap . containsKey ( id ) ) {
findViewById ( sBgSelectorSelectionMap . get ( mWorkingNote . getBgColorId ( ) ) ) . setVisibility (
findViewById ( sBgSelectorSelectionMap . get ( mWorkingNote . getBgColorId ( ) ) ) . setVisibility (
View . GONE ) ;
View . GONE ) ;
mWorkingNote . setBgColorId ( sBgSelectorBtnsMap . get ( id ) ) ;
mWorkingNote . setBgColorId ( sBgSelectorBtnsMap . get ( id ) ) ;
mNoteBgColorSelector . setVisibility ( View . GONE ) ;
mNoteBgColorSelector . setVisibility ( View . GONE ) ;
} else if ( sFontSizeBtnsMap . containsKey ( id ) ) {
} else if ( sFontSizeBtnsMap . containsKey ( id ) ) {
// 隐藏之前选中的字体大小图标
findViewById ( sFontSelectorSelectionMap . get ( mFontSizeId ) ) . setVisibility ( View . GONE ) ;
findViewById ( sFontSelectorSelectionMap . get ( mFontSizeId ) ) . setVisibility ( View . GONE ) ;
mFontSizeId = sFontSizeBtnsMap . get ( id ) ;
mSharedPrefs . edit ( ) . putInt ( PREFERENCE_FONT_SIZE , mFontSizeId ) . commit ( ) ;
int fontSizeId = sFontSizeBtnsMap . get ( id ) ;
findViewById ( sFontSelectorSelectionMap . get ( mFontSizeId ) ) . setVisibility ( View . VISIBLE ) ;
mFontSizeId = fontSizeId ;
mSharedPrefs . edit ( ) . putInt ( PREFERENCE_FONT_SIZE , fontSizeId ) . commit ( ) ;
mNoteEditor . setTextAppearance ( this , ResourceParser . TextAppearanceResources . getTexAppearanceResource ( fontSizeId ) ) ;
// 显示新选中的字体大小图标
findViewById ( sFontSelectorSelectionMap . get ( fontSizeId ) ) . setVisibility ( View . VISIBLE ) ;
mFontSizeSelector . setVisibility ( View . GONE ) ;
if ( mWorkingNote . getCheckListMode ( ) = = TextNote . MODE_CHECK_LIST ) {
if ( mWorkingNote . getCheckListMode ( ) = = TextNote . MODE_CHECK_LIST ) {
getWorkingText ( ) ;
getWorkingText ( ) ;
switchToListMode ( mWorkingNote . getContent ( ) ) ;
switchToListMode ( mWorkingNote . getContent ( ) ) ;
} else {
} else {
mNoteEditor . setTextAppearance ( this ,
mNoteEditor . setTextAppearance ( this ,
TextAppearanceResources . getTexAppearanceResource ( mFontSizeId ) ) ;
TextAppearanceResources . getTexAppearanceResource ( f ontSizeId) ) ;
}
}
mFontSizeSelector . setVisibility ( View . GONE ) ;
}
}
}
}
@Override
@Override
public void onBackPressed ( ) {
public void onBackPressed ( ) {
if ( mFontSizeSelector . getVisibility ( ) = = View . VISIBLE ) {
mFontSizeSelector . setVisibility ( View . GONE ) ;
return ;
}
if ( mNoteBgColorSelector . getVisibility ( ) = = View . VISIBLE ) {
mNoteBgColorSelector . setVisibility ( View . GONE ) ;
return ;
}
if ( clearSettingState ( ) ) {
if ( clearSettingState ( ) ) {
return ;
return ;
}
}
saveNote ( ) ;
saveNote ( ) ;
super . onBackPressed ( ) ;
super . onBackPressed ( ) ;
}
}
@Override
public boolean onKeyDown ( int keyCode , KeyEvent event ) {
if ( keyCode = = KeyEvent . KEYCODE_BACK ) {
if ( mFontSizeSelector . getVisibility ( ) = = View . VISIBLE ) {
mFontSizeSelector . setVisibility ( View . GONE ) ;
return true ;
}
if ( mNoteBgColorSelector . getVisibility ( ) = = View . VISIBLE ) {
mNoteBgColorSelector . setVisibility ( View . GONE ) ;
return true ;
}
}
return super . onKeyDown ( keyCode , event ) ;
}
private boolean clearSettingState ( ) {
private boolean clearSettingState ( ) {
if ( mNoteBgColorSelector . getVisibility ( ) = = View . VISIBLE ) {
if ( mNoteBgColorSelector . getVisibility ( ) = = View . VISIBLE ) {
mNoteBgColorSelector . setVisibility ( View . GONE ) ;
mNoteBgColorSelector . setVisibility ( View . GONE ) ;
@ -575,7 +627,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
}
@Override
@Override
public boolean onOptionsItemSelected ( MenuItem item ) {
public boolean onOptionsItemSelected ( MenuItem item ) {
switch ( item . getItemId ( ) ) {
switch ( item . getItemId ( ) ) {
case R . id . menu_new_note :
case R . id . menu_new_note :
@ -597,9 +648,15 @@ public class NoteEditActivity extends Activity implements OnClickListener,
builder . show ( ) ;
builder . show ( ) ;
break ;
break ;
case R . id . menu_font_size :
case R . id . menu_font_size :
mFontSizeSelector . setVisibility ( View . VISIBLE ) ;
if ( mFontSizeSelector . getVisibility ( ) = = View . VISIBLE ) {
findViewById ( sFontSelectorSelectionMap . get ( mFontSizeId ) ) . setVisibility ( View . VISIBLE ) ;
mFontSizeSelector . setVisibility ( View . GONE ) ;
break ;
} else {
mFontSizeSelector . setVisibility ( View . VISIBLE ) ;
mNoteBgColorSelector . setVisibility ( View . GONE ) ;
// 显示当前选中的字体大小
findViewById ( sFontSelectorSelectionMap . get ( mFontSizeId ) ) . setVisibility ( View . VISIBLE ) ;
}
return true ;
case R . id . menu_list_mode :
case R . id . menu_list_mode :
mWorkingNote . setCheckListMode ( mWorkingNote . getCheckListMode ( ) = = 0 ?
mWorkingNote . setCheckListMode ( mWorkingNote . getCheckListMode ( ) = = 0 ?
TextNote . MODE_CHECK_LIST : 0 ) ;
TextNote . MODE_CHECK_LIST : 0 ) ;
@ -620,7 +677,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
default :
default :
break ;
break ;
}
}
return true ;
return super . onOptionsItemSelected ( item ) ;
}
}
private void setReminder ( ) {
private void setReminder ( ) {
@ -1034,45 +1091,198 @@ public class NoteEditActivity extends Activity implements OnClickListener,
ContentResolver resolver = getContentResolver ( ) ;
ContentResolver resolver = getContentResolver ( ) ;
switch ( requestCode ) {
switch ( requestCode ) {
case PHOTO_REQUEST :
case PHOTO_REQUEST :
Uri originalUri = intent . getData ( ) ; //1.获得图片的真实路径
if ( resultCode ! = RESULT_OK ) {
Bitmap bitmap = null ;
Log . e ( TAG , "获取图片失败: resultCode = " + resultCode ) ;
try {
Toast . makeText ( NoteEditActivity . this , "获取图片失败: 用户取消或操作失败" , Toast . LENGTH_SHORT ) . show ( ) ;
bitmap = BitmapFactory . decodeStream ( resolver . openInputStream ( originalUri ) ) ; //2.解码图片
return ;
} catch ( FileNotFoundException e ) {
Log . d ( TAG , "onActivityResult: get file_exception" ) ;
e . printStackTrace ( ) ;
}
}
if ( bitmap ! = null ) {
if ( intent = = null ) {
//3.根据Bitmap对象创建ImageSpan对象
Log . e ( TAG , "获取图片失败: intent为null" ) ;
Log . d ( TAG , "onActivityResult: bitmap is not null" ) ;
Toast . makeText ( NoteEditActivity . this , "获取图片失败: 未获取到图片数据" , Toast . LENGTH_SHORT ) . show ( ) ;
ImageSpan imageSpan = new ImageSpan ( NoteEditActivity . this , bitmap ) ;
return ;
}
Uri originalUri = intent . getData ( ) ;
if ( originalUri = = null ) {
Log . e ( TAG , "获取图片失败: originalUri为null" ) ;
Toast . makeText ( NoteEditActivity . this , "获取图片失败: 图片URI无效" , Toast . LENGTH_SHORT ) . show ( ) ;
return ;
}
try {
Log . d ( TAG , "开始加载图片: Uri = " + originalUri ) ;
// 获取图片的真实路径
String path = getPath ( this , originalUri ) ;
String path = getPath ( this , originalUri ) ;
//4.使用[local][/local]将path括起来, 用于之后方便识别图片路径在note中的位置
Log . d ( TAG , "图片路径: " + path ) ;
String img_fragment = "[local]" + path + "[/local]" ;
//创建一个SpannableString对象, 以便插入用ImageSpan对象封装的图像
// 尝试多种方式加载图片
SpannableString spannableString = new SpannableString ( img_fragment ) ;
Bitmap bitmap = null ;
spannableString . setSpan ( imageSpan , 0 , img_fragment . length ( ) , Spannable . SPAN_EXCLUSIVE_EXCLUSIVE ) ;
//5.将选择的图片追加到EditText中光标所在位置
// 方式1: 直接从Uri加载
NoteEditText e = ( NoteEditText ) findViewById ( R . id . note_edit_view ) ;
try {
int index = e . getSelectionStart ( ) ; //获取光标所在位置
bitmap = MediaStore . Images . Media . getBitmap ( resolver , originalUri ) ;
Log . d ( TAG , "Index是: " + index ) ;
Log . d ( TAG , "从Uri加载图片成功" ) ;
Editable edit_text = e . getEditableText ( ) ;
} catch ( Exception e ) {
edit_text . insert ( index , spannableString ) ; //将图片插入到光标所在位置
Log . e ( TAG , "从Uri加载图片失败" , e ) ;
}
mWorkingNote . mContent = e . getText ( ) . toString ( ) ;
//6.把改动提交到数据库中,两个数据库表都要改的
// 方式2: 如果方式1失败, 尝试从文件路径加载
if ( bitmap = = null & & path ! = null ) {
try {
bitmap = BitmapFactory . decodeFile ( path ) ;
Log . d ( TAG , "从文件路径加载图片成功" ) ;
} catch ( Exception e ) {
Log . e ( TAG , "从文件路径加载图片失败" , e ) ;
}
}
// 方式3: 如果前两种方式都失败, 尝试使用ContentResolver
if ( bitmap = = null ) {
try {
InputStream inputStream = resolver . openInputStream ( originalUri ) ;
if ( inputStream ! = null ) {
bitmap = BitmapFactory . decodeStream ( inputStream ) ;
inputStream . close ( ) ;
Log . d ( TAG , "从ContentResolver加载图片成功" ) ;
}
} catch ( Exception e ) {
Log . e ( TAG , "从ContentResolver加载图片失败" , e ) ;
}
}
if ( bitmap = = null ) {
Log . e ( TAG , "所有加载方式都失败" ) ;
Toast . makeText ( NoteEditActivity . this , "获取图片失败: 无法加载图片" , Toast . LENGTH_SHORT ) . show ( ) ;
return ;
}
Log . d ( TAG , "图片加载成功,尺寸: " + bitmap . getWidth ( ) + "x" + bitmap . getHeight ( ) ) ;
// 调整图片大小
int maxSize = 1024 ;
int width = bitmap . getWidth ( ) ;
int height = bitmap . getHeight ( ) ;
if ( width > maxSize | | height > maxSize ) {
float scale = Math . min ( ( float ) maxSize / width , ( float ) maxSize / height ) ;
width = Math . round ( width * scale ) ;
height = Math . round ( height * scale ) ;
Bitmap scaledBitmap = Bitmap . createScaledBitmap ( bitmap , width , height , true ) ;
bitmap . recycle ( ) ; // 释放原始bitmap
bitmap = scaledBitmap ;
Log . d ( TAG , "图片已调整大小: " + width + "x" + height ) ;
}
// 创建ImageSpan对象
Log . d ( TAG , "开始创建ImageSpan, bitmap尺寸: " + bitmap . getWidth ( ) + "x" + bitmap . getHeight ( ) ) ;
// 调整图片大小
int maxWidth = 768 ; // 最大宽度
float scale = ( float ) maxWidth / bitmap . getWidth ( ) ;
int newWidth = ( int ) ( bitmap . getWidth ( ) * scale ) ;
int newHeight = ( int ) ( bitmap . getHeight ( ) * scale ) ;
Bitmap scaledBitmap = Bitmap . createScaledBitmap ( bitmap , newWidth , newHeight , true ) ;
bitmap . recycle ( ) ;
bitmap = scaledBitmap ;
Log . d ( TAG , "调整后的图片尺寸: " + newWidth + "x" + newHeight ) ;
// 创建Drawable
Drawable drawable = new BitmapDrawable ( getResources ( ) , bitmap ) ;
drawable . setBounds ( 0 , 0 , newWidth , newHeight ) ;
// 创建ImageSpan
ImageSpan imageSpan = new ImageSpan ( drawable ) ;
Log . d ( TAG , "ImageSpan创建成功" ) ;
// 获取EditText和光标位置
NoteEditText noteEditText = ( NoteEditText ) findViewById ( R . id . note_edit_view ) ;
if ( noteEditText = = null ) {
Log . e ( TAG , "noteEditText为null" ) ;
return ;
}
Log . d ( TAG , "获取到noteEditText" ) ;
int index = noteEditText . getSelectionStart ( ) ;
if ( index < 0 ) {
index = 0 ;
}
Log . d ( TAG , "当前光标位置: " + index ) ;
// 获取当前文本
Editable edit_text = noteEditText . getEditableText ( ) ;
if ( edit_text = = null ) {
Log . e ( TAG , "edit_text为null" ) ;
return ;
}
Log . d ( TAG , "获取到edit_text, 长度: " + edit_text . length ( ) ) ;
// 创建新的SpannableString
SpannableString spannableString = new SpannableString ( " " ) ;
spannableString . setSpan ( imageSpan , 0 , 1 , Spannable . SPAN_EXCLUSIVE_EXCLUSIVE ) ;
Log . d ( TAG , "SpannableString创建成功" ) ;
// 插入图片
edit_text . insert ( index , spannableString ) ;
Log . d ( TAG , "图片插入成功,当前文本长度: " + edit_text . length ( ) ) ;
// 保存图片路径到数据库
String imagePath = "[local]" + path + "[/local]" ;
mWorkingNote . mContent = noteEditText . getText ( ) . toString ( ) ;
Log . d ( TAG , "保存的图片路径: " + imagePath ) ;
// 更新数据库
ContentResolver contentResolver = getContentResolver ( ) ;
ContentResolver contentResolver = getContentResolver ( ) ;
ContentValues contentValues = new ContentValues ( ) ;
ContentValues contentValues = new ContentValues ( ) ;
final long id = mWorkingNote . getNoteId ( ) ;
final long id = mWorkingNote . getNoteId ( ) ;
contentValues . put ( "snippet" , String . valueOf ( mWorkingNote ) ) ;
contentValues . put ( "snippet" , String . valueOf ( mWorkingNote ) ) ;
contentValues . put ( "has_attachment" , 1 ) ; // 标记有附件
contentResolver . update ( Uri . parse ( "content://micode_notes/note" ) , contentValues , "_id=?" , new String [ ] { "" + id } ) ;
contentResolver . update ( Uri . parse ( "content://micode_notes/note" ) , contentValues , "_id=?" , new String [ ] { "" + id } ) ;
ContentValues contentValues1 = new ContentValues ( ) ;
ContentValues contentValues1 = new ContentValues ( ) ;
contentValues1 . put ( "content" , mWorkingNote . mContent ) ;
contentValues1 . put ( "content" , mWorkingNote . mContent ) ;
contentValues1 . put ( "mime_type" , "vnd.android.cursor.item/text_note" ) ;
contentResolver . update ( Uri . parse ( "content://micode_notes/data" ) , contentValues1 , "mime_type=? and note_id=?" , new String [ ] { "vnd.android.cursor.item/text_note" , "" + id } ) ;
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 ( ) ;
ContentValues imageValues = new ContentValues ( ) ;
imageValues . put ( "note_id" , id ) ;
imageValues . put ( "mime_type" , "image/*" ) ;
imageValues . put ( "content" , path ) ; // 使用content列存储图片路径
imageValues . put ( "data1" , 0 ) ; // 使用data1存储图片类型
imageValues . put ( "data3" , "" ) ; // 使用data3存储额外信息
contentResolver . insert ( Uri . parse ( "content://micode_notes/data" ) , imageValues ) ;
Log . d ( TAG , "数据库更新成功" ) ;
// 强制刷新EditText显示
noteEditText . invalidate ( ) ;
noteEditText . requestLayout ( ) ;
Log . d ( TAG , "EditText刷新完成" ) ;
// 检查图片是否真的插入
Spannable spannable = noteEditText . getText ( ) ;
ImageSpan [ ] spans = spannable . getSpans ( 0 , spannable . length ( ) , ImageSpan . class ) ;
Log . d ( TAG , "当前文本中的ImageSpan数量: " + spans . length ) ;
if ( spans . length > 0 ) {
Log . d ( TAG , "第一个ImageSpan的位置: " + spannable . getSpanStart ( spans [ 0 ] ) + " - " + spannable . getSpanEnd ( spans [ 0 ] ) ) ;
Drawable d = spans [ 0 ] . getDrawable ( ) ;
if ( d ! = null ) {
Log . d ( TAG , "ImageSpan drawable尺寸: " + d . getIntrinsicWidth ( ) + "x" + d . getIntrinsicHeight ( ) ) ;
}
}
// 重新设置文本以确保ImageSpan被保存
noteEditText . setText ( noteEditText . getText ( ) ) ;
} catch ( SecurityException e ) {
Log . e ( TAG , "获取图片失败: 权限不足" , e ) ;
Toast . makeText ( NoteEditActivity . this , "获取图片失败: 应用没有足够的权限" , Toast . LENGTH_SHORT ) . show ( ) ;
} catch ( Exception e ) {
Log . e ( TAG , "获取图片失败: 未知错误" , e ) ;
Toast . makeText ( NoteEditActivity . this , "获取图片失败: " + e . getMessage ( ) , Toast . LENGTH_SHORT ) . show ( ) ;
}
}
break ;
break ;
default :
default :
@ -1126,10 +1336,47 @@ public class NoteEditActivity extends Activity implements OnClickListener,
continue ;
continue ;
}
}
// 尝试加载图片
// 尝试多种方式加载图片
Bitmap bitmap = BitmapFactory . decodeFile ( path ) ;
Bitmap bitmap = null ;
// 方式1: 直接从文件加载
try {
bitmap = BitmapFactory . decodeFile ( path ) ;
Log . d ( TAG , "Successfully loaded image from file" ) ;
} catch ( Exception e ) {
Log . e ( TAG , "Failed to load image from file" , e ) ;
}
// 方式2: 如果方式1失败, 尝试使用ContentResolver
if ( bitmap = = null ) {
try {
Uri uri = Uri . fromFile ( imageFile ) ;
InputStream inputStream = getContentResolver ( ) . openInputStream ( uri ) ;
if ( inputStream ! = null ) {
bitmap = BitmapFactory . decodeStream ( inputStream ) ;
inputStream . close ( ) ;
Log . d ( TAG , "Successfully loaded image using ContentResolver" ) ;
}
} catch ( Exception e ) {
Log . e ( TAG , "Failed to load image using ContentResolver" , e ) ;
}
}
if ( bitmap ! = null ) {
if ( bitmap ! = null ) {
ImageSpan imageSpan = new ImageSpan ( this , bitmap ) ;
// 调整图片大小
int maxSize = 1024 ;
int width = bitmap . getWidth ( ) ;
int height = bitmap . getHeight ( ) ;
if ( width > maxSize | | height > maxSize ) {
float scale = Math . min ( ( float ) maxSize / width , ( float ) maxSize / height ) ;
width = Math . round ( width * scale ) ;
height = Math . round ( height * scale ) ;
Bitmap scaledBitmap = Bitmap . createScaledBitmap ( bitmap , width , height , true ) ;
bitmap . recycle ( ) ;
bitmap = scaledBitmap ;
}
ImageSpan imageSpan = new ImageSpan ( this , bitmap , ImageSpan . ALIGN_BASELINE ) ;
SpannableString spannableString = new SpannableString ( matcher . group ( ) ) ;
SpannableString spannableString = new SpannableString ( matcher . group ( ) ) ;
spannableString . setSpan ( imageSpan , 0 , spannableString . length ( ) ,
spannableString . setSpan ( imageSpan , 0 , spannableString . length ( ) ,
Spannable . SPAN_EXCLUSIVE_EXCLUSIVE ) ;
Spannable . SPAN_EXCLUSIVE_EXCLUSIVE ) ;