顯示具有 Android Studio 標籤的文章。 顯示所有文章
顯示具有 Android Studio 標籤的文章。 顯示所有文章

2019年3月6日 星期三

Android 產生Signed Apk時錯誤 Keystore was tampered with, or password was incorrect

在產生signed apk時

明明輸入正確密碼卻出現 Keystore was tampered with, or password was incorrect 錯誤訊息

密碼打到懷疑人生...一直以為是密碼錯誤

 於是開始找密碼  

方法一: https://github.com/nanqiu/android-keystore-password-recover/blob/master/README.md

下載這個程式 把你的xxxx.jks放到同一資料夾

建立一個關鍵字wordlist.txt

然後想想可能的關鍵字 打在裡面

打開 cmd下指令
java -jar AndroidKeystoreBrute_v1.05.jar -m 3 -k xxxx.jks -d "wordlist.txt" 

 找到密碼

結果密碼沒錯啊

回到Android Studio再產生看看, 一樣是說密碼錯誤 wtf, 難道是其中有一個密碼錯誤

於是再繼續找密碼


https://stackoverflow.com/questions/28034899/how-to-retrieve-key-alias-and-key-password-for-signed-apk-in-android-studiomigr

這篇提到如果有用過Android Studio 2.2之前的

Android Studio會有Log檔案, 裡面竟然有密碼啊啊啊啊啊

Windows系統位置在
C:\Users\xxxxx\.AndroidStudio2.2\system\log
裡面有個 idea.log.1
用記事本打開他, 搜尋一下password,  you got it !!!
兩個密碼都有
結果都正確啊啊啊啊啊啊

於是我開始懷疑根本是Android Studio的問題

https://stackoverflow.com/questions/32987530/android-studio-keystore-was-tampered-with-or-password-was-incorrect
提到換密碼就好

https://stackoverflow.com/questions/2889238/keystore-change-passwords

先找到keytool位置
C:\Program Files\Java\jdk1.8.0_73\bin
然後將你的xxxx.jks放在這
cmd下指令
 
keytool -storepasswd -keystore xxxx.jks
會要你輸入舊密碼與新密碼
 
keytool -keypasswd  -alias xxxx -keystore xxxx.jks
alias名稱要正確
然後一樣輸入舊密碼與新密碼
完成


回到Android Studio, 一定要先Clean Project
再Generate Signed Bundle/APK

成功產生!!! 害我嚇到吃手手 WTF

2016年3月7日 星期一

Android RecyclerView

替代ListView方案 RecyclerView

1.在build.gradle(Module:app)添加compile 'com.android.support:recyclerview-v7:+'
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"
    defaultConfig {
        applicationId "com.terryyamg.recyclerviewtest"
        minSdkVersion 17
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    productFlavors {
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.0'
    compile 'com.android.support:recyclerview-v7:+'
}


2./res/layout/activity_main.xml


    



3.新增項目的layout /res/layout/item.xml
點擊效果
android:clickable="true"
android:background="?android:attr/selectableItemBackground"


    



4.新增分隔線class檔案 DividerItemDecoration.java
package com.terryyamg.recyclerviewtest;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

    private static final int[] ATTRS = new int[]{
            android.R.attr.listDivider
    };

    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;

    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;

    private Drawable mDivider;

    private int mOrientation;

    public DividerItemDecoration(Context context, int orientation) {
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
        setOrientation(orientation);
    }

    public void setOrientation(int orientation) {
        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
            throw new IllegalArgumentException("invalid orientation");
        }
        mOrientation = orientation;
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }
    }

    public void drawVertical(Canvas c, RecyclerView parent) {
        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();

        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    public void drawHorizontal(Canvas c, RecyclerView parent) {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getHeight() - parent.getPaddingBottom();

        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int left = child.getRight() + params.rightMargin;
            final int right = left + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
        } else {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        }
    }
}


5.新增點擊class檔案 RecyclerTouchListener.java
package com.terryyamg.recyclerviewtest;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {

    private GestureDetector gestureDetector;
    private ClickListener clickListener;

    public interface ClickListener {
        void onClick(View view, int position);

        void onLongClick(View view, int position);
    }

    public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
        this.clickListener = clickListener;
        gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }

            @Override
            public void onLongPress(MotionEvent e) {
                View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
                if (child != null && clickListener != null) {
                    clickListener.onLongClick(child, recyclerView.getChildAdapterPosition(child));
                }
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {

        View child = rv.findChildViewUnder(e.getX(), e.getY());
        if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
            clickListener.onClick(child, rv.getChildAdapterPosition(child));
        }
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
}

6.主檔 MainActivity.java
package com.terryyamg.recyclerviewtest;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private String[] ss = {"no.01", "no.02", "no.03","no.04", "no.05", "no.06","no.07", "no.08", "no.09","no.10", "no.11", "no.12"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RecyclerView rv = (RecyclerView) findViewById(R.id.rv);
        MyAdapter adapter = new MyAdapter(ss);
        LinearLayoutManager lm = new LinearLayoutManager(this);
        rv.setLayoutManager(lm);
        rv.setHasFixedSize(true); //當RecyclerView大小沒改變時最佳化
        rv.setItemAnimator(new DefaultItemAnimator()); //預設動畫效果
        rv.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL)); //分隔線
        rv.setAdapter(adapter);
        //監聽事件
        rv.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), rv, new RecyclerTouchListener.ClickListener() {
            @Override
            public void onClick(View view, int position) {
                Toast.makeText(MainActivity.this, ss[position],Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onLongClick(View view, int position) {

            }
        }));
    }

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

        private String[] ss;

        public class MyViewHolder extends RecyclerView.ViewHolder {
            public TextView tv;

            public MyViewHolder(View view) {
                super(view);
                tv = (TextView) view.findViewById(R.id.tv);
            }
        }

        public MyAdapter(String[] ss) {
            this.ss = ss;
        }

        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            //設定item layout
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);

            return new MyViewHolder(itemView);
        }

        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {
            //放入資料
            holder.tv.setText(ss[position]);
        }

        @Override
        public int getItemCount() {
            //取得長度
            return ss.length;
        }
    }

}




檔案下載:
https://github.com/terryyamg/RecyclerViewTest
參考連結:
http://www.androidhive.info/2016/01/android-working-with-recycler-view/
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#getChildPosition%28android.view.View%29

2015年12月15日 星期二

Android Address 取得地址

以座標來取得住址位置
http://developer.android.com/reference/android/location/Address.html

1./res/layout/activity_main.xml 放個TextView


    



2.MainAcitvity.java
package com.terryyamg.addressestest;

import android.app.Activity;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.widget.TextView;

import java.io.IOException;
import java.util.List;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tvAddress = (TextView) findViewById(R.id.tvAddress);

        Geocoder geocoder = new Geocoder(this);
        List<Address> addresses = null;
        double lat = 22.6721740;
        double lon = 120.3100350;
        try {
            addresses = geocoder.getFromLocation(lat, lon, 1); //放入座標
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (addresses != null && addresses.size() > 0) {
            Address address = addresses.get(0);
            String addressText = String.format("%s-%s%s%s%s",
                    address.getCountryName(), //國家
                    address.getAdminArea(), //城市
                    address.getLocality(), //區
                    address.getThoroughfare(), //路
                    address.getSubThoroughfare() //巷號
            );

            tvAddress.setText(addressText);
        }

    }

}


檔案下載:
https://github.com/terryyamg/AddressesTest
參考連結:
http://developer.android.com/reference/android/location/Address.html
http://wptrafficanalyzer.in/blog/android-reverse-geocoding-at-touched-location-in-google-map-android-api-v2/

2015年11月23日 星期一

Android Badger Icon 提示 通知 數字

icon上的數字提示通知,Android沒有內建的,所以使用第三方套件ShortcutBadger

使用IDE: Android Studio
1.建立新方案後,在build.gradle(Module:app)檔案裡的dependencies位置裡面加上 compile 'me.leolin:ShortcutBadger:1.1.3@aar' 下載該套件
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'me.leolin:ShortcutBadger:1.1.3@aar'
}
2.AndroidManifest.xml


    

        
            
                

                
            
        

    


3.res/layout/activity_main.xml


    

    

    




4.MainActivity.java
package com.terryyamg.shortcutbadgertext;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import me.leolin.shortcutbadger.ShortcutBadger;

public class MainActivity extends Activity {

    private int badgeCount;
    private EditText numInput;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        numInput = (EditText) findViewById(R.id.numInput);

        Button button = (Button) findViewById(R.id.btnSetBadge);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                badgeCount = 0;
                try {
                    badgeCount = Integer.parseInt(numInput.getText().toString());
                } catch (NumberFormatException e) {
                    Toast.makeText(MainActivity.this, "錯誤:", Toast.LENGTH_SHORT).show();
                }

                ShortcutBadger.with(MainActivity.this).count(badgeCount); //次數

                Toast.makeText(MainActivity.this, "通知次數=" + badgeCount, Toast.LENGTH_SHORT).show();
            }
        });


        //find the home launcher Package
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        ResolveInfo resolveInfo = getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
        String currentHomePackage = resolveInfo.activityInfo.packageName;

        TextView textViewHomePackage = (TextView) findViewById(R.id.textViewHomePackage);
        textViewHomePackage.setText("手機型號:" + currentHomePackage);
    }

    @Override
    protected void onStart() {
        super.onStart();
        ShortcutBadger.with(this).remove(); //歸0
        Toast.makeText(this, "已讀", Toast.LENGTH_SHORT).show();
    }
}


檔案下載:
https://github.com/terryyamg/ShortcutBadgerText
參考連結:
https://github.com/leolin310148/ShortcutBadger

2015年6月4日 星期四

Android Studio Import libs 專案 匯入 套件 UI 美化

Android Studio專案套件匯入與eclipse匯入方式不同
1.首先建立一個空白專案,建立完成後打開在app下的build.gradle檔案

2.以https://github.com/rey5137/material UI 為例,在build.gradle檔案加入
compile 'com.android.support:appcompat-v7:21.0.3' 
compile 'com.github.rey5137:material:1.1.1'
compile 'com.android.support:cardview-v7:21.0.3'





3.基本上在這裡點選Build -> Clear Project 就會下載匯入在你的專案裡


4.在專案點右鍵 -> Open Module Settings中的Dependencies裡可以看到匯入的lib



5.下載https://github.com/rey5137/material/archive/master.zip 拿裡面的demo檔來測試
位置在下載的資料夾material-master\app\src\main,在這裡先測試button原件
將material-master\app\src\main\res除了layout資料夾其他資料夾複製到你的專案底下 res的位置


6.在專案res/下建立layout資料夾,建立activity_main.xml,複製material-master\app\src\main\res\layout\fragment_button.xml裡的程式碼


    

        

        

            

            

            

        

        

            

            

            

        

        

        

            

            

            

        

        

            

            

            

        

        

        

            

            

            

        

        

            

            

            

        

    



    
7.建立MainActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.view.View;

import com.rey.material.drawable.RippleDrawable;
import com.rey.material.widget.Button;
import com.rey.material.widget.FloatingActionButton;

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button bt_flat = (Button) findViewById(R.id.button_bt_flat);
        Button bt_flat_color = (Button) findViewById(R.id.button_bt_flat_color);
        Button bt_flat_wave = (Button) findViewById(R.id.button_bt_flat_wave);
        Button bt_flat_wave_color = (Button) findViewById(R.id.button_bt_flat_wave_color);
        Button bt_raise = (Button) findViewById(R.id.button_bt_raise);
        Button bt_raise_color = (Button) findViewById(R.id.button_bt_raise_color);
        Button bt_raise_wave = (Button) findViewById(R.id.button_bt_raise_wave);
        Button bt_raise_wave_color = (Button) findViewById(R.id.button_bt_raise_wave_color);
        FloatingActionButton bt_float = (FloatingActionButton) findViewById(R.id.button_bt_float);
        FloatingActionButton bt_float_color = (FloatingActionButton) findViewById(R.id.button_bt_float_color);
        FloatingActionButton bt_float_wave = (FloatingActionButton) findViewById(R.id.button_bt_float_wave);
        FloatingActionButton bt_float_wave_color = (FloatingActionButton) findViewById(R.id.button_bt_float_wave_color);

        /*左邊正常速度*/
        View.OnClickListener listener = new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if (v instanceof FloatingActionButton) {
                    FloatingActionButton bt = (FloatingActionButton) v;
                    bt.setLineMorphingState((bt.getLineMorphingState() + 1) % 2, true);
                }

                System.out.println(v + " " + ((RippleDrawable) v.getBackground()).getDelayClickType());
            }
        };
        /*右邊DELAY速度*/
        View.OnClickListener listener_delay = new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if (v instanceof FloatingActionButton) {
                    FloatingActionButton bt = (FloatingActionButton) v;
                    bt.setLineMorphingState((bt.getLineMorphingState() + 1) % 2, true);
                }

                System.out.println(v + " " + ((RippleDrawable) v.getBackground()).getDelayClickType());
            }
        };

        /*監聽事件*/
        bt_flat.setOnClickListener(listener);
        bt_flat_wave.setOnClickListener(listener);
        bt_raise.setOnClickListener(listener);
        bt_raise_wave.setOnClickListener(listener);
        bt_float.setOnClickListener(listener);
        bt_float_wave.setOnClickListener(listener);

        bt_flat_color.setOnClickListener(listener_delay);
        bt_flat_wave_color.setOnClickListener(listener_delay);
        bt_raise_color.setOnClickListener(listener_delay);
        bt_raise_wave_color.setOnClickListener(listener_delay);
        bt_float_color.setOnClickListener(listener_delay);
        bt_float_wave_color.setOnClickListener(listener_delay);

    }

}
8.最後修改一下AndroidManifest.xml


    
    

        
            
                

                
            
        
    




其餘的UI就依樣畫葫蘆

檔案下載: https://github.com/terryyamg/ASLibTest
參考連結:https://github.com/rey5137/material