gy 2 years ago
commit 1e51462c4c

@ -22,19 +22,34 @@ import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.SearchManager;
import android.appwidget.AppWidgetManager;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
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;
@ -43,10 +58,12 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
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;
@ -65,6 +82,7 @@ import net.micode.notes.ui.NoteEditText.OnTextViewChangeListener;
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.Map;
@ -149,6 +167,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private String mUserQuery;
private Pattern mPattern;
private final int PHOTO_REQUEST = 1;//请求码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -159,12 +179,27 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return;
}
initResources();
//根据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);
}
});
}
/**
* Current activity may be killed when the memory is low. Once it is killed, for another time
* user load this activity, we should restore the former state
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
@ -263,14 +298,13 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
@Override
protected void onResume() {
protected void onResume() {//能获得用户焦点:可以操作
super.onResume();
initNoteScreen();
initNoteScreen();//初始化便签屏幕
}
private void initNoteScreen() {
mNoteEditor.setTextAppearance(this, TextAppearanceResources
.getTexAppearanceResource(mFontSizeId));
mNoteEditor.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
switchToListMode(mWorkingNote.getContent());
} else {
@ -288,11 +322,9 @@ public class NoteEditActivity extends Activity implements OnClickListener,
| DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_SHOW_TIME
| DateUtils.FORMAT_SHOW_YEAR));
/**
* TODO: Add the menu for setting alert. Currently disable it because the DateTimePicker
* is not ready
*/
showAlertHeader();
//将有图片路径的位置转换为图片
convertToImage();
}
//路径字符串格式 转换为 图片image格式
@ -455,6 +487,47 @@ public class NoteEditActivity extends Activity implements OnClickListener,
};
}
//路径字符串格式 转换为 图片image格式
private void convertToImage() {
NoteEditText noteEditText = (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.在路径的起始位置插入图片
}
}
}
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
@ -573,7 +646,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if (id == R.id.btn_set_bg_color) {
mNoteBgColorSelector.setVisibility(View.VISIBLE);
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
- View.VISIBLE);
View.VISIBLE);
} else if (sBgSelectorBtnsMap.containsKey(id)) {
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
View.GONE);
@ -696,10 +769,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
d.show();
}
/**
* Share note to apps that support {@link Intent#ACTION_SEND} action
* and {@text/plain} type
*/
private void sendTo(Context context, String info) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, info);
@ -906,12 +975,12 @@ public class NoteEditActivity extends Activity implements OnClickListener,
switchToListMode(mNoteEditor.getText().toString());
} else {
if (!getWorkingText()) {
mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ",
""));
mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ", ""));
}
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
mEditTextList.setVisibility(View.GONE);
mNoteEditor.setVisibility(View.VISIBLE);
convertToImage(); //退出清单模式,应该将有图片的地方显示出来
}
}
@ -1003,4 +1072,147 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private void showToast(int resId, int duration) {
Toast.makeText(this, resId, duration).show();
}
@Override
//重写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中光标所在位置
NoteEditText e = (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
public String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
// if (isExternalStorageDocument(uri)) {
// final String docId = DocumentsContract.getDocumentId(uri);
// final String[] split = docId.split(":");
// final String type = split[0];
//
// if ("primary".equalsIgnoreCase(type)) {
// return Environment.getExternalStorageDirectory() + "/" + split[1];
// }
// }
// // DownloadsProvider
// else if (isDownloadsDocument(uri)) {
// final String id = DocumentsContract.getDocumentId(uri);
// final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
// return getDataColumn(context, contentUri, null, null);
// }
// MediaProvider
// else
if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{split[1]};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// Media
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
//获取数据列_获取此 Uri 的数据列的值。这对MediaStore Uris 和其他基于文件的 ContentProvider。
public String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
//是否为外部存储文件
// public boolean isExternalStorageDocument(Uri uri) {
// return "com.android.externalstorage.documents".equals(uri.getAuthority());
// }
//
// //是否为下载文件
// public boolean isDownloadsDocument(Uri uri) {
// return "com.android.providers.downloads.documents".equals(uri.getAuthority());
// }
//是否为媒体文件
public boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
}

@ -30,6 +30,10 @@
android:id="@+id/menu_font_size"
android:title="@string/menu_font_size"/>
<item
android:id="@+id/menu_voice_mix"
android:title="朗读" />
<item
android:id="@+id/menu_list_mode"
android:title="@string/menu_list_mode" />
@ -49,4 +53,11 @@
<item
android:id="@+id/menu_delete_remind"
android:title="@string/menu_remove_remind" />
<TextView
android:id="@+id/text_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:layout_marginRight="8dip"
/>
</menu>

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string-array name="menu_share_ways">
<item>メールです </item>
<item>メールです </item>
</string-array>
</resources>

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">付箋</string>
<string name="app_widget2x2">付箋2x2</string>
<string name="app_widget4x4">付箋4x4</string>
<string name="widget_havenot_content">関連コンテンツはありません。新しいメモを作成してください</string>
<string name="widget_under_visit_mode">ゲストモードでは、メモの内容は表示されません</string>
<string name="notelist_string_info">...</string>
<string name="notelist_menu_new">新しい付箋を作成</string>
<string name="delete_remind_time_message">リマインダを削除しました</string>
<string name="set_remind_time_message">リマインダを作成</string>
<string name="note_alert_expired">期限切れ</string>
<string name="format_date_ymd">yyyyMMdd</string>
<string name="format_datetime_mdhm">MM月dd日 kk:mm</string>
<string name="notealert_ok">了解</string>
<string name="notealert_enter">表示</string>
<string name="note_link_tel">電話をかける</string>
<string name="note_link_email">メールを送信</string>
<string name="note_link_web">ウェブページを閲覧</string>
<string name="note_link_other">地図を開く</string>
<!-- note list string -->
<string name="menu_create_folder">フォルダを作成</string>
<string name="menu_export_text">テキストをエクスポート</string>
<string name="menu_sync">同期</string>
<string name="menu_sync_cancel">同期をキャンセル</string>
<string name="menu_setting">設定</string>
<string name="menu_search">検索</string>
<string name="menu_delete">削除</string>
<string name="menu_move">フォルダに移動</string>
<string name="menu_select_title"> %d 項目が選択されました</string>
<string name="menu_select_none">選択された項目はありません</string>
<string name="menu_select_all">すべて選択</string>
<string name="menu_deselect_all">すべて選択解除</string>
<string name="menu_font_size">文字のサイズ</string>
<string name="menu_font_small"></string>
<string name="menu_font_normal">通常</string>
<string name="menu_font_large"></string>
<string name="menu_font_super">超大</string>
<string name="menu_list_mode">リストモードに入る</string>
<string name="menu_normal_mode">リストモードを終了</string>
<string name="menu_folder_view">フォルダを表示</string>
<string name="menu_folder_delete">フォルダを削除</string>
<string name="menu_folder_change_name">フォルダ名を変更</string>
<string name="folder_exist">ォルダ %1$s は既に存在しています。別の名前を入力してください</string>
<string name="menu_share">共有</string>
<string name="menu_send_to_desktop">デスクトップに送信</string>
<string name="menu_alert">リマインドする</string>
<string name="menu_remove_remind">リマインドを削除</string>
<string name="menu_title_select_folder">フォルダを選択</string>
<string name="menu_move_parent_folder">一つ上のフォルダ</string>
<string name="info_note_enter_desktop">デスクトップに追加されました</string>
<string name="alert_title_delete">削除</string>
<string name="alert_message_delete_notes">選択した %d 件のメモを削除しますか?</string>
<string name="alert_message_delete_note">このメモを削除しますか?</string>
<string name="alert_message_delete_folder">このフォルダと含まれるメモを削除しますか?</string>
<string name="format_move_notes_to_folder">選択した %1$d 件のメモを %2$s フォルダに移動しました</string>
<!-- export text -->
<string name="error_sdcard_unmounted">SDカードが使用中のため、操作できません</string>
<string name="error_sdcard_export">テキストのエクスポート中にエラーが発生しました。SDカードを確認してください</string>
<string name="error_note_not_exist">表示するメモが存在しません</string>
<string name="error_note_empty_for_clock">空のメモにはアラームのリマインダを設定できません</string>
<string name="error_note_empty_for_send_to_desktop">空のメモをデスクトップに送信することはできません</string>
<string name="success_sdcard_export">エクスポートに成功しました</string>
<string name="failed_sdcard_export">エクスポートに失敗しました</string>
<string name="format_exported_file_location">テキストファイル(%1$sがSDカード%2$sのディレクトリに出力されました</string>
<!-- Sync -->
<string name="ticker_syncing">付箋を同期中...</string>
<string name="ticker_success">同期に成功しました</string>
<string name="ticker_fail">同期に失敗しました</string>
<string name="ticker_cancel">同期がキャンセルされました</string>
<string name="success_sync_account">%1$sとの同期に成功しました</string>
<string name="error_sync_network">同期に失敗しました。ネットワークとアカウント設定を確認してください</string>
<string name="error_sync_internal">同期に失敗しました。内部エラーが発生しました</string>
<string name="error_sync_cancelled">同期がキャンセルされました</string>
<string name="sync_progress_login">%1$sにログイン中...</string>
<string name="sync_progress_init_list">サーバーのメモリストを取得中...</string>
<string name="sync_progress_syncing">ローカルメモの同期中...</string>
<!-- Preferences -->
<string name="preferences_title">設定</string>
<string name="preferences_account_title">同期アカウント</string>
<string name="preferences_account_summary">Google Tasksとのメモを同期します</string>
<string name="preferences_last_sync_time">前回の同期: %1$s</string>
<string name="preferences_add_account">アカウントを追加</string>
<string name="preferences_menu_change_account">アカウントを変更</string>
<string name="preferences_menu_remove_account">アカウントを削除</string>
<string name="preferences_menu_cancel">キャンセル</string>
<string name="preferences_button_sync_immediately">即時同期</string>
<string name="preferences_button_sync_cancel">同期をキャンセル</string>
<string name="preferences_dialog_change_account_title">現在のアカウント: %1$s</string>
<string name="preferences_dialog_change_account_warn_msg">同期アカウントを変更すると、以前のアカウントの同期情報はクリアされ、重複データが発生する可能性があります</string>
<string name="preferences_dialog_select_account_title">付箋の同期</string>
<string name="preferences_dialog_select_account_tips">Googleアカウントを選択してください。メモは選択したアカウントのGoogle Tasksの内容と同期されます。</string>
<string name="preferences_toast_cannot_change_account">同期中のため、同期アカウントを変更できません</string>
<string name="preferences_toast_success_set_accout">同期アカウントは %1$s に設定されました</string>
<string name="preferences_bg_random_appear_title">新規メモの背景色をランダムに表示</string>
<string name="button_delete">削除</string>
<string name="call_record_folder_name">通話付箋</string>
<string name="hint_foler_name">名前を入力してください</string>
<string name="search_label">付箋を検索中</string>
<string name="search_hint">付箋を検索</string>
<string name="search_setting_description">付箋のテキスト</string>
<string name="search">付箋</string>
<string name="datetime_dialog_ok">設定</string>
<string name="datetime_dialog_cancel">キャンセル</string>
<string name="menu_secret">プライベートモード</string>
<string name="menu_quit_secret">プライベートモードを終了</string>
<plurals name="search_results_title">
<item quantity="other"><xliff:g id="NUMBER">%1$s</xliff:g> 条と一致“<xliff:g id="SEARCH">%2$s</xliff:g>”の検索結果</item>
</plurals>
</resources>

@ -128,6 +128,8 @@
<string name="search">Notes</string>
<string name="datetime_dialog_ok">set</string>
<string name="datetime_dialog_cancel">cancel</string>
<string name="menu_secret">secret model</string>
<string name="menu_quit_secret">quit secret model</string>
<plurals name="search_results_title">
<item quantity="one"><xliff:g id="number" example="1">%1$s</xliff:g> result for \"<xliff:g id="search" example="???">%2$s</xliff:g>\"</item>
<!-- Case of 0 or 2 or more results. -->

Loading…
Cancel
Save