题记:一个人不能在两个同样的坑里摔倒。
去年4月份的时候,我有一个任务,让我写个下载保存文件的方法,如果文件的名字存在,就加“-1”,如果仍然存在,就在-后面的数字加1,例如:文件名:Keep_On_It.mp3,第一次下载是Keep_On_It.mp3,第二次下载名字就保存成:Keep_On_It-1.mp3,第三次下载名字就保存成:Keep_On_It-2.mp3,第四次下载名字就保存为:Keep_On_It-3.mp3,以此类推的形式一直实现。当时我用的方法比较笨,可读性特别差,当时用了半天就实现了,就是截取字符串进行比较。最近研究源码下载的时候发现可以用for循环来实现,可读性强,容易理解,算法简练,不愧为谷歌设计出来的,简单明了,容易理解。
转载请标明出处:http://blog.csdn.net/wdaming1986/article/details/7342559
现在给大家分享一下:先看效果图片:
如果内存卡的这个目录只有这些MP3:

再次保存的名字就是最后一个Keep_It_On-3.mp3了

下面把代码奉上:
在CopyFileApp的工程里:
一、在com.cn.daming.copyfile包下的CopyFileAppActivity.java类中的代码:
package com.cn.daming.copyfile;
import java.io.File;
import java.util.Random;
import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.util.Log;
import android.widget.TextView;
public class CopyFileAppActivity extends Activity {
/** Called when the activity is first created. */
private final static String SDCARD_PATH="/mnt/sdcard/download/mp3/Keep_It_On.mp3";
private final static String FILENAME_SEQUENCE_SEPARATOR = "-";
private static Random sRandom = new Random(SystemClock.uptimeMillis());
private final static String LOG = "wangxianming";
private TextView m_TextView;
private TextView m_TextView_full;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
m_TextView = (TextView)findViewById(R.id.text_view);
m_TextView_full = (TextView)findViewById(R.id.text_view2);
Log.v(LOG, " ---->"+SystemClock.uptimeMillis());
// Check to see if we have an SDCard
String status = Environment.getExternalStorageState();
if (!status.equals(Environment.MEDIA_MOUNTED)) {
int title;
String msg;
// Check to see if the SDCard is busy, same as the music app
if (status.equals(Environment.MEDIA_SHARED)) {
msg = getString(R.string.download_sdcard_busy_dlg_msg);
title = R.string.download_sdcard_busy_dlg_title;
} else {
msg = getString(R.string.download_no_sdcard_dlg_msg, "no sdcard");
title = R.string.download_no_sdcard_dlg_title;
}
new AlertDialog.Builder(this)
.setTitle(title)
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(msg)
.setPositiveButton(R.string.ok, null)
.show();
return;
}
File mp3File = new File(SDCARD_PATH);
if(mp3File != null && mp3File.exists()) {
String fileNamePath = mp3File.getAbsolutePath();
String filename = fileNamePath.substring(0, fileNamePath.lastIndexOf("."));
String extension = fileNamePath.substring(fileNamePath.lastIndexOf("."), fileNamePath.length());
m_TextView.setText(filename + extension);
m_TextView_full.setText(chooseUniqueFilename(filename, extension));
}
}
//This is method is core
private String chooseUniqueFilename(String filename, String extension) {
String fullFilename = filename + extension;
if(!new File(fullFilename).exists()) {
return fullFilename;
}
filename = filename + FILENAME_SEQUENCE_SEPARATOR;
/*
* This number is used to generate partially randomized filenames to avoid
* collisions.
* It starts at 1.
* The next 9 iterations increment it by 1 at a time (up to 10).
* The next 9 iterations increment it by 1 to 10 (random) at a time.
* The next 9 iterations increment it by 1 to 100 (random) at a time.
* ... Up to the point where it increases by 100000000 at a time.
* (the maximum value that can be reached is 1000000000)
* As soon as a number is reached that generates a filename that doesn't exist,
* that filename is used.
* If the filename coming in is [base].[ext], the generated filenames are
* [base]-[sequence].[ext].
*/
int sequence = 1;
for (int magnitude = 1; magnitude < 1000000000; magnitude *= 10) {
for (int iteration = 0; iteration < 9; ++iteration) {
fullFilename = filename + sequence + extension;
if (!new File(fullFilename).exists()) {
return fullFilename;
}
Log.v(LOG, "file with sequence number " + sequence + " exists");
sequence += sRandom.nextInt(magnitude) + 1;
}
}
return fullFilename;
}
}
二、layout目录下的main.xml中的代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:gravity="center"
android:text="@string/hello" />
<TextView
android:id="@+id/text_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:text=""
/>
<TextView
android:id="@+id/text_view2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:text="" />
</LinearLayout>
三、values目录下的strings.xml中的代码:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">This is daming Original</string>
<string name="app_name">CopyFileApp</string>
<string name="download_sdcard_busy_dlg_title" product="default" msgid="6877712666046917741">"SD 卡不可用"</string>
<string name="download_sdcard_busy_dlg_msg">"SD 卡正忙。要允许下载,请在通知中选择“关闭 USB 存储设备”。"</string>
<string name="download_no_sdcard_dlg_msg" product="default" msgid="2616399456116301518">"需要有 SD 卡才能下载</string>
<string name="download_no_sdcard_dlg_title" product="default" msgid="605904452159416792">"无 SD 卡"</string>
<string name="cancel" msgid="3017274947407233702">"取消"</string>
<string name="ok" msgid="1509280796718850364">"确定"</string>
</resources>
有什么好的建议和新颖的想法的可以留言,欢迎大家共同讨论。。。。。。。
分享到:
相关推荐
本资料集合是"老罗"(罗升阳)关于Android视频开发的一系列教学资源,包括源码和PPT,专注于讲解如何在Android环境中解析XML文件。 首先,我们要理解XML解析的基本概念。在Android中,XML解析有两种主要方式:DOM...
这篇文档将深入解析《Android应用源码之安卓图片上传和文件上传带jsp服务端源码》这个项目,它是一个适用于毕业设计的学习资源,主要涵盖了Android客户端应用与JSP服务器端的交互,涉及到图像和文件的上传功能。...
首先,Android源码中的`source.properties`和`package.xml`是构建系统的重要配置文件。`source.properties`记录了源代码仓库的信息,包括版本、作者、日期等,用于版本控制和构建过程。而`package.xml`则描述了源码...
"myweibo1.2"可能是一个版本号命名的应用程序APK文件,用于实际在设备上运行和测试新浪微博的Android客户端。 在源码分析中,开发者可以关注以下几个关键知识点: 1. **应用架构**:学习模块化设计,例如MVVM...
在Android开发中,加载本地共享库.so文件是一个常见的操作,通常涉及到System类中的两个方法:System.loadLibrary()和System.load()。这两个方法都用于加载native代码库,但它们的用法和工作原理存在一些差异。以下...
这个"Android拍照并上传文件到服务端源码"的项目主要涵盖了两个关键部分:Android客户端的图片拍摄和上传功能,以及服务器端的图片接收处理。 一、Android客户端 1. **启动相机应用**:在Android中,可以使用...
Android Mars项目中的视频代码涉及到XML源码的解析,这对于我们理解XML在Android应用中的作用至关重要。 XML文档结构分为声明、元素、属性、文本内容、注释等部分。在Android中,XML文件主要有以下几种类型: 1. *...
《深入解析Android2048源码:共享偏好存储最高分功能》 2048是一款风靡全球的数字拼图游戏,玩家通过上下左右滑动屏幕,将相同的数字合并,最终目标是得到2048这个数字。在Android平台上,开发者们将这个游戏进行...
这份“安卓Android源码——安卓图片上传和文件上传带jsp服务端源码.zip”压缩包提供了完整的实现方案,包括客户端的安卓代码以及服务端的jsp代码。下面将详细解析这一知识点。 首先,我们来关注客户端部分,也就是...
为了保持良好的文件组织和管理,遵循一定的命名规则,使用有意义的目录结构,并及时清理无用文件。同时,对于敏感数据,应加密存储以保护用户隐私。 总结,这个“安卓文件管理源码”涵盖了Android系统中的文件操作...
【Android 一键锁屏 OneKeyLock 源码解析】 在Android系统中,开发者可以通过编程方式实现各种定制化的功能,其中一键锁屏就是一个常见的需求。OneKeyLock项目就是这样一个实现,它提供了一种简单快捷的方式来锁定...
Android Parted GPT分区工具包是一款专为Android设备设计的磁盘分区管理工具,它集成了GPT(GUID Partition Table)分区表的支持,使得用户能够更有效地管理和调整Android设备的存储空间。在Android系统中,分区管理...
开源中国是一个在中国颇具影响力的开源软件社区,其android源码提供了深入了解Android应用开发的宝贵资源。这份源码可以供开发者深入研究Android平台的工作原理,学习最佳实践,并提升自己的编程技巧。 一、Android...
- 创建一个新的Android工程,命名为`sbsWeather`。 - 工程结构如图所示。 2. **布局设计**: - 使用XML文件定义布局,包含文本视图、编辑框和按钮。 ```xml xmlns:android=...
这份"Android应用源码之安卓图片上传和文件上传带jsp服务端源码.zip"的资源提供了完整的实现方案,包括客户端的Android代码以及服务端的jsp代码。下面将详细解析这一过程中的关键知识点。 一、Android客户端实现...
这个命名规则是遵循 Android SDK 的结构需求,以便于集成到你的开发环境中。接下来,将整个 "sources" 目录复制到你的 Android SDK 安装路径下的 "%android_home%\platforms\android-7" 文件夹中。这一步骤是为了...
这篇文档将深入解析《Android应用源码之五子棋附源码》的毕业设计项目,旨在为学习Android应用开发的学生提供宝贵的参考资料。该项目涵盖了Android应用程序的基础架构、游戏逻辑实现、用户界面设计以及源码分析等多...
《Android应用源码解析——基于"qiyi-IT计算机-毕业设计.zip"的深度学习》 在当今的移动互联网时代,Android应用开发已经成为IT行业不可或缺的一部分,尤其对于计算机科学和技术专业的毕业生而言,掌握Android应用...
【Android 24点游戏源码详解】 在Android平台上开发一款24点游戏,涉及到的知识点广泛,包括但不限于Android应用的基础架构、用户交互设计、算法实现等。以下将详细解析这款24点游戏的源码内容。 1. **基本架构**...
【Ubuntu10.4编译Funambol Android源码详解】 在云计算日益普及的时代,同步服务成为了连接不同设备间数据的重要桥梁。SyncML协议作为其中的代表性协议,因其开放性和跨平台特性备受青睐。Funambol是一个开源的...