Bootstrap

(基于安卓app开发的毕业设计)智能手机图片管理.(附论文+源码)

大家好!我是职场程序猿,感谢您阅读本文,欢迎一键三连哦。

💞当前专栏:安卓app毕业设计

精彩专栏推荐👇🏻👇🏻👇🏻

👉🎀 微信小程序毕业设计
👉🌎Java毕业设计

一、项目简介

随着手机性能的不断提升,虽然手机有了更大的内存,但日益增长的照片除了对硬件提出要求外,对管理也提出相应的挑战。不但数量太多,细节太多,分类复杂,还需要一张张打开才能鉴别,因此需要有专门的应用对照片进行分类管理。本研究项目基于Java语言和Android平台,搭建一款手机照片管理App,利用移动互联网技术解决上述问题。

二、系统核心功能模块部分截图

2.1用户登陆的设计与实现

用户通过APP提供的注册、登陆功能,实现使用其它核心功能的目的。应用逻辑为用户点击进入App,已注册用户输入手机号和密码进行用户登陆;新用户点击“注册”按钮进行用户注册,注册后通过用户名、密码实现登陆。
注册时用户编辑登陆名,编辑密码并进行二次确认,如果用户名合法且两次密码一致,则注册成功,用户注册信息写入数据库进行保存。
登录模块,用户输入电话号和密码后,由系统调用数据库相关信息,与用户输入的信息进行比较,如果结果一致,则认定为合法用户,登录成功。

2.2分类相册功能

这是本研究项目的核心功能,通过支持创建不同类别的相册,将照片进行合理分类,解决了图片归类步骤繁琐的痛点,方便分门别类的快速找到自己所需的照片。
App设计有添加相册功能,用户可以根据自己需要创建相册,并自主添加相应照片。具体效果如下图所示:

在这里插入图片描述

2.3照片管理功能

照片添加进相册之后,App还提供对照片的排序、添加照片描述、删除以及对照片缩放、旋转、保存等功能,用于对相册内照片的管理。具体实现效果如下:
在这里插入图片描述

2.4 壁纸功能

App还附带壁纸功能,用户可以根据各人喜好,将相册内的照片设置成手机壁纸,增加个性化需求。其开发效果如下图所示:
在这里插入图片描述

三、部分核心代码

4.1 BaseActivity部分


package com.android.socketdemo.base;

import android.Manifest;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

public abstract class BaseActivity extends FragmentActivity {

    private static final int REQUEST_CAMERA = 1000;
    private static final int IMAGE_REQUEST_CODE = 1001;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        checkPermission();
    }

    @TargetApi(Build.VERSION_CODES.M)
    private boolean checkPermission() {
        if(Build.VERSION.SDK_INT >= 23) {
            if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
                    && checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
                    && checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                return true;
            }

            String[] permistions = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE};
            requestPermissions(permistions, 0);
            return false;
        }
        return true;

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    public void photoDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(BaseActivity.this);
        builder.setMessage("请选择添加图片方式");

        //调用相机拍照
        builder.setPositiveButton("拍照", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (checkPermission()) {
                        takePhoto();
                    }
                } else {
                    takePhoto();
                }
            }
        });
        //从相册里面取照片
        builder.setNegativeButton("相册", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                pickPhoto();
            }
        });
        builder.create().show();
    }


    protected void takePhoto() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(intent, REQUEST_CAMERA);
    }

    /***
     * 从相册中取图片
     */
    protected void pickPhoto() {
        //AndroidImagePicker.getInstance().setSelectMode(AndroidImagePicker.Select_Mode.MODE_MULTI);
        Intent intent = new Intent(Intent.ACTION_PICK, null);
        //通过Intent 筛选所有的图片
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");

        startActivityForResult(intent, IMAGE_REQUEST_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        String path = "";
        if (requestCode == REQUEST_CAMERA && resultCode == RESULT_OK) {
            Bundle bundle0 = data.getExtras();
            Bitmap bitmap0 = (Bitmap) bundle0.get("data");
            File path0 = getFile(bitmap0);
            path = Uri.fromFile(path0).toString();
            uploadResult(path);
        } else if (requestCode == IMAGE_REQUEST_CODE && resultCode == RESULT_OK) {
            try {
                Cursor cursor0 =
                        getContentResolver()
                                .query(data.getData()
                                        , new String[]{MediaStore.Images.Media.DATA}
                                        , null, null, null);
                cursor0.moveToFirst();
                String capturPath0 = cursor0.getString(
                        cursor0.getColumnIndex(
                                MediaStore.Images.Media.DATA));
                cursor0.close();
                uploadResult(Uri.fromFile(new File(capturPath0)).toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public File getFile(Bitmap bitmap) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos);
        File file = new File(Environment.getExternalStorageDirectory() + "/" + System.currentTimeMillis() + ".png");
        try {
            file.createNewFile();
            FileOutputStream fos = new FileOutputStream(file);
            InputStream is = new ByteArrayInputStream(baos.toByteArray());
            int x = 0;
            byte[] b = new byte[1024 * 100];
            while ((x = is.read(b)) != -1) {
                fos.write(b, 0, x);
            }
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return file;
    }
    private void upload(File file) {
    }

    public abstract void uploadResult(String path);
}



4.2File部分


package com.android.socketdemo.utils;

import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileUtils {
    /**
     * 根据URI获取文件真实路径(兼容多张机型)
     *
     * @param context
     * @param uri
     * @return
     */
    public static String getFilePathByUri(Context context, Uri uri) {
        if ("content".equalsIgnoreCase(uri.getScheme())) {

            int sdkVersion = Build.VERSION.SDK_INT;
            if (sdkVersion >= 19) { // api >= 19
                return getRealPathFromUriAboveApi19(context, uri);
            } else { // api < 19
                return getRealPathFromUriBelowAPI19(context, uri);
            }
        } else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }
        return null;
    }

    /**
     * 适配api19及以上,根据uri获取图片的绝对路径
     *
     * @param context 上下文对象
     * @param uri     图片的Uri
     * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
     */
    @SuppressLint("NewApi")
    private static String getRealPathFromUriAboveApi19(Context context, Uri uri) {
        String filePath = null;
        if (DocumentsContract.isDocumentUri(context, uri)) {
            // 如果是document类型的 uri, 则通过document id来进行处理
            String documentId = DocumentsContract.getDocumentId(uri);
            if (isMediaDocument(uri)) { // MediaProvider
                // 使用':'分割
                String type = documentId.split(":")[0];
                String id = documentId.split(":")[1];

                String selection = MediaStore.Images.Media._ID + "=?";
                String[] selectionArgs = {id};

                //
                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                filePath = getDataColumn(context, contentUri, selection, selectionArgs);
            } else if (isDownloadsDocument(uri)) { // DownloadsProvider
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(documentId));
                filePath = getDataColumn(context, contentUri, null, null);
            } else if (isExternalStorageDocument(uri)) {
                // ExternalStorageProvider
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
                if ("primary".equalsIgnoreCase(type)) {
                    filePath = Environment.getExternalStorageDirectory() + "/" + split[1];
                }
            } else {
                //Log.e("路径错误");
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
            // 如果是 content 类型的 Uri
            filePath = getDataColumn(context, uri, null, null);
        } else if ("file".equals(uri.getScheme())) {
            // 如果是 file 类型的 Uri,直接获取图片对应的路径
            filePath = uri.getPath();
        }
        return filePath;
    }

    /**
     * 适配api19以下(不包括api19),根据uri获取图片的绝对路径
     *
     * @param context 上下文对象
     * @param uri     图片的Uri
     * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
     */
    private static String getRealPathFromUriBelowAPI19(Context context, Uri uri) {
        return getDataColumn(context, uri, null, null);
    }

    /**
     * 获取数据库表中的 _data 列,即返回Uri对应的文件路径
     *
     * @return
     */
    private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
        String path = null;

        String[] projection = new String[]{MediaStore.Images.Media.DATA};
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                int columnIndex = cursor.getColumnIndexOrThrow(projection[0]);
                path = cursor.getString(columnIndex);
            }
        } catch (Exception e) {
            if (cursor != null) {
                cursor.close();
            }
        }
        return path;
    }

    /**
     * @param uri the Uri to check
     * @return Whether the Uri authority is MediaProvider
     */
    private static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    private static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri the Uri to check
     * @return Whether the Uri authority is DownloadsProvider
     */
    private static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }


    // 指纹图片存放路径
    public static String sdCardDir = Environment.getExternalStorageDirectory() + "/fingerprintimages/";

    /**
     * 保存指纹图片
     *
     * @param bitmap
     */
    public static File saveBitmap(Context context, Bitmap bitmap) {

        try {
            File dirFile = new File(sdCardDir);
            if (!dirFile.exists()) {              //如果不存在,那就建立这个文件夹
                dirFile.mkdirs();
            }
            String name = System.currentTimeMillis() + "";
            File file = new File(sdCardDir, name + ".png");
            FileOutputStream fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
            MediaStore.Images.Media.insertImage(context.getContentResolver(),
                    file.getAbsolutePath(), name, null);
            return file;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;

    }
}


四、论文目录

1.绪论 6
1.1研究背景 6
1.1.1 社区的概念 6
1.1.2 互联网社区的发展历程 6
1.2研究的意义 9
1.3 论文结构 10
2.项目可行性分析 11
2.1系统分析的方法 11
2.2系统可行性分析 12
2.3系统需求分析 13
2.3.1功能性需求分析 13
2.3.2非功能性需求分析 14
3.相关技术简介 16
3.1JAVA程序语言 16
3.1.1 Java简介 16
3.1.2 Java主要特性 17
3.2数据库 20
3.3 Android架构 23
3.3.1 Linux内核 24
3.3.2 程序库 24
3.3.3 Android程序库 25
3.3.4 应用框架 26
3.3.5 应用程序 26
4.系统设计实现 26
4.1 开发环境搭建 27
4.1.1 window系统安装java 27
4.1.2安装配置Android Studio 31
4.1.3创建Android Studio工程 31
4.2 系统功能设计 32
4.3数据结构设计 33
4.4系统详细实现 35
4.4.1 用户登陆的设计与实现 35
4.4.2 广场模块 37
4.4.3消息模块 38
4.4.4个人中心及后台管理 39
5.软件测试 40
5.1软件测试的目的 41
5.2 软件测试的常用方式 41
5.2.1静态测试和动态测试 41
5.2.2黑盒测试、白盒测试和灰盒测试 42
5.2.4手动测试和自动化测试 43
5.3测试用例 43
5.4测试结果 45
6.研究总结 45
参考文献 46
致 谢 47

获取源码或论文

如嘘对应的源码,可以私wo

;