Android点滴积累
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0717/3196.html
使用AndroidStudio一分鐘實現Navigation Drawer 導航抽屜效果?
https://blog.csdn.net/finddreams/article/details/49492579
定制自己的Log日志工具
https://blog.csdn.net/guolipeng_network/article/details/73111418
使用Intent傳遞自定義對象
https://blog.csdn.net/mq2856992713/article/details/51049617
1.實現Serializable接口的對象?
2.實現Parcelable接口的對象?
創建定時任務
1.Java Timer類
2.Android Alarm機制
Alarm可以在需要進行定時任務時喚醒CPUhttps://blog.csdn.net/u014492609/article/details/51475254
AndroidStudio斷點調試
?https://blog.csdn.net/qq_32452623/article/details/53769708
?https://blog.csdn.net/huangxiaominglipeng/article/details/53100811?
?APK簽名
http://192.168.3.77:8989/wcp/webdoc/view/Pub402880cd5dc4c831015dd0c28455015f.html
http://192.168.3.77:8989/wcp/webdoc/view/Pub402880cd5c5da6e7015d5f2cf2c30c12.html
O平臺簽名有問題,試了M平臺和N平臺的方法都不行。所以選擇了模塊編譯。18.內置的apk 如何實現簽名 獲取系統權限
查看簽名信息 keytool -printcert -file?
[FAQ00366] 如何使Android應用程序獲取系統權限
?? ?在已經編譯好的工程中 :out/host/linux-x86/framework/signapk.jar 取出 signapk.jar 文件 ,然后從 build/target/product/security/項目名字/ 下面取出另外兩個文件 platform.x509.pem 和 platform.pk8
然后三個文件+apk文件,同一個路徑下。 執行簽名操作
?? ?java -jar signapk.jar platform.x509.pem platform.pk8 input.apk output.apk
?? ?然后apk就相當于簽名,獲取了系統權限。。當然,名字實際上也重新命名了。L-->alps/device/mediatek/common/security/項目
檢查APK簽名是否為platform簽名:
jarsigner -verify -verbose -certs ${your_apk}>log.txt
./aapt dump badging ?Maps.apk ?> log2.txt
keytool -list -v -keystore IDG.JKS
簽名前需先刪除原始apk中的META-INF
jarsigner -verbose -keystore IDG.JKS -signedjar IDG_CodeTelMessenger.apk IDG_CodeTelMessenger.apk viewappkey
jarsigner -verbose -keystore CERT.RSA -signedjar momkntestapp-sign.apk -digestalg SHA1 -sigalg SHA1withRSA momkntestapp.apk momkn_calib 添加算法jdk1.7以后
keytool -printcert -file MOMKN_CA.RSA/home/rwd/workspace/momkntestapp/bin/momkntestapp-eclipse.apk
第一步生成keystore 用來簽名
keytool -genkey -v -keystore android.keystore -alias android.keystore -keyalg RSA -validity 3650?
第二步生成 .cer文件 放到代碼里面
keytool -export -alias android.keystore -file android.cer -keystore android.keystoregyn@gyn-ThinkStation-P300:~$ keytool -genkey -v -keystore piranha -alias piranha -keyalg RSA -keysize 2048 -validity 7300
Enter keystore password: ?
Re-enter new password:?
What is your first and last name?
? [Unknown]: ?boloro
What is the name of your organizational unit?
? [Unknown]: ?sagereal
What is the name of your organization?
? [Unknown]: ?sagereal
What is the name of your City or Locality?
? [Unknown]: ?ningbo
What is the name of your State or Province?
? [Unknown]: ?zhejiang
What is the two-letter country code for this unit?
? [Unknown]: ?cn
Is CN=boloro, OU=sagereal, O=sagereal, L=ningbo, ST=zhejiang, C=cn correct?
? [no]: ?yGenerating 2,048 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 7,300 days
?? ?for: CN=boloro, OU=sagereal, O=sagereal, L=ningbo, ST=zhejiang, C=cn
Enter key password for <android.keystore>
?? ?(RETURN if same as keystore password): ?
Re-enter new password:?
[Storing android.keystore]
gyn@gyn-ThinkStation-P300:~$ keytool -export -alias android.keystore -file android.cer -keystore android.keystore
Enter keystore password: ?
Certificate stored in filejarsigner -verbose -keystore com.bjw.ComAssistant_2.keystore -signedjar com.bjw.ComAssistant_2_signed.apk -digestalg SHA1 -sigalg MD5withRSA com.bjw.ComAssistant_2.apk android.keystore
jarsigner命令格式:-verbose輸出詳細信息 -keystore密鑰庫位置 -signedjar要生成的文件 要簽名的文件 密鑰庫文件
?-signedjar PhoneBook_signed.apk表示簽名后生成的APK名稱
PhoneBook.apk表示未簽名的APK?
Android軟件-digestalg SHA1 -sigalg MD5withRSA:這就是必須加上的參數,如果你是jdk 1.6也不受影響
-androiddebugkey表示Key的別名
AppUpdate添加到Settings一級目錄
參照Software #119639 (Closed): [傳音需求]手機內部User Guide!
修改preference?
1先通過DDMS查看是哪個Activity
2這個Activity繼承了PreferenceActivity,重寫了preference的一系列方法通過控件的id或字符串找到preference的布局文件(這里可能找到很多preference,看哪個preference和Activity相似或者preference的布局和手機是對應的)。
再查看哪個java文件調用了這xml文件,grep會發現: Xxx.java: ? ? ? ?addPreferencesFromResource(R.xml.preference_display_options);
在該Java文件的onCreate()方法中獲取Preference,findPreference by key,setTitle()
?final Preference aboutPreference = findPreference("about");
? ? ? ? //chenghao add begin
? ? ? ??
? ? ? ? String str_pre=aboutPreference.getTitle().toString();
? ? ? ? String str_convert = str_pre.substring(0, 1).toUpperCase().concat(str_pre.substring(1).toLowerCase());
? ? ? ? android.util.Log.e("chenghao666","str_pre="+str_pre);
? ? ? ? android.util.Log.e("chenghao666","str_convert="+str_convert);
? ? ? ? aboutPreference.setTitle(str_convert);
? ? ? ? //chenghao add end
確定具體preference的,找到具體某個preference的key。在Activity中會根據key找到preference,進行一系列操作。
添加全局變量宏開關的三種方式
https://blog.csdn.net/hfreeman2008/article/details/49885885
Redmine115852 wangyannan add autoreboot test function begin?
?
Android各種獲取Context方法
https://www.cnblogs.com/chenxibobo/p/6136693.htmlhttps://blog.csdn.net/lmj623565791/article/details/40481055/
張鴻洋https://blog.csdn.net/zy_style/article/details/53230303
基于張鴻洋,做了添加。XXXActivity.this和getApplicationContext的區別呢?
XXXActivity和getApplicationContext返回的肯定不是一個對象,一個是當前Activity的實例,一個是項目的Application的實例。重點看Activity和Application,凡是跟UI相關的,都應該使用Activity做為Context來處理;其他的一些操作,Service,Activity,Application等實例都可以。
也即:
在絕大多數場景下,Activity、Service和Application這三種類型的Context都是可以通用的。
不過有幾種場景比較特殊,比如start an Activity,show a Dialog,Layout Inflation。應該使用Activity做為Context來處理!如何獲取Context:
1:View.getContext,返回當前View對象的Context對象,通常是當前正在展示的Activity對象。2:Activity.getApplicationContext,獲取當前Activity所在的(應用)進程的Context對象,通常我們使用Context對象時,要優先考慮這個全局的進程Context。
3:ContextWrapper.getBaseContext():用來獲取一個ContextWrapper進行裝飾之前的Context,可以使用這個方法,這個方法在實際開發中使用并不多,也不建議使用。
4:Activity.this 返回當前的Activity實例,如果是UI控件需要使用Activity作為Context對象,但是默認的Toast實際上使用ApplicationContext也可以。
?1. getApplicationContext()?
?這個函數返回的這個Application的上下文,所以是與app掛鉤的,所以在整個生命周期里面都是不變的,這個好理解,但是使用的時候要注意,該context是和引用的生命周期一致的,所以和activity生命周期掛鉤的任務不要使用該context,比如網絡訪問,防止內存泄露
?
?2. getBasecontext():
?不推薦使用
?
?3. getApplication():
?getApplication只能被Activity和Services使用,
?
?4. getParent() :
?返回activity的上下文,如果這個子視圖的話,換句話說,就是當在子視圖里面調用的話就返回一個帶有子視圖的activity對象,一目了然。
?
?5.getActivity():
?在fragment中使用,返回該fragment所依附的activity上下文
?
?6.this
ComponentName
https://blog.csdn.net/huangyabin001/article/details/36626341ComponentName這個類主要用來定義可見一個應用程序組件,例如:Activity,Service,BroadcastReceiver或者ContentProvider。
? ? 那么,如何用ComponentName來定義一個組件呢。
? ? ComponentName的構造函數:ComponentName(String pkg,String cls)
? ? omponentName來封裝一個組件的應用包名和組件的名字。
在Android中組件之間的交流往往使用意圖(Intent)來完成的,那么在Intent中有一個方法可以封裝一個ComponentName,最后我們在使用意圖去完成我們需要實現的功能。
例子:
? ? ComponentName cn=new ComponentName("com.example.appreceiver", "com.example.appreceiver.MainActivity"); ?
? ? Intent intent = new Intent(); ?
? ? intent.setComponent(cn);
? ? startActivityForResult(intent, 2); ?
??
問題一: ?
Android service如何獲取調用者的真實package name?
我有一個service,別的App可以調用它。
我的service想獲取調用者的packageName,該如何做呢?
實踐表明:必須調用者事先寫進Intent, 才能才能通過intent.getComponent().getPackageName()獲取到包名。
但是如何才能不用調用者事先寫入,直接獲取(即,如何防止用戶偽造packageName)?
回答:
String callingApp = context.getPackageManager().getNameForUid(Binder.getCallingUid());
或者 AppGlobals.getPackageManager().getNameForUid(Binder.getCallingUid());獲取調用者的類名:
intent.getComponent().getClassName();問題二:
Launcher加載所有的已安裝的程序的列表,當點擊圖標時可以啟動另一個應用。
https://blog.csdn.net/u012532559/article/details/52766348
我們一般都不知道應用程序的啟動Activity的類名,而只知道包名,我們可以通過ResolveInfo類來取得啟動Acitivty的類名。
? ? private void openApp(String packageName) { ?
? ? PackageInfo pi = getPackageManager().getPackageInfo(packageName, 0); ?
? ? Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); ?
? ? resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER); ?
? ? resolveIntent.setPackage(pi.packageName); ?
? ? List<ResolveInfo> apps = pm.queryIntentActivities(resolveIntent, 0); ?
? ? ResolveInfo ri = apps.iterator().next(); ?
? ? if (ri != null ) { ?
? ? String packageName = ri.activityInfo.packageName; ?
? ? String className = ri.activityInfo.name; ?
? ? Intent intent = new Intent(Intent.ACTION_MAIN); ?
? ? intent.addCategory(Intent.CATEGORY_LAUNCHER); ?
? ? ComponentName cn = new ComponentName(packageName, className); ?
? ? intent.setComponent(cn); ?
? ? startActivity(intent); ?
? ? } ?
} ?
單例模式
與Context相關 Context的保持
單例模式:是一種常用的軟件設計模式,在它的核心結構中值包含一個被稱為單例的特殊類。一個類只有一個實例,即一個類只有一個對象實例。
對于系統中的某些類來說,只有一個實例很重要,例如,一個系統中可以存在多個打印任務,但是只能有一個正在工作的任務;售票時,一共有100張票,可有有多個窗口同時售票,但需要保證不要超售(這里的票數余量就是單例,售票涉及到多線程)。如果不是用機制對窗口對象進行唯一化將彈出多個窗口,如果這些窗口顯示的都是相同的內容,重復創建就會浪費資源。內存泄露:
? Java中的內存泄露,廣義并通俗的說,就是:不再會被使用的對象的內存不能被回收,就是內存泄露。
? 如果長生命周期的對象持有短生命周期的引用,就很可能會出現內存泄露。
??
編寫工具類時,可能會編寫成單例的方式,這些工具類大多需要去訪問資源,也就說需要Context的參與。
單例中內部保持了一個Context的引用,不能確定傳入的Context是哪種。可能會造成內存泄露。你在某個Activity里面為了方便,直接傳了個this;這樣問題就來了,我們的這個類中的sInstance是一個static且強引用的,在其內部引用了一個Activity作為Context,也就是說,我們的這個Activity只要我們的項目活著,就沒有辦法進行內存回收。而我們的Activity的生命周期肯定沒這么長,所以造成了內存泄漏。
那么,我們如何才能避免這樣的問題呢?
將context引用改為ApplicationContext,它的生命周期和我們的單例對象一致。就不會造成內存泄露了。
單例模式例子:
? ? package com.mooc.shader.roundimageview; ?
? ? import android.content.Context; ?
? ? public class CustomManager ?
? ? { ?
? ? ? ? private static CustomManager sInstance; ?
? ? ? ? private Context mContext; ?
? ? ??
? ? ? ? private CustomManager(Context context) ?
? ? ? ? { ?
? ? ? ? ? ? this.mContext = context; ?
? ? ? ? } ?
? ? ??
? ? ? ? public static synchronized CustomManager getInstance(Context context) ?
? ? ? ? { ?
? ? ? ? ? ? if (sInstance == null) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? sInstance = new CustomManager(context);//context不確定是哪種,可能是Activity。需要修改成context.getApplicationContext()
? ? ? ? ? ? } ?
? ? ? ? ? ? return sInstance; ?
? ? ? ? } ?
? ? ? ? ??
? ? ? ? //some methods ??
? ? ? ? private void someOtherMethodNeedContext() ?
? ? ? ? { ?
? ? ? ? ? ? ??
? ? ? ? } ?
? ? } ??
2018-04-14-(使用Github及Git常見命令)
第一次使用github
執行git clone命令:chenghao@chenghao-ThinkStation-P300:~/Project/github-android/Test$ git clone git@github.com:Cheng8Hao/hello_world.git
正克隆到 'hello_world'...
The authenticity of host 'github.com (192.30.253.112)' can't be established.
RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,192.30.253.112' (RSA) to the list of known hosts.
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 7 (delta 0), reused 0 (delta 0), pack-reused 0
接收對象中: 100% (7/7), done.
檢查連接... 完成。
chenghao@chenghao-ThinkStation-P300:~/Project/github-android/Test$問題:add前取消對某文件的修改
git checkout問題一: git add 添加了多余文件怎么撤銷添加的操作??
git status 先看一下add 中的文件?
git reset HEAD 如果后面什么都不跟的話 就是上一次add 里面的全部撤銷了?
git reset HEAD XXX/XXX/XXX.java 就是對某個文件進行撤銷了
reset只是撤銷了添加,文件還是已修改狀態,再用checker命令。問題二:
如果不小心弄錯了git add后,又git commit了,但是還沒有push,怎么辦?
git log 查看節點?
git reset commit_id (回退到上一個提交的commit_id節點 代碼還是原來你修改過后的)?
或者git reset –hard commit_id (回退到上一個提交的commit_id節點, 代碼的修改也被清除了)問題三:
弄錯了git add后,又git commit了,又push了,怎么辦?
使用 git revert命令
此次操作之前和之后的commit和history都會保留,并且把這次撤銷作為一次最新的提交?
git revert HEAD 撤銷前一次 commit?
git revert HEAD^ 撤銷前前一次 commit?
git revert commit-id (撤銷指定的版本,撤銷也會作為一次提交進行保存)?
git revert是提交一個新的版本,將需要revert的版本的內容再反向修改回去,版本會遞增,不影響之前提交的內容。查看用戶名和郵箱地址:
$ git config user.name
$ git config user.emailgit add -A 和 git add . 的區別:
git add -A和 git add . ? git add -u在功能上看似很相近,但還是存在一點差別
git add . :他會監控工作區的狀態樹,使用它會把工作時的所有變化提交到暫存區,包括文件內容修改(modified)以及新文件(new),但不包括被刪除的文件。
git add -u :他僅監控已經被add的文件(即tracked file),他會將被修改的文件提交到暫存區。add -u 不會提交新文件(untracked file)。(git add --update的縮寫)
git add -A :是上面兩個功能的合集(git add --all的縮寫)https://github.com/I18N486/coolweather
git diff commit-id1 commit-id2 --stat
這個指令可以看兩個版本之間有哪些文件改動git log -p file
可以看到具體一個文件的歷史改動記錄git show?
@BindView(R2.id.button)
Button button =(B)fin@BindView(R2.id.button2)
Settings?
8.0Settings?
https://blog.csdn.net/qq_31012033/article/details/79522813
https://blog.csdn.net/joychanger/article/details/51336527>>>AndroidManifest.xml
? ? >>>activity-alias詳解
? ? ? ? https://blog.csdn.net/ahence/article/details/51648768
? ? ? ? 即activity的別名,它有一個屬性叫android:targetActivity,這個屬性就是用來為該標簽設置目標Activity的,或者說它就是這個目標Activity的別名。
? ? ? ? 可用來設置某個Activity的快捷入口,可以放在桌面上或者通過該別名被其他組件快速調起。>>>Settings.java
? ? //Redmine 114884 zhangdi modified for settings ui 2018 01 17 begin
? ? public static class GestureDashboardActivity extends SettingsActivity {}
? ? //Redmine 114884 zhangdi modified for settings ui 2018 01 17 end
? ??
? ? //Redmine #122701 liuxiangnan added for user guide 2018.02.09,begin
? ? public static class UserGuideActivity extends SettingsActivity { /* empty */ }
? ? //Redmine #122701 liuxiangnan added for user guide 2018.02.09,end
? ??
>>>SettingsActivity.java
? ? >>>onCreate()
? ? ? ? >>>setContentView(mIsShowingDashboard ? R.layout.settings_main_dashboard : R.layout.settings_main_prefs);
? ? ? ? //mIsShowingDashboard,當前類是否為Settings.class,即進入方式為點擊launcher上的圖標進入的主設置界面?
? ? ? ? >>>launchSettingFragment(initialFragmentName, isSubSettings, intent);
? ? ? ? //加載布局?
? ? ? ??
? ? >>>launchSettingFragment()?
? ? ? ? if (!mIsShowingDashboard && initialFragmentName != null) {...}
? ? ? ? else{ ? ? ??
? ? ? ? ? ? // Show search icon as up affordance if we are displaying the main Dashboard,如果我們正在顯示主儀表板,請顯示搜索圖標
? ? ? ? ? ? mDisplayHomeAsUpEnabled = true;
? ? ? ? ? ? mInitialTitleResId = R.string.dashboard_title;
? ? ? ? ? ? switchToFragment(DashboardSummary.class.getName(), null /* args */, false, false, mInitialTitleResId, mInitialTitle, false);
? ? ? ? ? ? }
? ? ? ? ? ??
? ? ?>>>switchToFragment()
? ? ?
>>>DashboardSummary.java
? ? //對于它我們主要是想知道它的數據加載,它是怎么加載自己的子項的。
? ? 對子項的數據獲取在updateCategoryAndSuggestion()中得到實現。>>>對于第一級菜單的加載。在AndroidManifest.xml中的配置如下列圖:
? ? 例子:
? ? <activity android:name=".Settings$NetworkDashboardActivity"
? ? ? ? android:taskAffinity="com.android.settings"
? ? ? ? android:label="@string/network_dashboard_title"
? ? ? ? android:icon="@drawable/ic_settings_wireless"
? ? ? ? android:parentActivityName="Settings">
? ? ? ? <intent-filter android:priority="1">
? ? ? ? ? ? <action android:name="android.settings.WIRELESS_SETTINGS" />
? ? ? ? ? ? <action android:name="android.settings.AIRPLANE_MODE_SETTINGS" />
? ? ? ? ? ? <category android:name="android.intent.category.DEFAULT" />
? ? ? ? </intent-filter>
? ? ? ??
? ? ? ? <intent-filter>
? ? ? ? ? ? <action android:name="android.intent.action.MAIN" />
? ? ? ? ? ? <category android:name="android.intent.category.DEFAULT" />
? ? ? ? ? ? <category android:name="android.intent.category.VOICE_LAUNCH" />
? ? ? ? </intent-filter>
? ? ? ??
? ? ? ? <intent-filter android:priority="11">
? ? ? ? ? ? <action android:name="com.android.settings.action.SETTINGS"/>
? ? ? ? </intent-filter>
? ? ? ??
? ? ? ? //類別,這里com.android.settings.category.ia.homepage代表一級頁面
? ? ? ? <meta-data android:name="com.android.settings.category" android:value="com.android.settings.category.ia.homepage"/>
? ? ? ? ??
? ? ? ? //跳轉到的fragment ?
? ? ? ? <meta-data android:name="com.android.settings.FRAGMENT_CLASS" android:value="com.android.settings.network.NetworkDashboardFragment"/>
? ? ? ? ? ??
? ? ? ? <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED" android:value="true" />
? ? ? ? </activity>
? ? ? ??
>>>第二級菜單的加載
? ? 第一級菜單是完全動態的加載,但二級菜單則是動態加載和靜態xml布局文件.
? ??
? ? 例子:第一級菜單System下的二級菜單。
? ? ? ? 跳轉的Fragment是 SystemDashboardFragment.java,該類繼承DashboardFragment.java。
? ??
? ? >>>父類 DashboardFragment.java
? ? ? ? 1.靜態加載部分:
? ? ? ? 靜態加載部分的實現方法為:
? ? ? ? >>>displayResourceTiles()
? ? ? ? ? ? >>>getPreferenceScreen()
? ? ? ? ? ? /** 實現布局文件中的子項控件的業務邏輯?
? ? ? ? ? ? * ?DashboardFragment.java的子類SystemDashboardFragment.java實現getPreferenceControllers()方法,該方法加載繼承于AbstractPreferenceController.java的實現業務邏輯類?
? ? ? ? ? ? */ ?
? ? ? ? ? ??
? ? ? ? 2.動態加載部分:
? ? ? ? >>>refreshDashboardTiles()
? ? ? ??
? ? ? ??
注:
添加一級菜單:119639(UserGuider A15);112154(來電閃爍功能 A15)
添加二級菜單:129308(AppUpdate F1)
將一級菜單調整到二級菜單:129309(調整UserGuider位置)
? ??
? ??
? ? Android8.0 Settings provider 數據庫 新方法
https://blog.csdn.net/Aaron121314/article/details/78332628? ? Settings.db在android6.0上的變化
https://blog.csdn.net/kv110/article/details/51520207
? ??
在framework中添加新類或者新api UpdateAPI
http://192.168.3.77:8989/wcp/webdoc/view/Pub402880cd5dc4c831015de48cbff601f8.html
https://www.cnblogs.com/zhengtu2015/p/5134287.html
編譯android framework層的資源文件
https://blog.csdn.net/thinkinwm/article/details/17916873
Redmine127424 liujingjing add mediabutton in fm 20180423 beginif("com.android.fmradio".equals(appInfo.packageName)){?
? ? notiBuilder.setSmallIcon(com.android.internal.R.drawable.fm_title_icon);}
暗碼處理的地方:
https://blog.csdn.net/u013398960/article/details/72899353
alps/vendor/mediatek/proprietary/packages/apps/Dialer/java/com/android/dialer/app/dialpad/DialpadFragment.java?
Dynamic Shortcuts
長按應用彈出快捷菜單.
App Shortcuts是指在桌面長按app圖標而出現的快捷方式, 可以為你的app的關鍵功能添加更快速的入口而不用先打開app,點擊快捷方式可以訪問應用功能, 并且這種快捷方式也可以被拖拽到桌面單獨放置, 變成單獨的桌面快捷方式.*****https://www.jianshu.com/p/8cfd506caa07 -->構建回退棧的例子(靜態和動態配置都可以)
*****https://www.jianshu.com/p/fddc8d5f8d64 --->最佳實踐!
https://blog.csdn.net/qibin0506/article/details/52878690
1 ?? ?Static Shortcuts
//配置多個intent,點擊打開最后一個intent的頁面,前面的intent用來構建回退棧
runOnUiThread
https://www.aliyun.com/jiaocheng/4598.html
重新回過頭來看 runOnUiThread()的源碼:final Handler mHandler = new Handler();
private Thread mUiThread;
// ...
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
// ...
}首先在主線程里通過無參的構造方法創建一個Handler,這個Handler是指向主線程的。
當執行runOnUiThread()時,當前線程不是主線程,調用mHandler.post(action),將Runnable添加到主線程的消息隊列中
這樣,Runnable的語句就是在主線程執行的了。注意:
用這種方式創建ProgressDialog就比較方便,或者刷新adapter也比使用Thread+Handler方便。
如果不是在activity中創建,需要在前面加上((Activity)mContext).?
https://blog.csdn.net/liuweiballack/article/details/49800829
android:configuration 處理屏幕旋轉和語言切換等問題
https://blog.csdn.net/lyhhj/article/details/48789705
Android Studio導入github項目詳解
問題1:
我們要改3個文件
1?? ?根目錄下的build.gradle文件中的build:gradle版本
2?? ?gradle文件夾下的gradle-wrapper.properties文件中的distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
3?? ?app目錄下build.gradle的依賴庫
? ? ?? ?testCompile 'junit:junit:4.12'
? ? ?? ?compile 'com.android.support:appcompat-v7:26.+'問題2:
https://blog.csdn.net/CHENYUFENG1991/article/details/74136439?locationNum=10&fps=1
Unregistered VCS root detected. The directory…is under Git, but is not registered in the Settings
問題:
修改AS中的代碼,git status后會有一些無關代碼的文件發生變化.
這種情況,你是在設計gitignore 之前就沒考慮好的!現在的措施是:
你要先去刪除遠程的 .idea 目錄。rm -rf .idea (這樣會刪掉你本地的,不過你重新打開一次項目就有會自動給你生成了)
git add -A .
提交
git pullpull 后再看看同步后,遠程的刪掉沒有;如果本地有,再次重復下。
干凈后,這下 git rm -r --cached .idea 取消跟蹤
再push 吧
camera快速編譯
touch vendor/mediatek/proprietary/hardware/mtkcam/legacy/v1/common/paramsmgr/feature/custom/custom.cpp &&?
?./mk VP501_H5019_Rokit mm vendor/mediatek/proprietary/hardware/mtkcam/legacy/v1/common/paramsmgr/ &&
?./mk ?VP501_H5019_Rokit ?mm vendor/mediatek/proprietary/hardware/mtkcam/legacy/platform/mt6580/v1/common/paramsmgr/adb push
adb push out/target/product/k80hd_bsp_fwv_512m/vendor/lib/libcam.paramsmgr.so vendor/lib/libcam.paramsmgr.so
[FAQ17665] 快速修改調試Feature Table
[FAQ14389] Feature Table加載原理和調試方法修改camera FOV此項使用快速編譯 無效!?
Content provider 中getPathSegments用途
--getPathSegments得到uri的path部分,并拆分,去掉"/",取到第一個元素(從第0個開始)。 ? ? ? ? ? ? ? ? ?
?比如:content://"+FirstProvierMetaData.AUTHORIY+"/users /1" ? ? ? ? ? ? ? ? ? ? ??
?//getPathSegments()得到的是users 和 1,get(1)會得到1 ? ? ? ? ? ? ? ? ? ??qb.appendWhere(UserTableMetaData._ID+"="+uri.getPathSegments().get(1)); ? ? ? ? ? ? ? ??
Demo:
? ? ? ? Uri uri = Uri.parse("content://com.haha.mycontentproviderdemo.NoteContentProvider/notes");
? ? ? ? Uri myUri = Uri.withAppendedPath(uri, "#/2");
? ? ? ? List<String> list = myUri.getPathSegments();
? ? ? ? int i = 0;
? ? ? ? for (Iterator iterator = list.iterator(); iterator.hasNext(); i++) {
? ? ? ? ? ? String string = (String) iterator.next();
? ? ? ? ? ? Log.i("test", "集合里的元素為:" + string);
? ? ? ? ? ? Log.i("test", "集合中下標為 " + i +"的String類型元素為:"+ list.get(i));
? ? ? ? }
Log:
01-01 19:32:51.633 8516-8516/com.example.test2 I/test: 集合里的元素為:notes
01-01 19:32:51.634 8516-8516/com.example.test2 I/test: 集合中下標為 0的String類型元素為:notes
01-01 19:32:51.634 8516-8516/com.example.test2 I/test: 集合里的元素為:#
01-01 19:32:51.634 8516-8516/com.example.test2 I/test: 集合中下標為 1的String類型元素為:#
01-01 19:32:51.634 8516-8516/com.example.test2 I/test: 集合里的元素為:2
01-01 19:32:51.634 8516-8516/com.example.test2 I/test: 集合中下標為 2的String類型元素為:2
Failed to resolve: com.android.support:appcompat-v7:27.0.1問題解決
https://blog.csdn.net/waa_studio/article/details/78732460
sdk版本和build tool版本不一致
在project下的build.gradle文件下加上
allprojects {
? ? repositories {
? ? ? ? jcenter()
+ ? ? ? ?maven { url "https://jitpack.io" }
+ ? ? ? ?maven { url "https://maven.google.com" }
? ? }
}android gradle plugin update recommend
To take advantage of all the latest features (such as Instant Run), improvements and security fixes, we strongly recommend that you update the Android Gradle plugin to version 2.3.3 and Gradle to version 3.3. ?You can learn more about this version of the plugin from the release notes.?Unregistered VCS root detected
The directory /home/chenghao/APK/QianBaoDai is under Git, but is not registered in the Settings.
Sources for 'Android API 25 Platform' not found
方法:降低sdk版本的方式
Intellij IDEA 提交代碼到遠程GitHub倉庫
https://blog.csdn.net/longge92345/article/details/51902275?
解決ListViews適配器notifyDataSetChanged()無效問題
http://blog.csdn.net/csdn_lqr/article/details/50947825
聲明:
? ? 1,要使mAdapter.notifyDataSetChanged()有效的前提條件是數據發生變化!!!
? ? 2,new操作在java中是創建一個新的對象,實際上跟c語言一樣,會在內存中開辟一個新的空間,這里就會牽扯到數據的址傳遞和值傳遞問題。?
<meta-data>標簽
https://blog.csdn.net/c418098445/article/details/45248765
<meta-data>元素用name-value對的格式給其父組件提供任意可選的數據。一個組件元素能夠包含任意多個<meta-data>子元素,所有這些元素中定義的值會被收集到一個Bundle對象中,并且提供給組件的PackageItemInfo.metaData屬性字段<meta-data android:name="string" android:resource="resource specification" android:value="string" />
這是該元素的基本結構.可以包含在 <activity> <activity-alias> <service> <receiver>四個元素中。?1.在Activity的應用。
xml代碼段: ?
? ? <activity> ?
? ? ? ? ? ?<meta-data android:name="myMsg" android:value="hello"></meta-data> ?
? ? </activity> ?
java代碼段:
? ? ActivityInfo info=this.getPackageManager() .getActivityInfo(getComponentName(),PackageManager.GET_META_DATA); ?
? ? String msg=info.metaData.getString("myMsg"); ?2.在application的應用。
xml代碼段:
? ? <application> ?
? ? ? ? ?<meta-data android:value="hello" android:name="myMsg"></meta-data> ?
? ? </application> ?
java代碼段:
? ? ApplicationInfo appInfo = this.getPackageManager().getApplicationInfo(getPackageName(),PackageManager.GET_META_DATA); ?
? ? String msg=appInfo.metaData.getString("myMsg"); ?3.在service的應用。
xml代碼段:
? ? <service android:name="MetaDataService"> ?
? ? ? ? <meta-data android:value="hello" android:name="myMsg"></meta-data> ?
? ? </service> ?
java代碼段:?
? ? ComponentName cn=new ComponentName(this, MetaDataService.class); ?
? ? ServiceInfo info=this.getPackageManager().getServiceInfo(cn, PackageManager.GET_META_DATA); ?
? ? String msg=info.metaData.getString("myMsg"); ?4.在receiver的應用。
xml代碼段:
? ? <receiver android:name="MetaDataReceiver"> ?
? ? ? ? ? <meta-data android:value="hello" android:name="myMsg"></meta-data> ?
? ? ? ? ? <intent-filter> ?
? ? ? ? ? ? ? <action android:name="android.intent.action.PHONE_STATE"></action> ?
? ? ? ? ? </intent-filter> ?
? ? ?</receiver> ?
java代碼段:
? ? ComponentName cn=new ComponentName(context, MetaDataReceiver.class); ?
? ? ActivityInfo info=context.getPackageManager().getReceiverInfo(cn, PackageManager.GET_META_DATA); ?
? ? String msg=info.metaData.getString("myMsg"); ??
Modem編譯
先拉modem代碼編譯之前首先查找準確的mak文件:
1.首先在projectConfig.mk文件中查找
CUSTOM_MODEM=編譯生成 modem 文件夾名稱
在對應項目的sagereal/custom/modem/路徑下找到相對應的modem文件夾名稱
備注:
80m和80n平臺對應路徑在vendor/mediatek/proprietary/modem/目錄下
進入對應的modem文件夾找到DbgInfo形式開頭的文件,例如:DbgInfo_WR8.W1449.MD.WG.MP_XXXXXXX_MOLY_WR8_W1449_MD_WG_MP_V91_5_P3_2017_02_16_14_20_1_wg_n
此文件中MP_和_MOLY之間名稱為此項目對應的正確的modem文件名稱。把整個modem源碼以modem命名放在alps相同目錄下
在script文件夾中的project.mk中把要編的modem添加上去
? ? eg: modem1=VP25D_H508_BAND1_HSPA
? ??
在modem目錄下,執行 ./mk,會生成modemtmp和output兩個文件夾,output為輸出的所需的文件夾把output目錄copy到vendor/mediatek/proprietary/custom/common/modem/
或者sagereal/custom/modem/對應的modem然后重命名即可。替換之后驗證:./mk {project} ?clone
? ? ? ? ? ? ?./mk {project} ?update-modem ?: 之后刷機驗
? ? ? ? ? ? ?
編譯完成之后,對比新生成的.mak文件和上述modem文件夾中舊的.mak文件,進一步確認mak文件是否選擇正確,然后再執行其他操作。
Notification
在創建Notification實例的過程中調用setlargeicon(),傳入的參數是Bitmap。
但是只有res/drawable下的ic_launcher.png。
就需要用到下面:
Android中Bitmap, Drawable, Byte,ID之間的轉化 - - ITeye博客Android之利用RemoteViews自定義Notification
https://blog.csdn.net/loveyaozu/article/details/51178707通知欄通知和小部件的開發過程中經常會用到RemoteViews。它們在更新UI的時候無法像Activity和Fragment那樣直接更新,前面講過,因為它是跨進程的view,更確切一點來說的話,它是運行在SystemServer進程中。為了能夠跨進程更新界面,RemoteViews提供了一些列可以跨進程更新UI的方法,內部有一些列的set方法,這些方法都是View的子集。
通話過程中收到短信或藍牙,無聲音提醒
https://blog.csdn.net/self_study/article/details/51055769
?alps/frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java ?wuxiaoming
?
?116115
?vendor/mediatek/proprietary/packages/apps/Mms/src/com/android/mms/transaction/MessagingNotification.java?
SystemProperties
參看http://blog.csdn.net/yin1031468524/article/details/67640786
Android系統源碼中,存在大量的SystemProperties.get或SystemProperties.set,通過這兩個接口可以對系統的屬性進行讀取/設置,看著挺簡單的就是調用get或set就能獲取或設置系統屬性,其實并不然。曾經也遇到過有關的坑,所以就總結了下,這樣以后自己就不會在再次入坑了,接下來了正題吧
1、SystemProperties的使用
SystemProperties的使用很簡單,在SystemProperties.java中所以方法都是static,直接通過SystemProperties.get(String key)或SystemProperties.set(String key, String val)就可以了,系統屬性都是以鍵值對的形式存在即name和value需要注意的是對name和value的length是有限制的,name的最大長度是31,value最大長度是91
?
webview加載網頁出現("找不到網頁net:err_unknown_url_scheme")
解決方法:以"http","https"開頭的url在本頁用webview進行加載,其他鏈接進行跳轉
? ? private class MyWebViewClient extends WebViewClient{ ?
? ? ? ? @Override ??
? ? ? ? public boolean shouldOverrideUrlLoading(WebView view, String url) { ??
? ? ? ? ? ? ? ? if(url.startsWith("http:") || url.startsWith("https:") ) { ??
? ? ? ? ? ? ? ? view.loadUrl(url); ? ?
? ? ? ? ? ? ? ? return false; ? ?
? ? ? ? ? ? ? ? }else{ ?
? ? ? ? ? ? ? ? ? ? Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); ? ?
? ? ? ? ? ? ? ? startActivity(intent); ?
? ? ? ? ? ? ? ? return true; ? ?
? ? ? ? ? ? ? ? } ?
? ? ? ? } ? ???
? ? } ?
長按1撥打信箱電話接通時彈出撥號盤:
CallButtonPresenter.java
? ? -->getActivity().showDialpadFragment(true /* show */, true /* animate */);
? ? -->public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {}
? ? -->public void onInCallButtonUiReady(InCallButtonUi ui){}InCallFragment.java
? ? -->onButtonGridCreated()
? ??
InCallButtonGridFragment.java
? ? -->public interface OnButtonGridCreatedListener {
? ? ? ? void onButtonGridCreated(InCallButtonGridFragment inCallButtonGridFragment);
? ? ? ? void onButtonGridDestroyed();? ? ? ? ButtonController getButtonController(@InCallButtonIds int id);
? ? ? ? }
? ? ? ??
InCallButtonGridFragment.java
? ? -->
? ? @Override
? ? public void onViewCreated(View view, @Nullable Bundle bundle) {
? ? ? ? super.onViewCreated(view, bundle);
? ? ? ? buttonGridListener.onButtonGridCreated(this);
? ? }
? ??
2個分析方法如下: ? ?
? ??
一: ? ?
在撥通界面也可以通過點擊keypad鍵彈出撥號盤,分析如下:
通過id incall_second_button
找到incall_button-gird.xml和InCallButtonGirdFragment.java
--InCallButtonGirdFragment.java
? ? 里面有接口:
? ? ? ? /** Interface to let the listener know the status of the button grid. */
? ? ? ? ? ? public interface OnButtonGridCreatedListener {
? ? ? ? ? ? void onButtonGridCreated(InCallButtonGridFragment inCallButtonGridFragment);
? ? ? ? ? ? void onButtonGridDestroyed();
? ? ? ? ? ? ButtonController getButtonController(@InCallButtonIds int id);
? ? ? ? }
? ? 里面的生命周期方法:
? ? ? ? public void onViewCreated(View view, @Nullable Bundle bundle) {
? ? ? ? ? ? super.onViewCreated(view, bundle);
? ? ? ? ? ? android.util.Log.d("chenghao222","inCallbuttonGirdFragment.java-->onViewCreated()");
? ? ? ? ? ? buttonGridListener.onButtonGridCreated(this);
? ? ? ? }
? ? ? ? 調用了buttonGridListener.onButtonGridCreated(this);
? ? ? ? 接下來看哪一個類實現了該接口 OnButtonGridCreatedListener,并重寫了 onButtonGridCreated()方法。
? ? ? ? grep 發現InCallFragment.java實現了該接口,并重寫了 onButtonGridCreated()方法
? ? ? ? 在重寫的方法里有:
? ? ? ? inCallButtonUiDelegate.onInCallButtonUiReady(this);//inCallButtonUiDelegate是接口。
? ? ? ? 再看誰實現了他:CallButtonPresenter.java實現的,并重寫了onInCallButtonUiReady()方法,里面調用了onStateChange()方法。
? ? ? ? onStateChange()方法中調用了getActivity().showDialpadFragment(true /* show */, true /* animate */);//彈出撥號盤,bull's eye!
? ? ? ? 和updateButtonStates();
? ? ? ??
?二: ? ? ??
由于通過點擊keypad鍵彈出撥號盤,可以分析按鍵的點擊事件:
? ? 在InCallButtonGirdFragment.java中的onCreateView()中有
? ? ? ? buttons[1] = ((CheckableLabeledButton) view.findViewById(R.id.incall_second_button));
? ? CheckableLabeledButton.java中有:接口
? ? ? ? /** Callback interface to notify when the button's checked state has changed */
? ? ? ? ? ? public interface OnCheckedChangeListener {
? ? ? ? ? ? ? ? void onCheckedChanged(CheckableLabeledButton checkableLabeledButton, boolean isChecked);
? ? ? ? }
? ? ButtonController.java中的內部類、抽象類 CheckableButtonController 實現了這個接口,并重寫了onCheckedChanged()方法,并在其中調用doCheckedChanged(isChecked)抽象方法。
? ? abstract class SimpleCheckableButtonController extends CheckableButtonController ;
? ? class DialpadButtonController extends SimpleCheckableButtonController {};終于實現了doCheckedChanged(isChecked)方法!在方法內調用了
? ? ? ? delegate.showDialpadClicked(isChecked);
? ??
? ? CallButtonPresenter.java實現了inCallButtonUiDelegate接口,重寫了showDialpadClicked()方法。
? ? showDialpadClicked()方法中調用 getActivity().showDialpadFragment(checked /* show */, true /* animate */); 實現點擊keypad鍵彈出撥號盤!
多次解綁服務(unBindService)拋出異常原因解析
http://blog.sina.com.cn/s/blog_675b4b8d0102vwc0.html查看源碼
總結一下:
1. 綁定服務,首先要做的事情就是先用Map記錄當前綁定服務所需的一些信息。 然后啟動服務。
2. 解綁服務,先從早前的Map集合中移除記錄,然后停止服務。
3. 如果再次解綁,無非就是再到這個map集合中找找有沒有這條記錄,沒有就拋出服務沒有注冊的異常,也就是早前根本沒有注冊過任何服務。
?怎么合patch:
1.申請patch,下載patch。
2.select left folder For compare,compare to “文件名”。
3.進入Bcomparer,合入保存再編譯刷機驗證。
?注:(先切換到master分支下)
? ? 刪除某個文件 ? ?rm kernel-3.18/tools/dct/old_dct/MT8590.fig
? ? 刪除某個文件夾 ?rm -r vendor/mediatek/proprietary/external/libhotknot_device/src/mt6737/
? ? 再一一刪除各個文件或文件夾 git rm kernel-3.18/tools/dct/old_dct/MT8590.fig...
? ? git add ./ 或者git add . 添加所有改動的文件,exe文件會被添加;
? ? git add alps/vendor/google/ ? ? ? ?//該路徑下的改動的文件會被添加
? ? git add sagereal/product/ ? ? ? ? ? //該路徑下的改動的文件會被添加
? ??
? ? 提交 git commit -m "ALPS03422589(For_sr6737t_65_n_alps-mp-n0.mp1-V1.0.2_P109)" //至此已完成主分支的合patch操作
? ??
? ? 接下來合到各個分支:
? ? 再切換到各個分支,用git cherry-pick fd1b0a0587ba1d36bac6f0a998840c5f2f4ced9a(修改好的分支的某次commit ID)
? ? (也可以用merge方法,但我不知道!)
? ? 執行git cherry-pick fd1b0a0587ba1d36bac6f0a998840c5f2f4ced9a后,不用commit,可以使用git log 查看提交,接著push就可以了。
? ? patch釋放后,要拉代碼,然后將patch上傳patch服務器下。然后有專門的人負責合patch到master以及各個分支。
? ? 注:git cherry-pick沖突后,解決沖突后,再add,commit,push
??
-------------------------------------------------------------------------------------------------------------------------------------------- ?
https://blog.csdn.net/liuhaomatou/article/details/54410361
怎么把自己的本地修改做成patch :
先修改代碼,再add,再 git commit -m "modify for cts error; checker:rongweidi",再git log 查看最后一次commit id,
再git format-patch -1 fb883372cb2b808de092dc744351d803db99c06b,這樣在工程下就生成了一個patch怎么合本地生成的patch:
把具體patch放到工程目錄下,git am --signoff 0001-cts-theme-error-checker-zhangqi.patch打patch
git apply --stat 0001-cts-theme-error-checker-zhangqi.patch
git apply --check 0001-cts-theme-error-checker-zhangqi.patch
git am --signoff 0001-cts-theme-error-checker-zhangqi.patchgit format-patche commit-id //會生成該條commit-id之后的每次提及對應的patch
AOSP宏控
1.Config.xml宏控
1>在symbols.xml 聲明宏控的類型 (alps/vendor/mediatek/proprietary/frameworks/base/res/res/values/symbols.xml)
eg:
<!--Redmine102280 chencong modify for camera flash when battery level is under 15% 2017.08.11 begin-->
?<java-symbol type="bool" name="sagereal_low_battery_level_warning" />
<!--Redmine102280 chencong modify for camera flash when battery level is under 15% 2017.08.11 end-->2>在config.xml ?給宏控賦值 (alps/vendor/mediatek/proprietary/frameworks/base/res/res/values/config.xml)
eg:
<!--Redmine102280 chencong modify for camera flash when battery level is under 15% 2017.08.11 begin-->
? ? ?<bool name="sagereal_low_battery_level_warning">false</bool>
<!--Redmine102280 chencong modify for camera flash when battery level is under 15% 2017.08.11 end-->3>在源碼文件中調用該宏控
注:bool型的值被寫入JavaOption.java文件
i. alps/vendor/mediatek/proprietary/frameworks/base/res/res/values/config.xml中定義宏控,格式:sagereal_xxx_xxx, xxx用于描述添加宏控的作用
eg:<bool name="sagereal_show_record_menu">true</bool>ii. alps/vendor/mediatek/proprietary/frameworks/base/res/res/values/symbols.xml中定義宏控的類型: <java-symbol type="bool" name="sagereal_show_record_menu" />
iii.在需要調用宏控的地方調用該宏控getContext().getResources().getBoolean(com.mediatek.internal.R.bool.sagereal_show_record_menu)
因為所加的內容被編譯在com.mediatek.internal包,所以此處調用com.mediatek.internal.R注:*****在對應項目的projectconfig.mk文件下可以對宏重新賦值。
clone_mmi.sh腳本文件作用:
將sagereal下對應項目的宏控的值寫到alps/vendor/mediatek/proprietary/frameworks/base/res/res/values/config.xml中2.ro值宏控
適用于獲取不到context的地方調用
i.在sagereal/mk/{project}/ProjectConfig.mk中添加宏控:SAGEREAL_FACTORYTEST_LED = yes
?? ?宏控格式:SAGEREAL_XXX_XXX, XXX問題修改的描述
ii.在alps/device/mediatek/common/device.mk中添加ro值的控制
?? ?ifeq ($(strip $(SAGEREAL_FACTORYTEST_LED)),yes)
?? ??? ?PRODUCT_PROPERTY_OVERRIDES += ro.sr_ftest_led=1
?? ?endif
iii.在源碼文件中調用宏控,使用SystemProperties.get(“ro.sr_ftest_led”, 0).equals(“1”)來判斷,注意導包,此處無需獲取context, ro.sr_ftest_led一旦沒設置,此處獲取出來為空, 可使用:?? ?adb shell getprop ro.sr_ftest_led 獲取或檢查是否設置加宏具體要怎么操作呢?
1.alps/vendor/mediatek/proprietary/frameworks/base/res/res/values/config.xml中定義宏控名稱及默認值(一版默認原生的流程false)
2.alps/vendor/mediatek/proprietary/frameworks/base/res/res/values/symbols.xml中定義類型
3.Java文件中調用宏控來控制代碼流程
4.ProjectConfig.mk中指定需要修改的宏控名稱及修改的值
5.clone_mmi.sh中指定path及writexml的宏控名稱
將數據庫文件pull出來:
adb pull /data/data/com.example.databasetest/databases/BookStore.db將數據庫文件push到手機:
adb push BookStore.db /data/data/com.example.databasetest/databases/打開終端
sqlitebrowser//打開可視化Sqlite例子:
chenghao@chenghao-ThinkStation-P300:~$ adb root
adbd is already running as root
chenghao@chenghao-ThinkStation-P300:~$ adb remount
remount succeeded
chenghao@chenghao-ThinkStation-P300:~$ adb shell
Chinchilla:/ # ?cd data/data/com.google.android.gsf/databases/ ? ? ? ? ? ? ? ? ? ? ? ? ??
Chinchilla:/data/data/com.google.android.gsf/databases # ls
googlesettings.db gservices.db subscribedfeeds.db?
Chinchilla:/data/data/com.google.android.gsf/databases # sqlite3 gservices.db ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
SQLite version 3.19.4 2017-08-18 19:28:12
sqlite> select * from main where name = "android_id"
? ?...> ;
sqlite> .headers on
sqlite> select * from main;
name|value
digest|1-da39a3ee5e6b4b0d3255bfef95601890afd80709
https://onlinesso.mediatek.com/FAQ#/SW/FAQ12393
Software #117876
[傳音需求-----圖庫] 圖庫放大比例,雙擊放大2倍,雙指縮放最大到3.5倍
修改sim卡默認鈴聲:
project.config
clone_integration.sh
alps/build/target/product/full_base.mk
alps/frameworks/base/data/sounds/AllAudio.mk
注意full_base.mk文件中修改的內容每行末尾都要加 \
不然會clone失敗?
怎樣修該代碼:
如果在sageral拷貝下的改動完成之后,
使用:
./mk UP19_H353_ODO_new clone
將sageral下的所有改動 克隆 到alps下面。然后模塊編譯:
./mk UP19_H353_ODO_new mm packages/apps/SagerealApp/ChromeCustomizations/adb remount
push apk到手機:
adb push out/target/product/sr6572_wet_l/system/vendor/app/ChromeCustomizations/ChromeCustomizations.apk system/vendor/app/ChromeCustomizations/ChromeCustomizations.apk提交代碼:?
?? ?a. git pull // 更新到最新代碼?
?? ?b. 修改代碼?
?? ?c. git status // 當前狀態,可以查看修改了哪些代碼,?
?? ?d. git add +文件路徑 //最好新拉工程,將需要提交的移到新拉的工程上再操作 如果確認所有的修改都是需要上傳到服務器上的可以使用:git add . // 將所有變動都上傳?
?? ?e. git commit –m, 在出現的界面數據上傳log信息,格式同svn:
?? ?
Redmine書寫格式:?? ?
Submitter:?
checker:?
Tester: ?
Bug:?
Files:?
M alps/vendor/mediatek/proprietary/packages/apps/Dialer/java/com/android/incallui/CallButtonPresenter.java?? ?
Comment: ?
Date: 2018-06-21android.util.Log.d("chenghao","");
?? ?f. git push origin XXX // XXX表示當前分支 比如 master xxxbranch?
git status
git add sagereal/pcb/WE552_H5018_commom/alps/vendor/mediatek/proprietary/custom/mt6755/hal/imgsensor_src/cfg_setting_imgsensor.cpp ?修改多處則:add .
git status
git diff
git commit -m "modify for ?submit: ?check: ?date: "
git push origin dev_fr //如果push不上去,說明這期間有人更新了代碼,所以要git pull再git push origin dev_fr。
?
總結
以上是生活随笔為你收集整理的Android点滴积累的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DirectX11--教程项目无法编译、
- 下一篇: ora-00955: 名称已由现有对象使