手机监控业务是把无线监控设备的视频信号通过公众无线移动通信网络传输,实现实时在线查看现场情况,不受时间和地域限制的3G新业务。用户可以随时随地主动去查看监控现场,或者当有报警信号产生的时候,也可以马上得到通知,并通过查看现场情况对报警进行确认。
手机监控系统的基本功能有:
实时报警:监控场地发生意外情况时,通过活动视频向手机报警。
主动查看:平时也可以随时随地的查看监控场地的情况。
在线设置:可以通过手机对监控设备进行设置,比如是否入侵检测,开机关机,图像设置等。
多手机支持:一部手机由于关机或是网络原因无法联系时,向其他手机报警。
除了在安防领域应用,视频信息的及时获取也是手机视频监控重要应用,如交通信息的实时获取、医院病人的探视、幼儿园小孩的探视、企业运营管理等。
家庭用户广泛认知
诺达咨询调查数据表明,分别有48%、42%和38%的用户认为手机监控可以应用于家庭防盗和家庭幼儿及老人监管以及家庭安全,其次,有30%-35%的用户认为手机监控可以应用于店铺防盗、交通信息的实时发布。有28%的用户认为手机监控可以应用于医院病人监护。另外,有不到25%的用户认为,手机监控可以应用于孩童在幼儿园活动的监看、宠物在家情况监看和企业安全与管理。
以上调查数据可以看出,在我国,目前普遍被大众认知和认可的手机监控是家庭监控,包括家庭防盗监控、家庭幼儿及老人监看和家庭安全监控。其他方面应用如店铺防盗、实时交通信息、医院病人监护、幼儿园儿童活动、宠物在家情况的应用用户认知度较低,这些方面应用的试用人群也相对较小。
对于企业安全与企业管理,从大众用户对其认知度来看,对其应用的价值认可度不高,同时由于手机终端的特性,与网络视频监控比较,更适合家庭和中小企业用户。
图1用户对手机视频监控应用于不同领域的认知
用户担心问题
诺达咨询对没有使用手机视频监控的用户原因进行调查,结果表明,43%的用户担心资费太高,其次对手机监控不了解和不需要此项服务的用户各占32%、30%。22%的用户担心性价比不高,12%用户因为使用比较麻烦而不选择手机视频监控服务。
图2用户手没有使用手机监控服务的原因
综合以上用户调查情况并结合市场进行分析,目前手机视频监控业务所面临的主要问题有以下四方面。
第一,资费是目前影响用户开通手机视频监控服务的重要因素。
诺达咨询进一步对用户开通手机监控服务的主要考虑因素进行调查,结果表明,最重要的因素为资费,有66%的用户认为资费是重要的考虑因素。其次,46%的用户认为获取服务的方便性(即业务办理流程)是影响用户开通手机监控业务的重要因素。其他,包括服务商的质量保障、设备成本、隐私安全和使用难易度对用户也有一定的影响,但是影响较小。
图3影响用户开通手机监控服务的主要因素
第二,用户认知度较低,
从诺达咨询调查数据来看,用户目前对手机监控的认知度还比较低,54%的用户对其了解一点,而39%的用户对其不了解,只有8%的用户对手机监控业务非常了解。
图4 用户对手机视频监控服务的了解
对我国手机监控业务用户认知度较低的现状进行分析,主要原因是:
一方面,运营商虽然早在2004年就有相关业务和产品推出,但是主要集中在行业和企业用户,在家庭用户方面的业务产品相对较少。加之个人及家庭用户对手机监控的需求还不高,用户对相关知识获取的主动性也较小。
另一方面,运营商的宣传不到位。从诺达咨询调查数据来看,用户目前获得手机视频监控相关信息的主要渠道是互联网,有51%的用户是通过互联网了解手机视频监控的,而从传统的电视媒体和报刊杂志获得相关信息的用户仅仅约各占24%,通过相关手机视频监控企业发放宣传资料和介绍获取相关信息的用户各占12%和10%。由此可见,手机视频监控的宣传尚不到位,导致消费者不能通过多方渠道获取相关信息。
图5用户手机监控相关信息获取渠道分布
第三,用户对服务质量不满意,担心性价比不高。
从图表2可以看出,有22%的用户不选择开通手机视频服务是担心性价比不高。同时,从诺达咨询对手机监控用户满意度调查来看,71%的用户认为目前的服务一般,18%的用户表示满意,非常满意的用户占9%。由此看见,大部分用户对目前的手机监控服务是可以接受的。在此,服务质量包括视频质量、日常系统维护等服务。分析其原因,一方面,开通手机监控的用户可以通过手机实现其对一定场所、人物的监看,但是,受目前网络建设等因素制约,视频传送或相关服务尚不能使用户满意。另一方面,三大运营商的产品都没有得到很好的推广和应用,因此,用户也无法通过比较对在使用的服务进行明确的评价。
第四,手机视频设备价格偏高。
诺达咨询调查数据表明,可以接受的购买手机监控设备的费用在100元以下的用户占38%,有同样比例的用户对100-200元的设备费用也可以接受,16%的用户对200-500元的设备费用可以接受。
图7用户可以接受的购买手机监控设备费用
手机视频监控系统一般分为服务器、现场终端、用户终端3个组成部分。
目前的厂商和服务提供商还停留在传统监控的观念上,将手机视频监控作为很专业的安防产品来定价,根据目前市场报价,家用的手机监控器终端一般在2000元至3000元之间,也可以通过电脑及电脑摄像头完成前端信息的采集,不需要购买其他设备,但效果稍差。与诺达咨询调查结果比较,目前效果较好的手机视频监控需要的前端设备2000-3000元的费用与用户对设备费用100元以下的期望还存在非常大的差距。
诺达咨询认为,如果手机视频设备价格在3000元左右,个人商铺、连锁店、工厂等行业用户会尝试使用,针对家庭及个人市场需求和性价比而言,手机视频监控前端设备的市场价格至少应该在1000元以内,才能吸引多数用户使用。
另外手机视频监控是一种长期经营的业务模式,用户可能要使用5年甚至更长的时间,所以服务器的稳定和扩容,客服人员上门服务的成本,长期也是一笔不小的开支。从长远来讲,如果运营商降低设备初装价格,在服务环节创造一部分利润,既节约了用户的短期成本,培育了市场,又有利于服务的稳定和价值链的形成。
合理资费与扩大宣传是市场发展关键
针对手机视频监控市场的发展问题,应从以下几方面予以解决:
第一,调整资费,扩大用户。
诺达咨询调查数据表明,用户可以接受的手机监控月资费以20元以下居多,占45%,其次20-50元占30%,50-80元占14%。
目前的资费标准与用户20元以下的资费期望值存在很大差距,如果个人或家庭用户的资费可以降低到20-50元,手机视频监控服务将可以被大多数用户所接受。
资费和设备的价格能否被大多数的消费者所接受是推广手机视频监控业务的关键因素。对消费者而言,决定选择哪家运营商服务的最大支点仍在资费,因此,在3G业务开展初期,建议运营商不要只注重短期投资回报率,而放弃占领用户市场的先机。
图8用户可以接受的家庭或个人手机监控月服务费
第二,扩大宣传,提高用户认知度。
随着3G网络建设和各项业务的开展,运营商的宣传力度也不断增强,但是,目前用户对3G业务的了解还以手机电视业务最为熟悉,多数用户对手机视频监控业务的了解仅限于听说过,因此,运营商一方面应该扩大宣传面,除了互联网,开展在电视广播和报纸杂志上等媒体的宣传,扩大受众群体。另一方面,运营商应该细化宣传内容,对于资费标准、交费方式、服务开通办理流程以及用户关心的信息保密等内容给出消费者详细的信息。
第三,改善体验,培养用户习惯。
用户习惯决定市场,目前,受到数据传输速率和大部分用户终端视频播放功能等因素的限制,手机视频监控远不及手机短信等应用普及,手机视频监控未来的目标用户使用习惯尚未形成。在这种情况下,服务商需要从长远利益出发,对市场进行培育,引导用户的消费习惯。运营商可以尝试让部分手机用户经过免费体验接受服务进一步使用户养成消费习惯。
手机视频监控将追随3G脚步发展
手机视频监控系统作为涉及安防和移动通信领域的
从国外的视频监控市场可以看出,个人用户是视频监控领域不可缺少的重要客户,一直以来,我国发展稍快的网络视频监控业务主要集中在行业用户上,由于家用视频监控一直没有形成规模,产业链也没有完全形成,加上造价、设备复杂性方面的影响,家用视频监控市场一直没有显著的发展。近年来,随着人们生活条件的改善,国内市场对适合民用的安全监控系统的需求有所升温,以手机为终端的视频监控,从设备外观、功能、应用和价格等方面正不断贴近家庭市场的消费需求。
3G网络技术和移动终端的不断发展,为手机视频监控的出现和推广提供了必要的条件,市场需求为手机视频监控的发展提供了广阔空间。同时也是3G市场发展的主要推动力量,是未来移动通信重要的市场增长点。随着3G商用步伐加快,3G无线网络技术也在加速创新。
图9 2006-2011年中国手机监控市场规模及预测
根据诺达咨询《手机视频监控市场及用户行为研究报告2009》研究结果,2006-2009年为手机监控业务导入期,2006年手机监控业务市场规模达到1.3亿人民币,手机监控业务的年运营费用自2009年开始,将会逐步下降,目前平均约1000元/年,至2011年将逐步下降到600元/年,设备费用也将由目前的3000元/点,逐步下降到2011年的1000元/点。
由此估算出2009年,中国手机监控市场规模将达到19.5亿元,2011年,中国手机监控业务市场规模将达到72.2亿元。
<!--<center></center>-->第一步:新建一个继承Activity的类,如:NewActivity public class NewActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //这里可以使用setContentView(R.layout.xxx)显示某个视图.... } } 第二步:需要在功能清单AndroidManifest.xml文件中添加进上面Activity配置代码(红色部分): <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cn.itcast.action" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> ..... <activity android:name=".NewActivity" android:label="新activity的页面标题"/> </application> ... </manifest> android:name属性值的前面加了一个点表示NewActivity是当前包cn.itcast.action下的类,如果类在应用的当前包下,可以省略点符号,如果类在应用的子包下必须加点,如:NewActivity类在cn.itcast.action.user包下可以这样写:<activity android:name=“.user.NewActivity“ />
在一个Activity中可以使用系统提供的startActivity(Intent intent)方法打开新的Activity,在打开新的Activity前,你可以决定是否为新的Activity传递参数: 第一种:打开新的Activity,不传递参数 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { ....... Button button =(Button) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener(){//点击该按钮会打开一个新的Activity public void onClick(View v) { //新建一个显式意图,第一个参数为当前Activity类对象,第二个参数为你要打开的Activity类 startActivity(new Intent(MainActivity.this, NewActivity.class)); }}); } }
第二种:打开新的Activity,并传递若干个参数给它: public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { ....... button.setOnClickListener(new View.OnClickListener(){//点击该按钮会打开一个新的Activity public void onClick(View v) { Intent intent = new Intent(MainActivity.this, NewActivity.class) Bundle bundle = new Bundle();//该类用作携带数据 bundle.putString("name", "传智播客"); bundle.putInt("age", 4); intent.putExtras(bundle);//附带上额外的数据 startActivity(intent); }}); } } 在新的Activity中接收前面Activity传递过来的参数: public class NewActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { ........ Bundle bundle = this.getIntent().getExtras(); String name = bundle.getString("name"); int age = bundle.getInt("age"); } }
Bundle类用作携带数据,它类似于Map,用于存放key-value名值对形式的值。相对于Map,它提供了各种常用类型的putXxx()/getXxx()方法,如:putString()/getString()和putInt()/getInt(),putXxx()用于往Bundle对象放入数据,getXxx()方法用于从Bundle对象里获取数据。Bundle的内部实际上是使用了HashMap<String, Object>类型的变量来存放putXxx()方法放入的值: public final class Bundle implements Parcelable, Cloneable { ...... Map<String, Object> mMap; public Bundle() { mMap = new HashMap<String, Object>(); ...... } public void putString(String key, String value) { mMap.put(key, value); } public String getString(String key) { Object o = mMap.get(key); return (String) o; ........//类型转换失败后会返回null,这里省略了类型转换失败后的处理代码 } } 在调用Bundle对象的getXxx()方法时,方法内部会从该变量中获取数据,然后对数据进行类型转换,转换成什么类型由方法的Xxx决定,getXxx()方法会把转换后的值返回。
第一种写法,用于批量添加数据到Intent: Intent intent = new Intent(); Bundle bundle = new Bundle();//该类用作携带数据 bundle.putString("name", "传智播客"); intent.putExtras(bundle);//为意图追加额外的数据,意图原来已经具有的数据不会丢失,但key同名的数据会被替换 第二种写法:这种写法的作用等价于上面的写法,只不过这种写法是把数据一个个地添加进Intent,这种写法使用起来比较方便,而且只需要编写少量的代码。 Intent intent = new Intent(); intent.putExtra("name", "传智播客"); Intent提供了各种常用类型重载后的putExtra()方法,如: putExtra(String name, String value)、 putExtra(String name, long value),在putExtra()方法内部会判断当前Intent对象内部是否已经存在一个Bundle对象,如果不存在就会新建Bundle对象,以后调用putExtra()方法传入的值都会存放于该Bundle对象,下面是Intent的putExtra(String name, String value)方法代码片断: public class Intent implements Parcelable { private Bundle mExtras; public Intent putExtra(String name, String value) { if (mExtras == null) { mExtras = new Bundle(); } mExtras.putString(name, value); return this; }
使用startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,在新的Activity关闭前需要向前面的Activity返回数据需要使用系统提供的setResult(int resultCode, Intent data)方法实现: public class NewActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { ...... button.setOnClickListener(new View.OnClickListener(){ public void onClick(View v) { Intent intent = new Intent();//数据是使用Intent返回 intent.putExtra(“result”, “传智播客的学生很可爱”);//把返回数据存入Intent NewActivity.this.setResult(RESULT_OK, intent);//设置返回数据 NewActivity.this.finish();//关闭Activity }}); } } setResult()方法的第一个参数值可以根据业务需要自己定义,上面代码中使用到的RESULT_OK是系统Activity类定义的一个常量,值为-1,代码片断如下: public class android.app.Activity extends ......{ public static final int RESULT_CANCELED = 0; public static final int RESULT_OK = -1; public static final int RESULT_FIRST_USER = 1; }
使用startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,我们需要为startActivityForResult()方法传入一个请求码(第二个参数)。请求码的值是根据业务需要由自已设定,用于标识请求来源。例如:一个Activity有两个按钮,点击这两个按钮都会打开同一个Activity,不管是那个按钮打开新Activity,当这个新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。在onActivityResult()方法如果需要知道新Activity是由那个按钮打开的,并且要做出相应的业务处理,这时可以这样做: @Override public void onCreate(Bundle savedInstanceState) { .... button1.setOnClickListener(new View.OnClickListener(){ public void onClick(View v) { startActivityForResult (new Intent(MainActivity.this, NewActivity.class), 1); }}); button2.setOnClickListener(new View.OnClickListener(){ public void onClick(View v) { startActivityForResult (new Intent(MainActivity.this, NewActivity.class), 2); }}); @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch(requestCode){ case 1: //来自按钮1的请求,作相应业务处理 case 2: //来自按钮2的请求,作相应业务处理 } } }
在一个Activity中,可能会使用startActivityForResult()方法打开多个不同的Activity处理不同的业务,当这些新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。为了知道返回的数据来自于哪个新Activity,在onActivityResult()方法中可以这样做(ResultActivity和NewActivity为要打开的新Activity): public class ResultActivity extends Activity { ..... ResultActivity.this.setResult(1, intent); ResultActivity.this.finish(); } public class NewActivity extends Activity { ...... NewActivity.this.setResult(2, intent); NewActivity.this.finish(); } public class MainActivity extends Activity { // 在该Activity会打开ResultActivity和NewActivity @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch(resultCode){ case 1: // ResultActivity的返回数据 case 2: // NewActivity的返回数据 } } }
Android基本的设计理念是鼓励减少组件间的耦合,因此Android提供了Intent (意图) ,Intent提供了一种通用的消息系统, 它允许在你的应用程序与其它的应用程序间传递Intent来执行动作和产生事件。 使用Intent可以激活Android应用的三个核心组件:活动、服务和广播接收器。 Intent可以划分成显式意图和隐式意图。 显式意图:调用Intent.setComponent()或Intent.setClass()方法指定了组件名或类对象的Intent为显式意图, 显式意图明确指定了Intent应该传递给哪个组件。 隐式意图:没有调用Intent.setComponent()或Intent.setClass()方法指定组件名或类对象的Intent为隐式意图。 Android系统会根据隐式意图中设置的动作(action)、 类别(category)、数据(URI和数据类型)找到最合适的组件来处理这个意图。 那么Android是怎样寻找到这个最合适的组件呢?记的前面我们在定义活动时,指定了一个intent-filter, Intent Filter(过滤器)其实就是用来匹配隐式Intent的, 如果Intent Filter定义的动作、类别、数据(URI和数据类型)与Intent匹配, 就会使用Intent Filter所在的组件来处理该Intent。 想要接收使用startActivity()方法传递的隐式意图的活动必须在它们的意图过滤器中包含"android.intent.category.DEFAULT"
下面请看例子
设计视图
主界面 main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button" android:id="@+id/button" /> </LinearLayout>
分界面
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="@string/context" android:id="@+id/result" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/finish" android:id="@+id/finish" /> </LinearLayout>
string.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, OneActivity!</string> <string name="app_name">多个Activity的使用</string> <string name="context">这是新的Activity</string> <string name="button">打开新的Activity</string> <string name="finish">关闭</string> </resources>
资源配置文件 androidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.file" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".OneActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- 应用的是 应用的标题 --> <activity android:name=".otherActivity" android:label="@string/context"></activity> </application> <uses-sdk android:minSdkVersion="7" /> </manifest>
主Activity
package com.file; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; /** * 这个是程序入口的Activity * @author Administrator * */ public class OneActivity extends Activity { private static final String tag="OneActivity"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button button=(Button)this.findViewById(R.id.button); //为按钮设置单击事件 button.setOnClickListener(listener); } private View.OnClickListener listener=new View.OnClickListener() { @Override public void onClick(View v) { /** * 打开新的Activity 在打开新的Activity之前,必须在当前的Activity对应的清单文件中进行配置 * 这好比是stuts1的action的重定向 * 组件和组件之间的联系是通过意图Intent来实现 这里德组件指的是Activity */ //写法一 /** * 这个意图 表示是执行OneActivity的这个应用的otherActivity的应用 定义意图是做什么操作 */ Intent intent=new Intent(OneActivity.this, otherActivity.class); //设置传递参数 intent.putExtra("id", 100); intent.putExtra("name", "liming"); /** * 执行这个意图 把这个意图交给操作系统去处理 */ OneActivity.this.startActivityForResult(intent, 3); //写法二 //Intent intent=new Intent(); //intent.setClass(OneActivity.this, otherActivity.class); //写法三 /** * 三种写法都是等价的 都是打开应用里面的组件 */ //Intent intent=new Intent(); //intent.setComponent(new ComponentName(OneActivity.this, otherActivity.class)); } }; /** * 接受返回的参数的方法 * 参数 请求码 结果码 意图返回的数据 */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Log.i(tag, "requestCode=="+requestCode+" resultCode=="+resultCode); Log.i(tag, "data=="+data); if(resultCode==12){ //获取意图里的信息 data.getStringExtra("result"); Log.i(tag,data.getStringExtra("result")); } super.onActivityResult(requestCode, resultCode, data); } }
次要的Activity
package com.file; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; public class otherActivity extends Activity { private TextView textview; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState);//执行构造一个界面 setContentView(R.layout.otherui); //执行要使用的界面 textview=(TextView)this.findViewById(R.id.result); Intent intent=otherActivity.this.getIntent();//获取传递过来的意图 int id=intent.getIntExtra("id", 0); //获取意图传递过来的参数 方法对应的 参数一 参数名 默认的值 String name=intent.getStringExtra("name"); textview.setText("id为:"+id+",name:"+name); Button button = (Button)this.findViewById(R.id.finish); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent();//数据是使用Intent返回 intent.putExtra("result", "itcast student");//把返回数据存入Intent otherActivity.this.setResult(12, intent);//设置返回数据 otherActivity.this.finish(); } }); } }
好了 到这里就结束了 看懂了代码就自然懂了
//放大缩小图片
public static Bitmap zoomBitmap(Bitmap bitmap,int w,int h){
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Matrix matrix = new Matrix();
float scaleWidht = ((float)w / width);
float scaleHeight = ((float)h / height);
matrix.postScale(scaleWidht, scaleHeight);
Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
return newbmp;
}
//将Drawable转化为Bitmap
public static Bitmap drawableToBitmap(Drawable drawable){
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height,
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0,0,width,height);
drawable.draw(canvas);
return bitmap;
}