现在几乎所有app应用都可以调用手机的照相功能了,但我在开始时碰到一个问题就是拍照之后在系统相册中找不到我拍照的照片怎么办?下面我来给各位同学一并分享一下。
系统已经有的东西,如果我们没有新的需求的话,直接调用是最直接的。下面讲讲调用系统相机拍照并保存图片和如何调用系统相册的方法。
首先看看调用系统相机的核心方法:
代码如下 |
复制代码 |
Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(camera, CAMERA);
|
相机返回的数据通过下面的回调方法取得,并处理:
代码如下 |
复制代码 |
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == CAMERA && resultCode == Activity.RESULT_OK && null != data){
String sdState=Environment.getExternalStorageState();
if(!sdState.equals(Environment.MEDIA_MOUNTED)){
GameLog.log(Tag, "sd card unmount");
return;
}
new DateFormat();
String name= DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA))+".jpg";
Bundle bundle = data.getExtras();
//获取相机返回的数据,并转换为图片格式
Bitmap bitmap = (Bitmap)bundle.get("data");
FileOutputStream fout = null;
File file = new File("/sdcard/pintu/");
file.mkdirs();
String filename=file.getPath()+name;
try {
fout = new FileOutputStream(filename);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fout);
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
try {
fout.flush();
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//显示图片
}
}
|
下面是调用系统相册并取得照片的方法:
代码如下 |
复制代码 |
Intent picture = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(picture, PICTURE);
|
下面是相应的回调方法:
代码如下 |
复制代码 |
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == CAMERA && resultCode == Activity.RESULT_OK && null != data){
Uri selectedImage = data.getData();
String[] filePathColumns={MediaStore.Images.Media.DATA};
Cursor c = this.getContentResolver().query(selectedImage, filePathColumns, null,null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePathColumns[0]);
String picturePath= c.getString(columnIndex);
c.close();
//获取图片并显示
}
|
这样就完成了系统调用,很简单,但是有些朋友会碰到照片拍好了,在手机相册中发现照片不显示呀。
解决Android拍照保存在系统相册不显示的问题
MediaStore.Images.Media.insertImage(getContentResolver(), mBitmap, "", "");通过上面的那句代码就能插入到系统图库,这时候有一个问题,就是我们不能指定插入照片的名字,而是系统给了我们一个当前时间的毫秒数为名字,有一个问题郁闷了很久,我还是先把insertImage的源码贴出来吧
代码如下 |
复制代码 |
/**
* Insert an image and create a thumbnail for it.
*
* @param cr The content resolver to use
* @param source The stream to use for the image
* @param title The name of the image
* @param description The description of the image
* @return The URL to the newly created image, or <code>null</code> if the image failed to be stored
* for any reason.
*/
public static final String insertImage(ContentResolver cr, Bitmap source,
String title, String description) {
ContentValues values = new ContentValues();
values.put(Images.Media.TITLE, title);
values.put(Images.Media.DESCRIPTION, description);
values.put(Images.Media.MIME_TYPE, "image/jpeg");
Uri url = null;
String stringUrl = null; /* value to be returned */
try {
url = cr.insert(EXTERNAL_CONTENT_URI, values);
if (source != null) {
OutputStream imageOut = cr.openOutputStream(url);
try {
source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut);
} finally {
imageOut.close();
}
long id = ContentUris.parseId(url);
// Wait until MINI_KIND thumbnail is generated.
Bitmap miniThumb = Images.Thumbnails.getThumbnail(cr, id,
Images.Thumbnails.MINI_KIND, null);
// This is for backward compatibility.
Bitmap microThumb = StoreThumbnail(cr, miniThumb, id, 50F, 50F,
Images.Thumbnails.MICRO_KIND);
} else {
Log.e(TAG, "Failed to create thumbnail, removing original");
cr.delete(url, null, null);
url = null;
}
} catch (Exception e) {
Log.e(TAG, "Failed to insert image", e);
if (url != null) {
cr.delete(url, null, null);
url = null;
}
}
if (url != null) {
stringUrl = url.toString();
}
return stringUrl;
}
|
上面方法里面有一个title,我刚以为是可以设置图片的名字,设置一下,原来不是,郁闷,哪位高手知道title这个字段是干嘛的,告诉下小弟,不胜感激!
当然Android还提供了一个插入系统相册的方法,可以指定保存图片的名字,我把源码贴出来吧
代码如下 |
复制代码 |
/**
* Insert an image and create a thumbnail for it.
*
* @param cr The content resolver to use
* @param imagePath The path to the image to insert
* @param name The name of the image
* @param description The description of the image
* @return The URL to the newly created image
* @throws FileNotFoundException
*/
public static final String insertImage(ContentResolver cr, String imagePath,
String name, String description) throws FileNotFoundException {
// Check if file exists with a FileInputStream
FileInputStream stream = new FileInputStream(imagePath);
try {
Bitmap bm = BitmapFactory.decodeFile(imagePath);
String ret = insertImage(cr, bm, name, description);
bm.recycle();
return ret;
} finally {
try {
stream.close();
} catch (IOException e) {
}
}
}
|
啊啊,贴完源码我才发现,这个方法调用了第一个方法,这个name就是上面方法的title,晕死,这下更加郁闷了,反正我设置title无效果,求高手为小弟解答,先不管了,我们继续往下说
上面那段代码插入到系统相册之后还需要发条广播
代码如下 |
复制代码 |
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
|
上面那条广播是扫描整个sd卡的广播,如果你sd卡里面东西很多会扫描很久,在扫描当中我们是不能访问sd卡,所以这样子用户体现很不好,用过微信的朋友都知道,微信保存图片到系统相册并没有扫描整个SD卡,所以我们用到下面的方法
代码如下 |
复制代码 |
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(new File("/sdcard/image.jpg"));
intent.setData(uri);
mContext.sendBroadcast(intent);
|
或者用MediaScannerConnection
代码如下 |
复制代码 |
final MediaScannerConnection msc = new MediaScannerConnection(mContext, new MediaScannerConnectionClient() {
public void onMediaScannerConnected() {
msc.scanFile("/sdcard/image.jpg", "image/jpeg");
}
public void onScanCompleted(String path, Uri uri) {
Log.v(TAG, "scan completed");
msc.disconnect();
}
});
|
也行你会问我,怎么获取到我们刚刚插入的图片的路径?呵呵,这个自有方法获取,insertImage(ContentResolver cr, Bitmap source,String title, String description),这个方法给我们返回的就是插入图片的Uri,我们根据这个Uri就能获取到图片的绝对路径
代码如下 |
复制代码 |
private String getFilePathByContentResolver(Context context, Uri uri) {
if (null == uri) {
return null;
}
Cursor c = context.getContentResolver().query(uri, null, null, null, null);
String filePath = null;
if (null == c) {
throw new IllegalArgumentException(
"Query on " + uri + " returns null result.");
}
try {
if ((c.getCount() != 1) || !c.moveToFirst()) {
} else {
filePath = c.getString(
c.getColumnIndexOrThrow(MediaColumns.DATA));
}
} finally {
c.close();
}
return filePath;
}
|
根据上面的那个方法获取到的就是图片的绝对路径
做一个输入框时发现android中ditView的默认焦点了,这种问题如果是在输入框还好,但在搜索页面或浏览页面这样就会影响用户体验了,那要如何取消EditView的默认焦点呢,下面我们来看看。
在网上找了好久,有点 监听软键盘事件,有点 调用 clearFouse()方法,但是测试了都没有! xml中也找不到相应的属性可以关闭这个默认行为
解决之道:在EditText的父级控件中找一个,设置成
代码如下 |
复制代码 |
android:focusable="true"
android:focusableInTouchMode="true"
|
这样,就把EditText默认的行为截断了!
代码如下 |
复制代码 |
<LinearLayout
style="@style/FillWrapWidgetStyle"
android:orientation="vertical"
android:background="@color/black"
android:gravity="center_horizontal"
android:focusable="true"
android:focusableInTouchMode="true"
>
<ImageView
android:id="@+id/logo"
style="@style/WrapContentWidgetStyle"
android:background="@drawable/dream_dictionary_logo"
/>
<RelativeLayout
style="@style/FillWrapWidgetStyle"
android:background="@drawable/searchbar_bg"
android:gravity="center_vertical"
>
<EditText
android:id="@+id/searchEditText"
style="@style/WrapContentWidgetStyle"
android:background="@null"
android:hint="Search"
android:layout_marginLeft="40dp"
android:singleLine="true"
/>
</RelativeLayout>
</LinearLayout>
|
查阅了很多资料后,发现以下方法最简单:
在xml中,在EditText控件之前
加入
代码如下 |
复制代码 |
<LinearLayout
android:id="@+id/linearLayout_focus"
android:focusable="true"
android:focusableInTouchMode="true"
android:layout_width="0px"
android:layout_height="0px"/>
|
这是一个虚假的LinearLayout,不会显示的,但是会抢走焦点
本文章来给各位同学介绍一个微信开发实现一键拨号出现屏蔽问题的解决方案,如果你碰到此问题不防进入参考一下。
在微信中出现无法拨号的情况,原先操作的时候,的确是OK的,现在微信版本升级了,我试了一下,果然拨号不行了,在首页的web页面中是没有问题的,但是在微信中就是拨打不了,找了很多,后来发现是微信做了屏蔽,解决方法如下:
1、拨号的代码还是不变,和原先的一样,
2、打开拨号页面要做下处理,在网址后面增加一个锚节点mp.weixin.qq.com。
实例如下:
如:<a href="tel:13764567708">移动WEB页面JS一键拨打号码咨询功能</a> 上需要拨号代码,操作如下
在有这个代码的页面URl后边加上“#mp.weixin.qq.com” 如:http://www.111cn.net /#mp.weixin.qq.com
这样,微信里面的一键拨号功能就OK了
本文章来给大家介绍关于Android开发之WebView的使用进阶,希望有兴趣的同学可进入参考,并对你有所帮助哦。
1、当打开WebView所显示网页上的超链接时,会调用系统的浏览器打开,而不是在原先的WebView上显示。
2、当我按下返回键时,并不是返回的上次打开的网页,而是直接退出程序。下面说明如果解决上面的两个问题
在原WebView上显示打开的链接需要自定义一个类,继承自WebViewClient,并设置WebView的WebViewClient即可:
代码如下 |
复制代码 |
class MyWebViewClient extends WebViewClient
{
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
//重写此方法表明点击链接是在当前的webview里跳转,不跳到浏览器那边
view.loadUrl(url);
return true;
}
}
webview = (WebView)this.findViewById(R.id.webView);
MyWebViewClient mwvc = new MyWebViewClient();
webview.setWebViewClient(mwvc);
webview.loadUrl("/index.php"); |
这样,当点击网页里的超链接时,就会在当前的WebView中显示,而不是打开浏览器去显示该网页。
响应返回键退回上一个网页第一个问题解决了之后,又引发一个新的问题,那就是当点击了好几层链接后,按下返回按钮并不是按预想的那样回退到上一个网页,而是直接退出了程序。
解决这个问题就需要重写onKeyDown方法,当按下返回键时,判断当前打开的网页是不是顶级页面,如果是,则退出Activity,如果不是,则退回上一个页面:
代码如下 |
复制代码 |
String topPage = "/index.php";
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK))
{
String currentUrl = webview.getUrl();
if(currentUrl.equals(topPage))
{
this.finish();
}
else
{
webview.goBack();
}
return true;
}
return false;
}
|
本文章给各位同学介绍一个简单的Android 自定义弹出对话框界面实例,如果你对此有了解不防进入参考。
在安卓开发中,时常遇到要弹窗提醒的情况。而系统自带的弹出对话框由不是很美观,可以通过自己继承对话框类(Dialog),并设置自定义的布局文件,来达到美化弹出式对话框的目的。
首先是自定义一个对话框类,继承自Dialog,然后再构造函数中传入对话框显示内容、按钮响应函数等参数:
代码如下 |
复制代码 |
public UserDefinedDialog(Context context, String message,
View.OnClickListener onclicklistener,
View.OnClickListener cancelListener)
{
super(context,R.style.Theme_Dialog);
this.ctx = context;
this.msg = message;
if (onclicklistener != null)
{
this.okListener=onclicklistener;
}
if(cancelListener != null)
{
IsTwoButton=true;
this.cancelListener=cancelListener;
}
}
|
然后,在自定义对话框类的OnCreate函数中,设置对话框的布局,以及显示风格:
代码如下 |
复制代码 |
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.alertdialog);
tvtitle = (TextView) findViewById(R.id.dialogtitle);
tvcontent = (TextView) findViewById(R.id.dialogcontent);
btnleft = (Button) findViewById(R.id.btnleft);
btnright = (Button) findViewById(R.id.btnright);
btnleft.setOnClickListener(this);
btnright.setOnClickListener(this);
btncenter = (Button) findViewById(R.id.btncenter);
btncenter.setOnClickListener(this);
if(IsTwoButton)
{
btnleft.setVisibility(View.VISIBLE);
btnright.setVisibility(View.VISIBLE);
btncenter.setVisibility(View.GONE);
}
tvtitle.setText("提示");
tvcontent.setText(msg);
WindowManager m;
m = (WindowManager)ctx.getSystemService(Context.WINDOW_SERVICE);
Display d = m.getDefaultDisplay();
LayoutParams p = getWindow().getAttributes();
//设置对话框宽高
p.height = (int) (d.getHeight() * 0.3);
p.width = (int) (d.getWidth() * 0.9);
//设置对话框透明度
p.alpha = 0.8f;
//让背景变黑
p.dimAmount = 0.7f;
getWindow().setAttributes(p);
getWindow().setGravity(Gravity.CENTER);
}
|
另外,自定义的对话框类UserDefinedDialog同时实现了OnClickListener接口,用于实现对点击对话框上按钮的响应,在响应函数中,会判断在构造该类的时候是否传入了相应的响应函数,并交由该函数处理:
代码如下 |
复制代码 |
public void onClick(View v)
{
switch (v.getId())
{
case R.id.btnleft:
if(cancelListener != null){
cancelListener.onClick(v);
}
break;
case R.id.btncenter:
if(okListener != null){
okListener.onClick(v);
}
break;
case R.id.btnright:
if(okListener != null){
okListener.onClick(v);
}
break;
}
this.cancel();
}
|
最后,调用的时候非常简单:
代码如下 |
复制代码 |
new UserDefinedDialog(this,
"我是一个按钮的对话框,默认效果取消",
null, null).show();
new UserDefinedDialog(this, "我是两个按钮的对话框",
new OnClickListener() {
public void onClick(View v) {
//dosomething
}
},
new OnClickListener() {
public void onClick(View v) {
//dosomething}
}).show();
|
美化之后的对话框如下图所示:
自定义对话框-单个按钮
标签:[!--infotagslink--]