网上有人给出了方案:
1)进入刚安装的Android Studio目录下的bin目录。找到idea.properties文件,用文本编辑器打开。
2)在idea.properties文件末尾添加一行: disable.android.first.run=true ,然后保存文件。
3)关闭Android Studio后重新启动,便可进入界面。
分类目录归档:Android
Android service 自动重启
当Android的service被停止(内存不够、被其他app杀掉)的时候,加入以下代码到你的service里,就可以马上重新启动了。
@Override
public void onDestroy() {
super.onDestroy();
// Restart service in 500 ms
((AlarmManager) getSystemService(Context.ALARM_SERVICE))
.set(AlarmManager.RTC,
System.currentTimeMillis() + 500,
PendingIntent.getService(this, 3, new Intent(this, TaskService.class), 0));
}
Android:通过Url打开App
Android支持通过Url打开App,比如下面的Url
scheme://host/datastring
要打开这样的Url,首先在配置文件AndroidManifest.xml里使用<data>添加一种App打开的格式,代码如下
<?xml version=”1.0″ encoding=”utf-8″?>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android”
package=”com.sheng00.customuridemo”
android:versionCode=”1″
android:versionName=”1.0″ >
<uses-sdk
android:minSdkVersion=”9″
android:targetSdkVersion=”17″ />
<application
android:allowBackup=”true”
android:icon=”@drawable/ic_launcher”
android:label=”@string/app_name”
android:theme=”@style/AppTheme” >
<activity
android:name=”com.sheng00.customuridemo.MainActivity”
android:label=”@string/app_name” >
<intent-filter>
<action android:name=”android.intent.action.MAIN” />
<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
<!– Open links like scheme://host/?… –>
<intent-filter>
<action android:name=”android.intent.action.VIEW” />
<category android:name=”android.intent.category.DEFAULT” />
<category android:name=”android.intent.category.BROWSABLE” />
<data android:scheme=”scheme” android:host=”host” />
</intent-filter>
</activity>
</application>
</manifest>
注意,第二个<intent-filter>中的data绑定了url 在页面中出现scheme://host/类似这样的链接,点击就可以直接打开app app中处理链接地址代码如下
package com.sheng00.customuridemo;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onResume() {
super.onResume();
Intent intent = getIntent();
if (intent != null) {
String action = intent.getAction();
String dataString = intent.getDataString();
if(dataString!=null){
TextView tv = (TextView) findViewById(R.id.tv);
tv.append("n" + dataString);
}
}
}
@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;
}
}
源代码:https://github.com/shengoo/myandroidcode/tree/master/CustomUriDemo
android客户端测试
Customized SeekBarPreference
Android没有提供SeekBarPreference,所以只有自己写一个了。。
SeekBarPreference.java
package com.sheng00.BatteryStatus; import com.sheng00.BattaryStatus.R; import android.content.Context; import android.content.res.TypedArray; import android.preference.Preference; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; import android.widget.RelativeLayout; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; public class SeekBarPreference extends Preference implements OnSeekBarChangeListener { private final String TAG = getClass().getName(); private static final String ANDROIDNS="http://schemas.android.com/apk/res/android"; private static final String SHENG00NS="http://sheng00.com"; private static final int DEFAULT_VALUE = 50; private int mMaxValue = 100; private int mMinValue = 0; private int mInterval = 1; private int mCurrentValue; private String mUnitsLeft = ""; private String mUnitsRight = ""; private SeekBar mSeekBar; private TextView mStatusText; public SeekBarPreference(Context context, AttributeSet attrs) { super(context, attrs); initPreference(context, attrs); } public SeekBarPreference(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initPreference(context, attrs); } private void initPreference(Context context, AttributeSet attrs) { setValuesFromXml(attrs); mSeekBar = new SeekBar(context, attrs); mSeekBar.setOnSeekBarChangeListener(this); mSeekBar.setMax(mMaxValue - mMinValue); } private void setValuesFromXml(AttributeSet attrs) { mMaxValue = attrs.getAttributeIntValue(ANDROIDNS, "max", 100); mMinValue = attrs.getAttributeIntValue(SHENG00NS, "min", 0); mUnitsLeft = getAttributeStringValue(attrs, SHENG00NS, "unitsLeft", ""); String units = getAttributeStringValue(attrs, SHENG00NS, "units", ""); mUnitsRight = getAttributeStringValue(attrs, SHENG00NS, "unitsRight", units); try { String newInterval = attrs.getAttributeValue(SHENG00NS, "interval"); if(newInterval != null) mInterval = Integer.parseInt(newInterval); } catch(Exception e) { Log.e(TAG, "Invalid interval value", e); } } private String getAttributeStringValue(AttributeSet attrs, String namespace, String name, String defaultValue) { String value = attrs.getAttributeValue(namespace, name); if(value == null) value = defaultValue; return value; } @Override protected View onCreateView(ViewGroup parent){ RelativeLayout layout = null; try { LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); layout = (RelativeLayout)mInflater.inflate(R.layout.seek_bar_preference, parent, false); } catch(Exception e) { Log.e(TAG, "Error creating seek bar preference", e); } return layout; } @Override public void onBindView(View view) { super.onBindView(view); try { // move our seekbar to the new view we've been given ViewParent oldContainer = mSeekBar.getParent(); ViewGroup newContainer = (ViewGroup) view.findViewById(R.id.seekBarPrefBarContainer); if (oldContainer != newContainer) { // remove the seekbar from the old view if (oldContainer != null) { ((ViewGroup) oldContainer).removeView(mSeekBar); } // remove the existing seekbar (there may not be one) and add ours newContainer.removeAllViews(); newContainer.addView(mSeekBar, ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); } } catch(Exception ex) { Log.e(TAG, "Error binding view: " + ex.toString()); } updateView(view); } /** * Update a SeekBarPreference view with our current state * @param view */ protected void updateView(View view) { try { RelativeLayout layout = (RelativeLayout)view; mStatusText = (TextView)layout.findViewById(R.id.seekBarPrefValue); mStatusText.setText(String.valueOf(mCurrentValue)); mStatusText.setMinimumWidth(30); mSeekBar.setProgress(mCurrentValue - mMinValue); mSeekBar.setEnabled(this.isEnabled()); TextView unitsRight = (TextView)layout.findViewById(R.id.seekBarPrefUnitsRight); unitsRight.setText(mUnitsRight); TextView unitsLeft = (TextView)layout.findViewById(R.id.seekBarPrefUnitsLeft); unitsLeft.setText(mUnitsLeft); } catch(Exception e) { Log.e(TAG, "Error updating seek bar preference", e); } } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { int newValue = progress + mMinValue; if(newValue > mMaxValue) newValue = mMaxValue; else if(newValue < mMinValue) newValue = mMinValue; else if(mInterval != 1 && newValue % mInterval != 0) newValue = Math.round(((float)newValue)/mInterval)*mInterval; // change rejected, revert to the previous value if(!callChangeListener(newValue)){ seekBar.setProgress(mCurrentValue - mMinValue); return; } // change accepted, store it mCurrentValue = newValue; if (mStatusText != null) { mStatusText.setText(String.valueOf(newValue)); } persistInt(newValue); } public void onStartTrackingTouch(SeekBar seekBar) {} public void onStopTrackingTouch(SeekBar seekBar) { notifyChanged(); } @Override protected Object onGetDefaultValue(TypedArray ta, int index){ int defaultValue = ta.getInt(index, DEFAULT_VALUE); return defaultValue; } @Override protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { if(restoreValue) { mCurrentValue = getPersistedInt(mCurrentValue); } else { int temp = 0; try { temp = (Integer)defaultValue; } catch(Exception ex) { Log.e(TAG, "Invalid default value: " + defaultValue.toString()); } persistInt(temp); mCurrentValue = temp; } } }
这时需要在layout里写布局文件
seek_bar_preference.xml
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/widget_frame"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:paddingTop="5dp"
android:paddingRight="10dp"
android:paddingBottom="5dp"
>
<TextView android:id="@android:id/title"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="22dp"
android:typeface="sans"
android:textStyle="normal"
android:textColor="#ffffff"
></TextView>
<TextView android:id="@android:id/summary"
android:layout_alignParentLeft="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@android:id/title"
></TextView>
<TextView android:id="@+id/seekBarPrefUnitsRight"
android:layout_alignParentRight="true"
android:layout_below="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
></TextView>
<TextView android:id="@+id/seekBarPrefValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/seekBarPrefUnitsRight"
android:layout_below="@android:id/title"
android:gravity="right"
></TextView>
<TextView android:id="@+id/seekBarPrefUnitsLeft"
android:layout_below="@android:id/title"
android:layout_toLeftOf="@id/seekBarPrefValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
></TextView>
<LinearLayout android:id="@+id/seekBarPrefBarContainer"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@android:id/summary">
</LinearLayout>
</RelativeLayout>
然后可以写进我们的activity的布局文件里了:
<com.sheng00.batterystatus.seekbarpreference
sheng00:unitsright="%"
sheng00:unitsleft=""
android:dependency="@string/low_alert_checkbox"
android:summary=" "
android:title="@string/low_alert_level"
sheng00:min="1"
android:max="50"
android:key="@string/low_alert_level_key"
android:defaultvalue="15" />
android.intent.action.MAIN与android.intent.category的作用
在android和ophone的应用程序可以有多个Activity,每个Activity是同级别的,那么在启动程序时,最先启动哪个Activity呢?
有些程序可能需要显示在程序列表里,有些不需要。怎么定义呢?
android.intent.action.MAIN决定应用程序最先启动的Activity 。
android.intent.category.LAUNCHER决定应用程序是否显示在程序列表里。
因为你的程序可能有很多个activity,
只要xml配置文件中有这么一个intent-filter,而且里面有这个launcher,那么这个activity就是点击程序时最先运行的那个activity。
如果只有一个Activity,没有这两句也可以。
android 程序设置全屏显示
2中方法
在AndroidManifest.xml中
<activity android:name=””
…
android:theme=”@android:style/Theme.NoTitleBar.Fullscreen”/>
程序里
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
…
android sdk下载地址
ADT 10.0.0下载地址
http://dl.google.com/android/ADT-10.0.0.zip
下载下列文件时加前缀 :
https://dl-ssl.google.com/android/repository/
API 2
android-1.1_r1-windows.zip
android-1.1_r1-macosx.zip
android-1.1_r1-linux.zip
API 3
android-1.5_r03-windows.zip
android-1.5_r03-linux_x86.zip
android-1.5_r03-mac_x86.zip
google_apis-3-r03.zip
API 4
android-1.6_r02-windows.zip
android-1.6_r02-linux.zip
android-1.6_r02-macosx.zip
google_apis-4_r02.zip
API 5
android-2.0_r01-windows.zip
android-2.0_r01-linux.zip
android-2.0_r01-macosx.zip
google_apis-5_r01.zip
API 6
android-2.0.1_r01-linux.zip
android-2.0.1_r01-macosx.zip
android-2.0.1_r01-windows.zip
google_apis-6_r01.zip
API 7
android-2.1_r01-windows.zip
samples-2.1_r01-linux.zip
android-2.1_r01-macosx.zip
google_apis-7_r01.zip
API 8
android-2.2_r02-windows.zip
android-2.2_r02-macosx.zip
tools
tools_r05-windows.zip
tools_r05-linux.zip
tools_r05-macosx.zip
usb_d
usb_driver_r03-windows.zip
android使用ZipInputStream解压缩zip压缩文件
public class unzip extends Activity {
/** Called when the activity is first created. */
static final int BUFFER = 2048;
TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
textView = new TextView(this);
super.onCreate(savedInstanceState);
textView.setText(“Main Activity”);
extractZipfile();
setContentView(textView);
}
private void extractZipfile() {
String extractDir = getApplicationContext().getFilesDir()
.getAbsolutePath()
+ “/unzip/”;
try {
BufferedOutputStream dest = null;
ZipInputStream zis = new ZipInputStream(getResources()
.openRawResource(R.raw.book));
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
File file = new File(extractDir + entry.getName());
if (file.exists()) {
textView.append(“n” + file.getAbsolutePath() + “texists”);
continue;
}
if (entry.isDirectory()) {
if (!file.exists())
file.mkdirs();
textView.append(“nCreate directory: “
+ file.getAbsolutePath());
continue;
}
textView.append(“nExtracting:” + entry);
int count;
byte data[] = new byte[BUFFER];
textView.append(” to ” + file.getAbsolutePath());
FileOutputStream fos = new FileOutputStream(file);
dest = new BufferedOutputStream(fos, BUFFER);
while ((count = zis.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, count);
}
dest.flush();
dest.close();
}
zis.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
解决Android屏幕方向变化的问题
作为一个Android开发新手,当我们在开发的时候面对一个大问题
“处理屏幕方向变化“
这个问题的原因是什么?
那么它会导致许多问题如下。
1。只要我们改变方向,它就会创建一个新的Activity。
2。如果在播放音频文件,这将重新载入两次文件,这将同时播放两个同样的歌。
3。导致内存管理问题。
4。如果你有一个20字段的表单,你填写了15个字段,就会丢失15个字段里的内容。
那么如何解决这个问题。谷歌在manifest.xml一行代码解决问题
添加这行代码到Activity的属性来解决这个问题。
android:configChanges=”orientation”
这样也行
<activityandroid:label=”@string/app_name”android:configChanges=”orientation”
android:name=”.com.androidpeople”> |
现在你是完全从这个方向变化问题的自由。