Android开发中将数据存储到文件实例

 更新时间:2016年9月20日 19:53  点击:1656
Android为数据存储提供了如下几种方式:文件、SharedPreferences(偏好参数)、SQLite数据库、内容提供者(Content provider)、网络,本文我们重点讲讲文件存储。

第一步,改写AndroidManifest.xml,给手机的Scard卡授权

<!--添加Scard卡读写授权 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

然后加单元测试instrumentation

 <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.example.androidsdcard" >
    </instrumentation>

并且在application下加 <uses-library android:name="android.test.runner"/>


 <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <uses-library android:name="android.test.runner"/>
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>


第二步,编写文件读写的类FileStream

package com.example.androidsdcard;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import android.content.Context;
import android.os.Environment;

public class FileStream {
    private Context context;

    public FileStream(Context context) {
        this.context = context;
    }

    public FileStream() {

    }
    //读取sd卡的文件内容
    public String readFile(String filename){
        FileInputStream inputStream=null;
        //字符缓冲流
        ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
     //                 通过Environment获得sd卡的路径
        File file=new File(Environment.getExternalStorageDirectory(),filename);
        //判断sdcard是否存在
        if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
            try {
                inputStream=new FileInputStream(file);
                int len=0;
         //创建字节数组
                byte[]data=new byte[2048];
          //按字节数组的大小进行读取
                while((len=inputStream.read(data))!=-1){
                    outputStream.write(data, 0, len);    
                }
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                if(inputStream!=null){
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
        return new String(outputStream.toByteArray());
        
    }

    public boolean savaFile(String filename, String content) {
        boolean flag = false;
        FileOutputStream outputStream = null;
        File file = new File(Environment.getExternalStorageDirectory(),
                filename);
        if (Environment.MEDIA_MOUNTED.equals(Environment
                .getExternalStorageState())) {
            try {
                outputStream = new FileOutputStream(file);
                outputStream.write(content.getBytes());
                flag = true;
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (outputStream != null) {
                    try {
                        outputStream.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }

        }

        return flag;
    }

}


第三部,编写测试类进行单元测试,进行文件的读写

package com.example.androidsdcard;

import android.content.Context;
import android.test.AndroidTestCase;
import android.util.Log;

public class MyTest extends AndroidTestCase {
    private final String TAG="MyTest";
    public MyTest(){
        
    }
    public void saveFile(){//测试文件写入
        Context context=getContext();
        FileStream fileStream=new FileStream(context);
        boolean flag=fileStream.savaFile("hello.txt","你好吗?");
        Log.i(TAG,"--->"+flag);
        
    }
    public void readFile(){//测试文件内容读取
        Context context=getContext();
        FileStream fileStream=new FileStream(context);
        String filename="hello.txt";
        String flag=fileStream.readFile(filename);
        Log.i(TAG,"--->"+flag);
        
    }

}

本文我们谈谈在 Android开发中,用Volley框架实现获取服务器的字符串响应的实例,做Android开发的朋友可以参考。

学习内容:

例一、使用StringRequest实现获取服务器的字符串响应...

 
Android的Volley中到底实现了哪些请求才是我们在开发中需要进行使用的...Volley实现的东西其实并不是很多,它的主要功能是实现异步进行网络请求和图片加载,其实就是异步加载解析Json数据,异步获取服务器的字符串数据,异步实现网络图片的动态加载,还有一个请求就是清空缓存的请求,不过使用的地方不是很多,主要还是前面三个方面,因此Volley相对于AndBase来说,其实还算是一个轻量级的框架,而AndBase涉及到的东西就更加的广泛,全面,但是网络请求这一部分使用Volley基本算是够用了...

1.StringRequest.java


package com.android.volley.toolbox;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import java.io.UnsupportedEncodingException;
public class StringRequest extends Request<String> {
    private final Listener<String> mListener; //请求成功的监听...
    //根据指定的请求方式和url创建一个StringRquest对象...
    public StringRequest(int method, String url, Listener<String> listener,
            ErrorListener errorListener) {
        super(method, url, errorListener); //设置请求方式,url,以及错误监听..
        mListener = listener; //设置成功监听...
    }
    //根据指定的url来创建一个StringRequest对象,请求方式默认为GET..
    public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {
        this(Method.GET, url, listener, errorListener);
    }
    //这里涉及到发送响应的过程了...表示整个请求的响应已经返回...
    @Override
    protected void deliverResponse(String response) {
        mListener.onResponse(response);
    }
    //对响应的解析过程...
    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        String parsed;
        try {
            parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); //对响应数据封装,解析字符集...
        } catch (UnsupportedEncodingException e) {
            parsed = new String(response.data);
        }
        return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));//返回请求成功...
    }
}



  上面只是StringRequest的源码实现,非常的简单...那么我们来具体的看看怎么用...

  一般使用在简单的响应方式,返回一些基本的数据信息,比如说用户登录中,在发送Post请求发送用户的账号信息和密码的时候,需要服务器调取数据库进行相关查找...在完成这个响应之后需要为服务端返回响应信息,一般就是以字符串的形式进行发送的...


package com.example.oop;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.ImageLoader.ImageCache;
import com.android.volley.toolbox.NetworkImageView;
import com.android.volley.toolbox.Volley;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity implements OnClickListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }
    public void init(){
        RequestQueue queue=Volley.newRequestQueue(MainActivity.this); //首先创建一个请求队列...
     //然后需要向请求队列中添加相关请求...
     queue.add(new StringRequest("http://www.baidu.com/",new Listener    <StringRequest>(){
        //请求成功,接收请求方法的重写...
        @Override
        public void onResponse(String response){
            System.out.println(response.toString());
        }
    },new ErrorListener(){ //请求失败,对错误的获取...
        @Override
        public void onErrorResponse(VolleyError error){
            System.out.println(error.toString());
        }
    });  
        
}
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}




  这里我们想百度页面发送了相关的请求,那么毫无疑问,请求成功是必然的,那么返回的东西就是百度页面的原生数据,其实就是Html页面代码...那么我们无法去解析这个页面,但是浏览器却是可以的,我们可以通过浏览器去加载这个页面...这只是一个简单的小例子而已,目的是我们需要清楚,服务器返回给我们的是什么数据...

  第二个例子:

  这是一个中间用于过程处理的JSP方法...用于处理账户和密码,只是一个简单的方式,我们当然也可以通过它去连接数据库,完善化这个函数...这里只是一个简单的小例子...


 <%
  String name=request.getParameter("name");
  String password=request.getParameter("password");
  if("darker".equals(name)&& "49681888".equals(password)){
      out.println("Receive name is:"+name);
    out.println("Receive password is:"+password);%>
    Your Message are right!
  <%}else{
      out.println("Receive name is:"+name);
    out.println("Receive password is:"+password);%>
    Your Message are wrong!
  <%}%>




  那么Activity中需要通过Post请求发送请求参数,才能够通过这个函数来进行下一步的判断...由于Post请求中没有传递参数的方法...但是我们可以通过重写getParam()方法...来指定相关参数,服务端会自动调用getParam()中的参数....


package com.example.oop;
//有一部分包没有引用,在编写的时候会自动引用的...
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
 
    TextView tv;
    String url="192.168.19.172:8080/JSP/post.jsp"
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv=(TextView)findViewById(R.id.tv_1);
        init();
    }
    public void init(){
        RequestQueue queue=Volley.newRequestQueue(MainActivity.this); //首先创建一个请求队列...
       queue.add(new StringRequest(Method.POST, url, new Listener<String>() {
    
    @Override
    public void onResponse(String response) {
        // TODO Auto-generated method stub
        System.out.println(response.toString());
        tv.setText(response.toString()); //对获取的数据进行显示...
    }
}, new ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        // TODO Auto-generated method stub
          System.out.println(error.toString());            
    }
}){
      //在这个方法里完成参数的相关传递....
    @Override
    protected Map<String, String>getParams() throws AuthFailureError{
        Map<String, String>map=new HashMap<String, String>();
        map.put("name", "darker");
        map.put("password", "49681888");
        return map;
    }
});
}
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}




  使用Post请求来完成验证,毫无疑问,这里由于我们传递的参数时正确的,因此客户端会获取到Receive name is:darker,Receive password is:49681888,Your Message are right!这段信息...

  StringRequest请求非常的简单,涉及的东西也并不是很多,适合于发送网络请求来获取相应的字符串数据,呈递给客户端

友盟是一款移动应用统计分析平台。它可以帮助移动应用运营人员统计和分析流量来源、产品留存数据、用户属性和行为数据等,以便产品开发者和运营人员利用数据进行产品、运营、推广策略的决策。

软硬件环境
    Macbook Pro MGX 72
    Android Studio 1.3.2
    Genymotion模拟器


集成友盟SDK

首先到友盟官网http://www.umeng.com/注册个帐户,完成后到管理后台添加需要集成友盟统计的应用,如下

umneg_01

提交后,分给你的应用分配key,如下

umneg_02

接下来到http://dev.umeng.com/analytics/android-doc/sdk-download下载SDK,将下载下来的文件夹中的libs里的jar文件copy到工程中的libs中,在Android Studio中右键单击jar文件,选择Add as library完成导入。


配置AndroidManifest.xml

添加相应权限,如下

<uses-sdk android:minSdkVersion="4"></uses-sdk>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>

然后填写key和渠道id,一个包中只能添加一个渠道,如下

<meta-data android:value="这里填写友盟分配的key值" android:name="UMENG_APPKEY" />
<meta-data android:value="这里填写渠道名称,如Wandoujia或者360" android:name="UMENG_CHANNEL" />

集成代码

在每个Activity的onResume方法中调用MobclickAgent.onResume(Context),在onPause方法中调用MobclickAgent.onPause(Context)。如果Activity之间有继承关系,不要重复添加onResume和onPause方法,否则会出现重复统计,影响统计结果。如果App中有调用Process.kill或者System.exit之类的方法杀死进程,请务必在此之前调用MobclickAgent.onKillProcess(Context)方法,用来保存统计数据。

至此,基本功能已经集成完毕,还是很简单的。后续的一些高级功能,可以根据自己的需求另行添加,官方的文档已经写得很详细了,这里就不再写了,感兴趣的去友盟的官网查看。



友盟统计怎么算新增用户 android

Android 统计分析 SDK使用指南


1. 建立App,下载SDK


登录你的帐号后,看到友盟的管理后台,点击"+添加新应用",进入新应用信息填写的页面。

App建立成功后,可以获得该App的AppKey,以及最新的开发指南和SDK文件。

可在 这里 下载SDK,包含开发文档,demo程序和jar包。

说明:在新应用信息填写中,请尽量填写真实的信息。您可以通过友盟统计分析平台的特性节省重复建立App的时间。
如果您要对App不同的发布渠道进行统计,不需要创建新App,请使用分发渠道分析,通过分发渠道分析,您可以更方便的对比数据。

2. 实现基本的使用基本统计实现本的页面跳转,机型,分辨率,地理位置 …的统计1. 导入umeng-sdk*.jar(简称SDK)下载最新版sdk的zip包,解压将其中的umeng-sdk.jar释放到本地目录,Eclipse用户右键您的工程根目录,选择Properties -> Java Build Path -> Libraries, 然后点击 Add External JARs... 选择指向 Analytics_Android_SDK_*.jar的路径,点击OK,即导入成功。


2. 配置 AndroidManifest.xml

<manifest……><application ……> ……<activity ……/><meta-dataandroid:value="YOUR_APP_KEY"android:name="UMENG_APPKEY"></meta-data><meta-dataandroid:value="Channel ID"android:name="UMENG_CHANNEL"/></application><uses-sdkandroid:minSdkVersion="4"></uses-sdk><uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission><uses-permissionandroid:name="android.permission.INTERNET"></uses-permission><uses-permissionandroid:name="android.permission.READ_PHONE_STATE"></uses-permission><uses-permissionandroid:name="android.permission.READ_LOGS"></uses-permission></manifest>

说明:


META-DATA 用途
UMENG_APPKEY 用来定位该应用程序的唯一性。
UMENG_CHANNEL 用来标注应用推广渠道,区分新用户的来源来查看统计,您可以使用20位以内的英文和数字为渠道定名,替换value中的"Channel ID"。详见渠道统计。
权限 用途
INTERNET(必须) 允许应用程序联网,以便向我们的服务器端发送数据。
READ_PHONE_STATE(必须) 获取用户手机的IMEI,用来唯一的标识用户。(如果您的应用会运行在无法读取IMEI的平板上,我们会将mac地址作为用户的唯一标识,请添加权限: android.permission.ACCESS_WIFI_STATE )
ACCESS_NETWORK_STATE 检测网络状态,友盟SDK 1.6版本新增权限。
READ_LOGS 如果您想获得客户端crash的报告, 需要添加这个权限。具体见【使用错误报告】。
WRITE_EXTERNAL_STORAGE 如果您使用了友盟自动更新提醒功能,需添加这个权限,为了将更新的APK临时存在SD卡里。


3. 添加代码


添加引用: import com.umeng.analytics.MobclickAgent

注册 Activity: 在每个Activity的onResume方法中调用 MobclickAgent.onResume(Context), onPause方法中调用
MobclickAgent.onPause(Context)

publicvoid onResume() { super.onResume(); MobclickAgent.onResume(this);}publicvoid onPause() { super.onPause(); MobclickAgent.onPause(this);}API:public void onResume(Context context)
context 当前Activity的引用,这里请不要将全局的application context传入。
public void onPause(Context context)
context 当前Activity的引用,这里请不要将全局的application context传入。
API说明:
void onResume(Context context)
context 当前Activity引用

void onPause(Context context)
context 当前Activity引用

说明:
方法将会自动地从AndroidManifest.xml文件里读取Appkey。

确保在所有的activity中都调用 MobclickAgent.onResume() 和MobclickAgent.onPause()方法,这两个调用将不会阻塞应用程序的主线程,也不会影响应用程序的性能。

注意如果您的Activity之间有继承或者控制关系请不要同时在父和子Activity中重复添加onPause和onResume方法,否则会造成重复统计(eg.使用TabHost、TabActivity、ActivityGroup时)。

一个应用程序在多个activity之间连续切换时,将会被视为同一个session(启动)。

当用户两次使用之间间隔超过30秒时,将被认为是两个的独立的session(启动),例如用户回到home,或进入其他程序,经过一段时间后再返回之前的应用。

4. 测试


确认所需的权限都已经添加:INTERNET, READ_PHONE_STATE, (READ_LOGS, WRITE_EXTERNAL_STORAGE)

确认APPKEY已经正确的写入Androidmanifest.xml

确认所有的Activity中都调用了onResume和onPause方法

确认测试手机(或者模拟器)已成功连入网络

启动应用程序,几分钟之后您应该已经可以看到相应的报表.

3. 使用错误报告友盟统计分析工具,还可以帮助您捕捉用户在使用应用程序过程中出现的异常退出(FC), 并在应用程序下次启动时将错误报告发送给服务器。
1. 自动捕获异常退出(FC)
在AndroidManifest.xml里面添加权限android.permission.READ_LOGS

在程序的Main Activity(应用程序入口)的onCreate方法里调用MobclickAgent.onError(Context).

publicvoid onCreate(Bundle savedinstanceState) { super.onCreate(savedInstanceState); MobclickAgent.onError(this); ...}API:public void onError(Context context)
context 当前Activity的引用
说明:错误报告包含应用程序版本,操作系统版本和设备型号以及程序出现异常时的Stacktrace,这些数据将帮助您修正应用程序的Bug。
2. 手动发送错误报告如果您自己捕获了程序中的异常,但是依然希望,将这次异常信息发送到友盟的服务器,您可以调用下面的函数。
MobclickAgent.reportError(Context context,String error) API:public void reportError(Context context, String error)
context 当前Activity的引用

error 开发者手动捕获的错误信息
说明:手动发送的异常信息和自动捕获的异常信息一样,都会展示在错误报告面板。

4. 使用自定义事件除了基本统计分析功能外,我们还支持您自定义的事件分析,例如您可以统计游戏中通过不同关卡的人数,广告的点击次数或者视频被播放的次数等等。 使用自定义事件功能请先在网站应用管理后台(设置->编辑自定义事件)中添加相应的自定义事件后,服务器才会对相应的自定义事件请求进行处理。
1. 事件数量统计1. 在您希望跟踪的代码部分,调用如下方法:MobclickAgent.onEvent(Context context, String event_id);API:public void onEvent(Context context, String event_id)
context 当前Activity的引用

event_id 为当前统计的事件ID,注意要先在友盟网站上注册此事件ID。
示例:统计微博应用中“转发"事件发生的次数,那么在“转发"的函数里调用
MobclickAgent.onEvent(this, "Forward") 2. 记录事件的不同属性及取值,调用如下方法:MobclickAgent.onEvent(Context context, String event_id, Map<String,String>; map);API:public voidonEvent(Context context, String event_id, Map map)
context 当前Activity的引用

event_id 为当前统计的事件ID,注意要先在友盟网站上注册此事件ID。

map 为当前事件的属性和取值集合(key-value)
示例:MobclickAgent.onEvent(LoginActivity.this, "sinaLogin");
新浪用户登陆海知笔记

3. 考虑事件在一个属性上的取值,可以调用如下方法:MobclickAgent.onEvent(Context context, String event_id, String label);API:public void onEvent(Context context, String event_id, String label)
context 当前Activity的引用

event_id 为当前统计的事件ID,注意要先在友盟网站上注册此事件ID.

label 事件的一个属性描述
示例:统计游戏中“死亡"事件发生的关卡数,那么可以在死亡的函数里调用
MobclickAgent.onEvent(this, "player_dead","level");2. 事件时长统计有的事件是持续发生的,需要记录其持续的时间,这里提供两种解决方法。
1. 在事件开始和结束时分别调用onEventBegin和 onEventEnd两个函数。MobclickAgent.onEventBegin(Context context, String event_id);...MobclickAgent.onEventEnd(Context context, String event_id);API:public voidonEventBegin(Context context, String event_id)

public void onEventEnd(Context context, String event_id)
context 当前Activity引用

event_id 为当前统计的事件ID,注意要先在友盟网站上注册此事件ID.
public void onEventBegin(Context context, String event_id, String label)

public void onEventEnd(Context context, String event_id, String label)
context 当前Activity引用

event_id 为当前统计的事件ID,注意要先在友盟网站上注册此事件ID.

label 事件的一个属性描述
示例:跟踪播放音乐事件发生的总时间,在音乐播放开始时调用:
MobclickAgent.onEventBegin(this, "music_play");在音乐播放结束时调用:
MobclickAgent.onEventEnd(this, "music_play");2. 跟踪时长的事件包含多个属性,在事件开始和结束时分别调用onKVEventBegin和 onKVEventEnd两个函数MobclickAgent.onKVEventBegin(Context context, String event_id, Map<String,String> map, String ekvFlag);...MobclickAgent.onKVEventEnd(Context context, String event_id, String ekvFlag);API:public void onKVEventBegin(Context context, String event_id, Map map, String ekvFlag)
context 当前Activity引用

event_id 为当前统计的事件ID,注意要先在友盟网站上注册此事件ID.

map 为当前事件的属性和取值集合(key-value)

ekvFlag 事件标示符
public void onKVEventEnd(Context context, String event_id, String ekvFlag)
context 当前Activity引用

event_id 为当前统计的事件ID,注意要先在友盟网站上注册此事件ID

ekvFlag 事件标示符,ekvFlag 和 event_id 一起标示一个唯一事件,并不会被统计;对于同一个事件,在onKVEventBegin和onKVEventEnd 中要传递相同的event_id 和 flag
示例跟踪每种类型的音乐播放了多久,在音乐播放开始时调用
Map<String,String> music = new HashMap<String,String>(); music.put("type", "popular"); music.put("artist", "JJLin"); music.put("User_status", "registered");MobclickAgent.onKVEventBegin(this, "music",music,"m7");在音乐播放结束时调用:
MobclickAgent.onKVEventEnd(this, "music",music,"m7");3. 自己计算并上传event时长,在您想跟踪时长的代码部分,调用如下方法:MobclickAgent.onEventDuration(Context context, String event_id, long duration);orMobclickAgent.onEventDuration(Context context, String event_id,String label, long duration)orMobclickAgent.onEventDuration(Context context, String event_id, Map<String, String> map, long duration)API:public void onEventDuration(Context context, String event_id, long duration)

public void onEventDuration(Context context, String event_id,String label, long duration)
context 当前Activity引用

event_id 为当前统计的事件ID,注意要先在友盟网站上注册此事件ID

label 事件的一个属性描述

duration 事件持续时长,单位毫秒,您需要手动计算并传入时长,作为事件的时长参数
public void onEventDuration(Context context, String event_id, Map map, long duration)
context 当前Activity引用

event_id 为当前统计的事件ID,注意要先在友盟网站上注册此事件ID

map 为当前事件的属性和取值集合(key-value)

duration 事件持续时长,单位毫秒,您需要手动计算并传入时长,作为事件的时长参数
说明
时长是友盟统计的一个新功能,使用过程中可能会出现一些常见的错误,开发者应该尽量的避免,这里有一些可能出错的案例。

每个event的key不能超过10个,event ID、map中key和value都不能使用特殊字符,且长度不能超过255个字符(否则将截取前255个字符),“id", “ts", “du"是保留字段,不能作为event ID及key的名称

5. 使用分发渠道分析有时需要统计应用程序的分发渠道,例如有多少用户来从联想乐园下载了您的应用,又有多少用户通过Google android market下载到您的应用程序。您只需要在AndroidManifest.xml里添加meta-data,并将 value属性修改为对应的发布渠道名。
配置AndroidManifest.XML添加下面代码
<application ……><activity ……/><meta-dataandroid:value="Channel ID"android:name="UMENG_CHANNEL"/></application>当然,这需要您在不同渠道发布应用程序时,重新编译打包。
说明
不要改变'UMENG_CHANNEL',修改'Channel ID'为您的渠道名称,注意不能是纯数字(eg.value="AndroidMarket")。

每台设备只记录第一次统计到的渠道,您如果在测试的时候发现渠道统计到的设备数量不增加,很可能是因为您用同一个设备修改过渠道号,您换一台设备测试即可。

6. 使用在线配置功能这个功能目前可以帮你在网站上动态配置两种类型的参数:

自定义key-value型的键值对

数据发送策略

在程序的入口Activity的OnCreate()方法中调用
publicvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MobclickAgent.updateOnlineConfig(this);}API:public voidupdateOnlineConfig(Context context)

下面我们一起来看一篇关于安卓开发之自定义ProgressBar简单完成颜色渐变功能进度条的例子,希望文章能够对各位有帮助。

我们在使用电脑或者手机时,经常会遇到进度条,比如下图:

今天我来演示一下,如何做出简单并且漂亮的颜色渐变进度条。

首先我先新建了一个系统默认样式的进度条,代码如下:

运行后显示如下:
大家可以看出,并不是很好看,那么下面开始进行自定义进度条的编写吧!
首先为ProgressBar设置一个drawable,代码如下:
这个代码在哪呢,请回到上面新建系统默认样式进度条时,其中一个属性为  style=”@android:style/Widget.Holo.ProgressBar.Horizontal”这条设置了进度条的style为Widget.Holo.ProgressBar.Horizontal,我们点进去看一下代码,如下图:
,我们看到一条属性为progressDrawable,继续跟上,发现代码如下:
,其中有三个ID,分别为background,secondaryProgress和progress,其中background为进度条的背景,secondaryProgress不清楚何功能,据说是在网上看在线视频的时候,缓冲进度显示的那个灰色的进度条,这里不管,progress为进度条的样子。
我们新建一个名为progress的layer-listXML文件,我们把IDprogress的内容拷贝到progress中,增删其中代码如下:
,主要属性 : 颜色为橙色到橙红色之间的渐变,圆角360dp表示左右两边为半圆.在ProgressBar中引用为:
:运行结果如下:
颜色渐变效果出现了,是不是挺好看的,这只是我自己加的颜色,如果有设计师提供精美图片,那么,还会更美丽。我们在他外面加层RelativeLayout,并设置一个shape,增加美观度,shape名字为shape_progressbar,
shape代码如下:
总代码如下
 
效果如下:

至此,自定义progressbar颜色渐变功能完成!

报错UTF-8+BOM我们知道是文件头有空格或一些字符所导致了,对于这个问题我们只需要通过记事本或一些编辑器即可解决,具体操作如下。
今天在用Android studio运行程序的时候,突然报了一种从未见过的错误,如图:

然后我就clean和build,结果都不好使,程序仍然报错,我请教了身边的大神,结果也没见过这种奇葩的情况,最后通过查询网上的解决办法及自己的总结,现整理出一套完美的解决方案。

错误原因,代码编码格式错误,平常我们都用UTF-8格式,之所以报上述错误,是因为编码格式变成了UTF-8+BOM格式,而以前我们编写Android程序都是用eclipse来写,eclipse可以自动把UTF-8+BOM格式转换成UTF-8格式,而Android studio没有这种功能。所以这种错误并不常见。
首先:打开Android studio的设置,把编码格式全部设置成UTF-8格式,此刻你可以试试是否还报错,我的结果是仍然没有解决。
其次,我们需要第三方软件,这里就用editplus来演示解决办法。安装完editplus之后打开软件,然后在里面打开报错的java文件,在菜单栏里点击Document命令,选择File Encoding——Convert Encoding,如图:

image

弹出Convert Encoding对话框,这时我们可以看到编码格式就是UTF-8+BOM,然后我们把它改成UFT-8就可以了,如图:imag2e

再去Android studio运行程序,就不会再报错了

[!--infotagslink--]

相关文章

  • php读取zip文件(删除文件,提取文件,增加文件)实例

    下面小编来给大家演示几个php操作zip文件的实例,我们可以读取zip包中指定文件与删除zip包中指定文件,下面来给大这介绍一下。 从zip压缩文件中提取文件 代...2016-11-25
  • Jupyter Notebook读取csv文件出现的问题及解决

    这篇文章主要介绍了JupyterNotebook读取csv文件出现的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2023-01-06
  • Android子控件超出父控件的范围显示出来方法

    下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
  • Photoshop打开PSD文件空白怎么解决

    有时我们接受或下载到的PSD文件打开是空白的,那么我们要如何来解决这个 问题了,下面一聚教程小伙伴就为各位介绍Photoshop打开PSD文件空白解决办法。 1、如我们打开...2016-09-14
  • 解决python 使用openpyxl读写大文件的坑

    这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
  • C#实现HTTP下载文件的方法

    这篇文章主要介绍了C#实现HTTP下载文件的方法,包括了HTTP通信的创建、本地文件的写入等,非常具有实用价值,需要的朋友可以参考下...2020-06-25
  • SpringBoot实现excel文件生成和下载

    这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
  • C#操作本地文件及保存文件到数据库的基本方法总结

    C#使用System.IO中的文件操作方法在Windows系统中处理本地文件相当顺手,这里我们还总结了在Oracle中保存文件的方法,嗯,接下来就来看看整理的C#操作本地文件及保存文件到数据库的基本方法总结...2020-06-25
  • php无刷新利用iframe实现页面无刷新上传文件(1/2)

    利用form表单的target属性和iframe 一、上传文件的一个php教程方法。 该方法接受一个$file参数,该参数为从客户端获取的$_files变量,返回重新命名后的文件名,如果上传失...2016-11-25
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • php批量替换内容或指定目录下所有文件内容

    要替换字符串中的内容我们只要利用php相关函数,如strstr,str_replace,正则表达式了,那么我们要替换目录所有文件的内容就需要先遍历目录再打开文件再利用上面讲的函数替...2016-11-25
  • Android模拟器上模拟来电和短信配置

    如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
  • PHP文件上传一些小收获

    又码了一个周末的代码,这次在做一些关于文件上传的东西。(PHP UPLOAD)小有收获项目是一个BT种子列表,用户有权限上传自己的种子,然后配合BT TRACK服务器把种子的信息写出来...2016-11-25
  • 夜神android模拟器设置代理的方法

    夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
  • AI源文件转photoshop图像变模糊问题解决教程

    今天小编在这里就来给photoshop的这一款软件的使用者们来说下AI源文件转photoshop图像变模糊问题的解决教程,各位想知道具体解决方法的使用者们,那么下面就快来跟着小编...2016-09-14
  • android自定义动态设置Button样式【很常用】

    为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
  • C++万能库头文件在vs中的安装步骤(图文)

    这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • Zend studio文件注释模板设置方法

    步骤:Window -> PHP -> Editor -> Templates,这里可以设置(增、删、改、导入等)管理你的模板。新建文件注释、函数注释、代码块等模板的实例新建模板,分别输入Name、Description、Patterna)文件注释Name: 3cfileDescriptio...2013-10-04
  • php文件上传你必须知道的几点

    本篇文章主要说明的是与php文件上传的相关配置的知识点。PHP文件上传功能配置主要涉及php.ini配置文件中的upload_tmp_dir、upload_max_filesize、post_max_size等选项,下面一一说明。打开php.ini配置文件找到File Upl...2015-10-21
  • Android WebView加载html5页面实例教程

    如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20