赞
踩
package com.example.software_china; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.view.View; import android.widget.Button; import android.widget.ImageView; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import java.io.File; public class MainActivity extends AppCompatActivity { private Button bt_camera; private Button bt_show_imag; private ImageView iv_image; private File file; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bt_camera=(Button) findViewById(R.id.bt_camera); iv_image =(ImageView) findViewById(R.id.iv_image); bt_show_imag =(Button) findViewById(R.id.bt_show_imag); bt_camera.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { file=new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg"); Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); startActivityForResult(intent,100); } }); bt_show_imag.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file),"image/*"); startActivity(intent); } } ); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode==100){ iv_image.setImageURI(Uri.fromFile(file)); } } }
写完之后,一点就闪退,调试后,原因如下:
2021-05-09 15:50:12.100 1727-1727/com.example.software_china E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.software_china, PID: 1727 android.os.FileUriExposedException: file:///storage/emulated/0/1620546589434.jpg exposed beyond app through ClipData.Item.getUri() at android.os.StrictMode.onFileUriExposed(StrictMode.java:1978) at android.net.Uri.checkFileUriExposed(Uri.java:2371) at android.content.ClipData.prepareToLeaveProcess(ClipData.java:963) at android.content.Intent.prepareToLeaveProcess(Intent.java:10331) at android.content.Intent.prepareToLeaveProcess(Intent.java:10316) at android.app.Instrumentation.execStartActivity(Instrumentation.java:1667) at android.app.Activity.startActivityForResult(Activity.java:4762) at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:675) at android.app.Activity.startActivityForResult(Activity.java:4691) at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:662) at com.example.software_china.MainActivity$1.onClick(MainActivity.java:48) at android.view.View.performClick(View.java:6724) at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992) at android.view.View.performClickInternal(View.java:6682) at android.view.View.access$3400(View.java:797) at android.view.View$PerformClick.run(View.java:26479) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:242) at android.app.ActivityThread.main(ActivityThread.java:7227) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:499) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:962)
总之呢,就是FileUriExposedException
报错
对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API
政策禁止在应用外部公开 file:// URI
, 如果一项包含文件 URI
的 intent 离开应用,则应用出现故障,并出现 FileUriExposedException
异常(需要把它封装一下)
然后改成
package com.example.software_china; import android.Manifest; import android.app.Activity; import android.content.ContentValues; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.view.View; import android.widget.Button; import android.widget.ImageView; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import java.io.File; public class MainActivity extends AppCompatActivity { private Button bt_camera; private Button bt_show_imag; private ImageView iv_image; int writeflag = 0;//判断储存权限是否获取 public void openCamera() { Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, getImageUri()); startActivityForResult(intent,100); } public Uri getImageUri() { Uri imageUri; File file=new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg"); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } String path = file.getPath(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { imageUri = Uri.fromFile(file); } else { //兼容android7.0 使用共享文件的形式 ContentValues contentValues = new ContentValues(1); contentValues.put(MediaStore.Images.Media.DATA, path); imageUri = this.getApplication().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); } return imageUri; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bt_camera=(Button) findViewById(R.id.bt_camera); iv_image =(ImageView) findViewById(R.id.iv_image); bt_show_imag =(Button) findViewById(R.id.bt_show_imag); bt_camera.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions((Activity) MainActivity.this, new String[]{Manifest.permission.CAMERA}, 1); } else { openCamera(); } } }); bt_show_imag.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(Intent.ACTION_VIEW); intent.setDataAndType(getImageUri(),"image/*"); startActivity(intent); } } ); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode==100){ iv_image.setImageURI(getImageUri()); } } }
Android 6.0 以后为了保护用户隐私,将一些权限的申请放在了应用运行的时候去申请, 比如以往的开发中,开发人员只需要将需要的权限在清单文件中配置即可,现在Google 可能想到用户可能并不注意这些权限。 so~ 就迎来了动态权限机制。
请注意,如果你使用了API 23以上, 然而并没有用代码处理权限问题。 那么你的程序将会 CRASH !!!
下面我们来看看到底哪些权限是需要动态申请的, 也称为危险权限。
group:android.permission-group.CONTACTS permission:android.permission.WRITE_CONTACTS permission:android.permission.GET_ACCOUNTS permission:android.permission.READ_CONTACTS group:android.permission-group.PHONE permission:android.permission.READ_CALL_LOG permission:android.permission.READ_PHONE_STATE permission:android.permission.CALL_PHONE permission:android.permission.WRITE_CALL_LOG permission:android.permission.USE_SIP permission:android.permission.PROCESS_OUTGOING_CALLS permission:com.android.voicemail.permission.ADD_VOICEMAIL group:android.permission-group.CALENDAR permission:android.permission.READ_CALENDAR permission:android.permission.WRITE_CALENDAR group:android.permission-group.CAMERA permission:android.permission.CAMERA group:android.permission-group.SENSORS permission:android.permission.BODY_SENSORS group:android.permission-group.LOCATION permission:android.permission.ACCESS_FINE_LOCATION permission:android.permission.ACCESS_COARSE_LOCATION group:android.permission-group.STORAGE permission:android.permission.READ_EXTERNAL_STORAGE permission:android.permission.WRITE_EXTERNAL_STORAGE group:android.permission-group.MICROPHONE permission:android.permission.RECORD_AUDIO group:android.permission-group.SMS permission:android.permission.READ_SMS permission:android.permission.RECEIVE_WAP_PUSH permission:android.permission.RECEIVE_MMS permission:android.permission.RECEIVE_SMS permission:android.permission.SEND_SMS permission:android.permission.READ_CELL_BROADCASTS
所属权限组 | 权限 |
---|---|
日历 | READ_CALENDAR |
日历 | WRITE_CALENDAR |
相机 | CAMERA |
联系人 | READ_CONTACTS |
联系人 | WRITE_CONTACTS |
联系人 | GET_ACCOUNTS |
位置 | ACCESS_FINE_LOCATION |
位置 | ACCESS_COARSE_LOCATION |
麦克风 | RECORD_AUDIO |
电话 | READ_PHONE_STATE |
电话 | CALL_PHONE |
电话 | READ_CALL_LOG |
电话 | WRITE_CALL_LOG |
电话 | ADD_VOICEMAIL |
电话 | USE_SIP |
电话 | PROCESS_OUTGOING_CALLS |
传感器 | BODY_SENSORS |
短信 | SEND_SMS |
短信 | RECEIVE_SMS |
短信 | READ_SMS |
短信 | RECEIVE_WAP_PUSH |
短信 | RECEIVE_MMS |
存储 | READ_EXTERNAL_STORAGE |
存储 | WRITE_EXTERNAL_STORAGE |
package com.example.software_china; import android.Manifest; import android.app.Activity; import android.content.ContentValues; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.provider.MediaStore; import android.view.View; import android.widget.Button; import android.widget.ImageView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private Button bt_camera; private Button bt_show_imag; private ImageView iv_image; int writeflag = 0;//判断储存权限是否获取 private File file; String[] permissions = new String[]{ Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.ACCESS_NETWORK_STATE, Manifest.permission.ACCESS_WIFI_STATE, Manifest.permission.INTERNET }; private final int permissionCode = 100;//权限请求码 public void openCamera() { Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, getImageUri()); startActivityForResult(intent,100); } public Uri getImageUri() { Uri imageUri; file=new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg"); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } String path = file.getPath(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { imageUri = Uri.fromFile(file); } else { //兼容android7.0 使用共享文件的形式 ContentValues contentValues = new ContentValues(1); contentValues.put(MediaStore.Images.Media.DATA, path); imageUri = this.getApplication().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); } return imageUri; } private void checkPermission() { List<String> permissionList = new ArrayList<>(); for (int i = 0; i < permissions.length; i++) { if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) { permissionList.add(permissions[i]); } } if (permissionList.size() <= 0) { //说明权限都已经通过,可以做你想做的事情去 } else { //存在未允许的权限 ActivityCompat.requestPermissions(this, permissions, permissionCode); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //6.0才用动态权限 if (Build.VERSION.SDK_INT >= 23) { checkPermission(); } setContentView(R.layout.activity_main); bt_camera=(Button) findViewById(R.id.bt_camera); iv_image =(ImageView) findViewById(R.id.iv_image); bt_show_imag =(Button) findViewById(R.id.bt_show_imag); bt_camera.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions((Activity) MainActivity.this, new String[]{Manifest.permission.CAMERA}, 1); } else { openCamera(); } } }); bt_show_imag.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(Intent.ACTION_VIEW); intent.setDataAndType(getImageUri(),"image/*"); startActivity(intent); } } ); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 100) { if (resultCode == RESULT_OK) { Bitmap bitmap = null; try { bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(getImageUri())); } catch (FileNotFoundException e) { e.printStackTrace(); } iv_image.setImageBitmap(bitmap); // Android 10 使用图片uri加载 iv_image.setImageURI(getImageUri()); } } } }
因为拍照后图片太大,没法直接放在控件imageview中,需要进行压缩,这里有相应的压缩代码
package com.example.software_china; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.LinearGradient; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; /** * Tools for handler picture * * */ public final class ImageTools { /** * Transfer drawable to bitmap * * @param drawable * @return */ public static Bitmap drawableToBitmap(Drawable drawable) { int w = drawable.getIntrinsicWidth(); int h = drawable.getIntrinsicHeight(); Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; Bitmap bitmap = Bitmap.createBitmap(w, h, config); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, w, h); drawable.draw(canvas); return bitmap; } /** * Bitmap to drawable * * @param bitmap * @return */ public static Drawable bitmapToDrawable(Bitmap bitmap) { return new BitmapDrawable(bitmap); } /** * Input stream to bitmap * * @param inputStream * @return * @throws Exception */ public static Bitmap inputStreamToBitmap(InputStream inputStream) throws Exception { return BitmapFactory.decodeStream(inputStream); } /** * Byte transfer to bitmap * * @param byteArray * @return */ public static Bitmap byteToBitmap(byte[] byteArray) { if (byteArray.length != 0) { return BitmapFactory .decodeByteArray(byteArray, 0, byteArray.length); } else { return null; } } /** * Byte transfer to drawable * * @param byteArray * @return */ public static Drawable byteToDrawable(byte[] byteArray) { ByteArrayInputStream ins = null; if (byteArray != null) { ins = new ByteArrayInputStream(byteArray); } return Drawable.createFromStream(ins, null); } /** * Bitmap transfer to bytes * * @return */ public static byte[] bitmapToBytes(Bitmap bm) { byte[] bytes = null; if (bm != null) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.PNG, 100, baos); bytes = baos.toByteArray(); } return bytes; } /** * Drawable transfer to bytes * * @param drawable * @return */ public static byte[] drawableToBytes(Drawable drawable) { BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; Bitmap bitmap = bitmapDrawable.getBitmap(); byte[] bytes = bitmapToBytes(bitmap); ; return bytes; } /** * Base64 to byte[] // */ // public static byte[] base64ToBytes(String base64) throws IOException { // byte[] bytes = Base64.decode(base64); // return bytes; // } // // /** // * Byte[] to base64 // */ // public static String bytesTobase64(byte[] bytes) { // String base64 = Base64.encode(bytes); // return base64; // } /** * Create reflection images * * @param bitmap * @return */ public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) { final int reflectionGap = 4; int w = bitmap.getWidth(); int h = bitmap.getHeight(); Matrix matrix = new Matrix(); matrix.preScale(1, -1); Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, h / 2, w, h / 2, matrix, false); Bitmap bitmapWithReflection = Bitmap.createBitmap(w, (h + h / 2), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmapWithReflection); canvas.drawBitmap(bitmap, 0, 0, null); Paint deafalutPaint = new Paint(); canvas.drawRect(0, h, w, h + reflectionGap, deafalutPaint); canvas.drawBitmap(reflectionImage, 0, h + reflectionGap, null); Paint paint = new Paint(); LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0, bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff, 0x00ffffff, Shader.TileMode.CLAMP); paint.setShader(shader); // Set the Transfer mode to be porter duff and destination in paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); // Draw a rectangle using the paint with our linear gradient canvas.drawRect(0, h, w, bitmapWithReflection.getHeight() + reflectionGap, paint); return bitmapWithReflection; } /** * Get rounded corner images * * @param bitmap * @param roundPx * 5 10 * @return */ public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) { int w = bitmap.getWidth(); int h = bitmap.getHeight(); Bitmap output = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, w, h); final RectF rectF = new RectF(rect); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; } /** * 缩小图片 * * @param bitmap * @param width * @param height * @return */ public static Bitmap zoomBitmap(Bitmap bitmap, int width, int height) { int w = bitmap.getWidth(); int h = bitmap.getHeight(); Matrix matrix = new Matrix(); float scaleWidth = ((float) width / w); float scaleHeight = ((float) height / h); matrix.postScale(scaleWidth, scaleHeight); Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true); return newbmp; } /** * Resize the drawable * @param drawable * @param w * @param h * @return */ public static Drawable zoomDrawable(Drawable drawable, int w, int h) { int width = drawable.getIntrinsicWidth(); int height = drawable.getIntrinsicHeight(); Bitmap oldbmp = drawableToBitmap(drawable); Matrix matrix = new Matrix(); float sx = ((float) w / width); float sy = ((float) h / height); matrix.postScale(sx, sy); Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height, matrix, true); return new BitmapDrawable(newbmp); } /** * Get images from SD card by path and the name of image * @param photoName * @return */ public static Bitmap getPhotoFromSDCard(String path,String photoName){ Bitmap photoBitmap = BitmapFactory.decodeFile(path + "/" +photoName +".png"); if (photoBitmap == null) { return null; }else { return photoBitmap; } } /** * Check the SD card * @return */ public static boolean checkSDCardAvailable(){ return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); } /** * Get image from SD card by path and the name of image * @return */ public static boolean findPhotoFromSDCard(String path,String photoName){ boolean flag = false; if (checkSDCardAvailable()) { File dir = new File(path); if (dir.exists()) { File folders = new File(path); File photoFile[] = folders.listFiles(); for (int i = 0; i < photoFile.length; i++) { String fileName = photoFile[i].getName().split("\\.")[0]; if (fileName.equals(photoName)) { flag = true; } } }else { flag = false; } // File file = new File(path + "/" + photoName + ".jpg" ); // if (file.exists()) { // flag = true; // }else { // flag = false; // } }else { flag = false; } return flag; } /** * 将图片保存到本地SD卡 * @param photoBitmap * @param photoName * @param path */ public static void savePhotoToSDCard(Bitmap photoBitmap, String path, String photoName){ if (checkSDCardAvailable()) { File dir = new File(path); if (!dir.exists()){ dir.mkdirs(); } File photoFile = new File(path , photoName + ".png"); FileOutputStream fileOutputStream = null; try { fileOutputStream = new FileOutputStream(photoFile); if (photoBitmap != null) { if (photoBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)) { fileOutputStream.flush(); // fileOutputStream.close(); } } } catch (FileNotFoundException e) { photoFile.delete(); e.printStackTrace(); } catch (IOException e) { photoFile.delete(); e.printStackTrace(); } finally{ try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * Delete the image from SD card * @param path * file:///sdcard/temp.jpg */ public static void deleteAllPhoto(String path){ if (checkSDCardAvailable()) { File folder = new File(path); File[] files = folder.listFiles(); for (int i = 0; i < files.length; i++) { files[i].delete(); } } } //删除上一次截图的临时文件,包括图片路径和文件名称 public static void deletePhotoAtPathAndName(String path,String fileName){ if (checkSDCardAvailable()) { File folder = new File(path); File[] files = folder.listFiles(); for (int i = 0; i < files.length; i++) { System.out.println(files[i].getName()); if (files[i].getName().equals(fileName)) { files[i].delete(); } } } } }
Bitmap bitmap= BitmapFactory.decodeFile(path);
if(bitmap!=null){
Bitmap newBitmap=ImageTools.zoomBitmap(bitmap, bitmap.getWidth()/3, bitmap.getHeight()/3);
//由于Bitmap内存占用较大,这里需要回收内存,否则会报out of memory异常
bitmap.recycle();
//将处理过的图片显示在界面上,并保存到本地
iv_image.setImageBitmap(newBitmap);
ImageTools.savePhotoToSDCard(newBitmap, Environment.getExternalStorageDirectory().getAbsolutePath(), String.valueOf(System.currentTimeMillis()));
break;
}else{
break;
}
误点后返回时,bitMap是null,然后就进行一系列错误代码的执行,只需要进行一个bitMap
判断即可
ContentResolver resolver=getContentResolver(); if(data!=null){ Uri originUri=data.getData(); try { Bitmap bitMap=MediaStore.Images.Media.getBitmap(resolver, originUri); if(bitMap!=null){ Bitmap smallMap=ImageTools.zoomBitmap(bitMap, bitMap.getWidth() / 3, bitMap.getHeight() / 3); bitMap.recycle(); iv_image.setImageBitmap(smallMap); } } catch (IOException e) { e.printStackTrace(); } break; }else{ break; }
误点后返回时,data是null,然后就进行一系列错误代码的执行,只需要进行一个data
判断即可
找相关资料,发现在android 10
系统中
需要在文件下AndroidManifest.xml 加上android:requestLegacyExternalStorage = “true” 这个属性
<application android:requestLegacyExternalStorage = “true”>
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。