ラベル android の投稿を表示しています。 すべての投稿を表示
ラベル android の投稿を表示しています。 すべての投稿を表示

IntelliJ IDEA "Cannot resolve symbol 'Xxxxx'" but builds modules successfully on a Gradle project


"Cannot resolve symbol 'Xxxxx'" on a Gradle project
  1. File > Invalidate Caches / Restart...
  2. Invalidate
  3. File > Close Project
  4. Remove the Gradle project from projects history
  5. Exit IntelliJ IDEA
  6. Remove "IntelliJ IDEA system" dir
    $ rm -rf ~/.IntelliJIdea201X.Y/system/
    
  7. Start IntelliJ IDEA again
  8. Import the Gradle project

Warning:Using incompatible plugins for the annotation processing: android-apt. This may result in an unexpected behavior.


IntelliJ IDEA 2017.2

先日 IntelliJ IDEA を起動しましたところ JETBRAINS 様より Build IU-172.3317.76 なるバージョンがこの私めの元に降ってまいりました。天下の JETBRAINS 様の手による名 IDE の誉れ高き IntelliJ IDEA の最新版でございます。何も迷うことはございません。ただちにアップグレードさせて頂きました。

アップグレード完了後再び IntelliJ IDEA を起動致しまして、とある Andorid 開発ブロジェクトを開きましたところ、すかさず、 Gradle の Android Plugin をアップデートせよ、との天啓でございます。私、こちらも迷うことなくアップデート致しました。

するとトップレベルの build.gradle ファイルが以下のように変更されます。

buildscript {

    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.0'

また gradle/wrapper/gradle-wrapper.properties ファイルも変更されるのです。

distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip

早速ビルドでございます。

するとどうでしょう? Data Binding 周りが一切ビルドされずことごとくエラーとなるのです。

Warning:Using incompatible plugins for the annotation processing: android-apt. This may result in an unexpected behavior.

ビルドを開始致しますと、最初に出るこの Warning がどうにも怪しいのでございます。そのままグーグル先生にお問い合わせ致しますと以下の回答が返ってきます。

先人の教えに倣いましてアプリモジュールレベルの build.gradle から該当箇所を削除致します。

消えないのであります。 Annotation Processing の Warning が。

暗澹たる気持ちでアプリモジュールレベルの build.gradle に記述してある依存ライブラリを一つずつ削除し、ビルドしていきます。すると、

apply plugin: 'realm-android'

Realm を削除したところで件の Warning が消えるではありませんか。

なんのことはございません。使っていた Realm が古すぎたのでございます。トップレベルの build.gradle を以下のとおり変更致しまして Realm を 2.0 から 3.5 にアップデート致します。

classpath "io.realm:realm-gradle-plugin:3.5.0"

無事 Warning が消えエミュレータ上での実行まですんなりでございます。気持ちビルド自体も早くなったような気がし、心穏やかに開発を続けられそうでございます。ありがとうございます。

error: could not install *smartsocket* listener: Address already in use

adb command returns an error.
$ adb devices
(snip)
error: could not install *smartsocket* listener: Address already in use
(snip)
Change Genymotion settings below, to fix this error.

check 'Use custom Android SDK tools'

Install CyanogenMod on Motorola Moto G (XT1032)

  1. Unlock Moto G

    1. $ adb devices
      List of devices attached
      hogehoge device
      TAnnnnnnnnTH device
              

    2. $ adb -s TAnnnnnnnnTH reboot bootloader
              

    3. $ sudo fastboot devices
      [sudo] password for user_name:
      TAnnnnnnnnTH fastboot
              

    4. $ sudo fastboot oem get_unlock_data
      ...
      (bootloader) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      (bootloader) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      (bootloader) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      (bootloader) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      (bootloader) 0000000
      OKAY [  0.133s]
      finished. total time: 0.133s
              

    5. To get device unlock code, visit https://motorola-global-portal.custhelp.com/app/standalone/bootloader/unlock-your-device-a/action/auth and follow the instructions there.

    6. $ sudo fastboot oem unlock XXXXXXXXXXXXXXXXXXXXX
      ...
      (bootloader) Unlock code = XXXXXXXXXXXXXXXXXXXXX
      
      (bootloader) Unlock completed! Wait to reboot
      
      FAILED (status read failed (No such device))
      finished. total time: 27.954s
              
  2. Login to Moto G again
    1. Power on
    2. Login to device
    3. Enable developer mode
  3. Install recovery using fastboot
    1. Download recovery, https://dl.twrp.me/xt1032/twrp-2.8.6.0-xt1032.img

    2. $ adb -s TAnnnnnnnnTH reboot bootloader
              

    3. $ sudo fastboot flash recovery twrp-2.8.6.0-xt1032.img
      target reported max download size of 536870912 bytes
      sending 'recovery' (8480 KB)...
      OKAY [  0.297s]
      writing 'recovery'...
      OKAY [  0.466s]
      finished. total time: 0.763s
              
    4. Volum Down to select Recovery
    5. Then Volum Up
  4. Install CyanogenMod
    1. Download CyanogenMod package, http://download.cyanogenmod.org/?device=falcon
    2. Download Google Apps, https://wiki.cyanogenmod.org/w/Google_Apps
    3. (In Team Win Recovery, Create backup.)
    4. In Team Win Recovery, Select Wipe and Factory Reset.
    5. Select Install and move to '/sdcard' dir.
    6. Install CyanogenMod package.
    7. Install Google Apps.
    8. Select Reboot and System.
  5. Done.

Genymotion Android エミュレータの hosts を書き換える

  1. Genymotion から hosts ファイルを引っ張ってくる
    $ adb -s 192.168.99.101:5555 pull /system/etc/hosts hosts
    
  2. hosts ファイルを書き換える
    $ vi hosts
    
  3. Genymotion の /system を書き込み可能でマウント
    $ adb -s 192.168.99.101:5555 remount
    
  4. Genymotion に書き換えた hosts ファイルを反映させる
    $ adb -s 192.168.99.101:5555 push hosts /system/etc
    

新 ubuntu マッシーンで android 開発環境構築

ヌーマッシーン購入

この度 System76 から2台目となる laptop Galago Ultra Pro を購入致しまして、開発環境を構築しておりました。(1台目は Lemur Ultra)

久しぶりということもあってか、android の開発環境の構築に何故か四苦八苦しておりました。

gradle や IntelliJ の設定をいろいろゴニョゴニョしてもなかなか Genymotion で動作確認するところまで行き着きません。結局はコレをやってなかったから出来なかったことが判明致しました。

また同様に開発環境を構築する機会もなかなかないと思われますので、備忘として残しておいてもアレかと思われますが、ここにメモさせて頂きます。

要は android SDK を 64bit マシーンにセットアップする際に必要となるパッケージが必要、ということでございました。

android-x86-4.4-RC1

VirtualBoxで簡単に動かせただよ
  • シャットダウンはSettingsの一番下(のみ?)

Volley synchronous request / Volleyで同期的なリクエストをする方法

com.android.volley.toolbox.RequestFuture

RequestQueue queue = Volley.newRequestQueue(context);
RequestFuture<Hoge> future = RequestFuture.newFuture();
Request<Hoge> request = new FugaRequest(Request.Method.POST, url, future);
queue.add(request);
try {
    Hoge response = future.get();
} catch (InterruptedException e) {
    // TODO
} catch (ExecutionException e) {
    // TODO
}

ubuntu MTP Nexus 7

(メモ)

$ sudo add-apt-repository ppa:langdalepl/gvfs-mtp
$ sudo apt-get update
$ sudo apt-get upgrade

ubuntu再起動

$ sudo shutdown -r now

補足
(なおusb debuggingを止めないとMTPで繋がりませんので)

Change the battery level of android emulator (AVD)

$ adb devices
List of devices attached 
emulator-5554 device
$ telnet localhost 5554
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Android Console: type 'help' for a list of commands
OK
help
Android console command help:

    help|h|?         print a list of commands
    event            simulate hardware events
    geo              Geo-location commands
    gsm              GSM related commands
    cdma             CDMA related commands
    kill             kill the emulator instance
    network          manage network settings
    power            power related commands
    quit|exit        quit control session
    redir            manage port redirections
    sms              SMS related commands
    avd              control virtual device execution
    window           manage emulator window
    qemu             QEMU-specific commands
    sensor           manage emulator sensors

try 'help <command>' for command-specific help
OK
power
allows to change battery and AC power status

available sub-commands:
    display          display battery and charger state
    ac               set AC charging state
    status           set battery status
    present          set battery present state
    health           set battery health state
    capacity         set battery capacity state

KO: missing sub-command
power capacity 77
OK

Intent com.android.camera.action.CROP ActivityNotFoundException

Intent intent = new Intent("com.android.camera.action.CROP");

    /* Not work. ActivityNotFoundException occurs. */
    //intent.setType("image/*");
    //intent.setData(uri);

    intent.setDataAndType(uri, "image/*"); // works!

    startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP);
(マジ?)

日本でも使えますよ?Chromecastの設定用apkを入手する

Googleのスマホ連携用HDMIスティック「Chromecast」が直輸入、ただし…
ただし、現時点ではChromecast用アプリを国内のGoogle Play/iTunesアカウントから入手することができず、使用するのは難しい状態。どちらのアカウントでも「このアプリは日本では利用できない」という旨のメッセージが表示され、端末にアプリを導入することはできなかった。
そう、正規ルートだとChromecast設定用アプリを入手することは出来ない。けど、
■ Chromecastの設定APKは落ちている
こちらでも紹介されてるし、APKの直リンはここ
■ Chromecastマジで(・∀・)イイ!!
2013版のNexus 7をリモコンにしてベットに寝転びながら、YouTubeの登録チャンネルから配信された新しい動画をボケーッと観てる。

Nexus 7 2012とNexus 7 2013を比較

2012(16GBモデル) 2013(16GB/WiFiモデル)
androidバージョン 4.3 4.3
モデル番号 Nexus 7 Nexus 7
カーネルバージョン 3.1.10-g1e8b3d8 3.4.0-g6537a16
ビルド番号 JWR66Y JSS15Q
ディスプレイインチ 7.3 6.8
Density tvdpi(213dpi) xhdpi(320dpi)
解像度(px) 800x1280 1200x1920
解像度(dp) 601.5x962.4 600x960
Size large large
Aspect ratio notlong notlong
おまけ重さ 340g 290g(ちょい軽い!)
厚さ 10.45mm 8.65mm(ちょい薄い!)
バッテリー 4325mAH 3950mAH(え!?)
RAM 1GB 2GB
CPU 1.2GHz
(NVIDIA Tegra 3)
1.5 GHz
(Qualcomm Snapdragon S4 Pro)
お値段(Google Play) ¥19,800 ¥27,800

APK Expansion Files

Development environment.
  • Ubuntu 11.10 (Oneiric)
  • JDK 1.6.0_24-b07
  • Eclipse 3.7.3 (Indigo)
    • Android Development Toolkit 17.0.0

Preparing.
  1. Get a publisher account here for Google Play, if you don't have yet.
  2. Download two packages from the SDK Manager.('Google Play APK Expansion Library' and 'Google Play Licensing Library')
    Android SDK Manager
  3. Create two library projects from existing source.
    • <sdk>/extras/google/play_apk_expansion/downloader_library
    • <sdk>/extras/google/play_licensing/library
  4. Create a new project which you want to use APK Expansion Files and add above two library project to your new project's build path.
    Add a reference to a library project

Implementing.
  1. Downloader service.
    // Extends com.google.android.vending.expansion.downloader.impl.DownloaderService class and override three methods.
    public class ExpansionFileDownloaderService extends DownloaderService {
     // the Base64-encoded RSA public key for your publisher account
     private static final String PUBLIC_KEY = "{YOU_PUBLIC_KEY}";
     // Generate 20 random bytes, and put them here.
     private static final byte[] SALT = new byte[] {};
     @Override public String getPublicKey() {
      return PUBLIC_KEY;
     }
     @Override public byte[] getSALT() {
      return SALT;
     }
     @Override public String getAlarmReceiverClassName() {
      return ExpansionFileAlarmReceiver.class.getName();
     }
    }
    
  2. Alarm receiver.
    public class ExpansionFileAlarmReceiver extends BroadcastReceiver {
     @Override public void onReceive(Context context, Intent intent) {
      try {
       DownloaderClientMarshaller.startDownloadServiceIfRequired(
         context, intent, ExpansionFileDownloaderService.class);
      } catch (NameNotFoundException e) {
       Log.e("apk-expansion-files", "NameNotFoundException occurred. " + e.getMessage(), e);
      }
     }
    }
    
  3. Main activity.
    @Override
     public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      
      // Check whether the file have been downloaded.
      String mainFileName = Helpers.getExpansionAPKFileName(this, true, 1);
      boolean fileExists = Helpers.doesFileExist(this, mainFileName, 32921796L, false);
      if (!fileExists) {
       Intent launcher = getIntent();
       Intent fromNotification = new Intent(this, getClass());
       fromNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
       fromNotification.setAction(launcher.getAction());
       if (launcher.getCategories() != null) {
        for (String cat : launcher.getCategories()) {
         fromNotification.addCategory(cat);
        }
       }
       PendingIntent pendingIntent = PendingIntent.getActivity(
         this, 0, fromNotification, PendingIntent.FLAG_UPDATE_CURRENT);
       try {
        // Start the download
        int result = DownloaderClientMarshaller.startDownloadServiceIfRequired(
          this, pendingIntent, ExpansionFileDownloaderService.class);
        if (DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED != result) {
         // implement Downloading UI.
         return;
        }
       } catch (NameNotFoundException e) {
        Log.e("apk-expansion-files", "NameNotFoundException occurred. " + e.getMessage(), e);
       }
      }
      // expansion file is available. start your application.
     }
    

Manifest declarations.
  • uses-permission
    <!-- Required to access Android Market Licensing -->
    <uses-permission android:name="com.android.vending.CHECK_LICENSE" />
    <!-- Required to download files from Android Market -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- Required to keep CPU alive while downloading files (NOT to keep screen awake) -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <!-- Required to poll the state of the network connection and respond to changes -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!-- Required to check whether Wi-Fi is enabled -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <!-- Required to read and write the expansion files on shared storage -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
  • application
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".ExpansionFileDownloaderService" android:label="@string/app_name" />
        <receiver android:name=".ExpansionFileAlarmReceiver" android:label="@string/app_name" />
    </application>
    

Testing APK Expansion Files
  1. Upload the application APK file and Expansion Files using the Google Play Developer Console.
    Uploading APK and Expansion file.
  2. Fill in the necessary application details. Click the Save button. Do not click Publish.
  3. Install the application on your test device and launch the app. Download will start soon.

android.widget.Toast.LENGTH_SHORT | LENGTH_LONG は何秒か?

実際、android.widget.Toast.LENGTH_SHORTとandroid.widget.Toast.LENGTH_LONGは何秒なのか?
  • com.android.server.NotificationManager#scheduleTimeoutLocked()
    private void scheduleTimeoutLocked(ToastRecord r, boolean immediate)
    {
        Message m = Message.obtain(mHandler, MESSAGE_TIMEOUT, r);
        long delay = immediate ? 0 : (r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY);
        mHandler.removeCallbacksAndMessages(r);
        mHandler.sendMessageDelayed(m, delay);
    }
    
  • com.android.server.NotificationManager.LONG_DELAY, SHORT_DELAY
    private static final int LONG_DELAY = 3500; // 3.5 seconds
    private static final int SHORT_DELAY = 2000; // 2 seconds
    
  • 2秒と3.5秒なのかな?


see also: android.widget.Toast

make: *** [out/host/linux-x86/obj/STATIC_LIBRARIES/libMesa_intermediates/src/glsl/linker.o] エラー1

android 最新ソースの make でコケた

こんなエラーメッセージが出て。。。
make: *** [out/host/linux-x86/obj/STATIC_LIBRARIES/libMesa_intermediates/src/glsl/linker.o] エラー1

環境
  • ubuntu 11.10 (64bit)
  • あとは全部ここに書いてあるビルド環境

エラーメッセージでググったらすぐ解決した

まあ、備忘録ってことで。(ここを参照のこと)
I'm hitting this too. The bug is the use of the offsetof() macro. Adding a "#include <stddef.h>" to linker.cpp fixes the issue for me.
とのことなので、
$ vi external/mesa3d/src/glsl/linker.cpp 
#include "main/shaderobj.h"

#include <stddef.h>

/**
 * Visitor that determines whether or not a variable is ever written.
 */
class find_assignment_visitor : public ir_hierarchical_visitor {
したら、一応最後まで走りましたよっと。

android org.apache.http.client.HttpClient user-agent

  • Android 2.2 (API Level 8)
  • リクエスト
    final HttpClient client = new DefaultHttpClient();
    final HttpParams params = client.getParams();
    params.setParameter(CoreProtocolPNames.USER_AGENT, "android user-agent hoge"); // !
    final HttpGet request = new HttpGet("http://hogehoge.com/");
    try {
    	final HttpResponse response = client.execute(request);
    	// ・・・
    } catch (ClientProtocolException e) {
    	// TODO Auto-generated catch block
    } catch (IOException e) {
    	// TODO Auto-generated catch block
    }
    
    サーバ側ログ
    192.168.100.101 - - [01/Aug/2011:01:23:45 +0900] "GET / HTTP/1.1" 200 175 "-" "android user-agent hoge"
    

WebView の Scrollbar 部分の余白

WebView の Scrollbar が表示される部分の余白みたいなのが気になって。
WebView#setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET)の場合
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mWebView = new WebView(this);
        mWebView.loadUrl(URL);
        mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET); // !
        mWebView.setWebViewClient(new WebViewClient());
        setContentView(mWebView);
    }
Scrollbarを常時表示させているなら違和感ないのかな。

WebView#setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY)にしてみる
   mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
あーこれだわ。標準でインストールされているブラウザとかの表示。

WebView#setScrollBarStyle(View.SCROLLBARS_OUTSIDE_INSET)は?
mWebView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_INSET);
ん?SCROLLBARS_INSIDE_INSETとの違いは?

んじゃWebView#setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY)は?
ん?SCROLLBARS_INSIDE_OVERLAYとの違いは?

WebView と WebViewClient を使って HTML のソースを LogCat に流す

public class HogeActivity extends Activity {
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final WebView webView = new WebView(this);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.setWebViewClient(new HogeWebViewClinet());
        webView.addJavascriptInterface(new WebViewLogger(), "webViewLogger");
        webView.loadUrl("http://www.yahoo.co.jp/");
        setContentView(webView);
    }
    
    class HogeWebViewClinet extends WebViewClient {
        @Override public void onPageFinished(WebView view, String url) {
            view.loadUrl("javascript:window.webViewLogger.log(document.documentElement.outerHTML);");
        }
    }
    
    class WebViewLogger {
        public void log(String str) {
            Log.d("webViewLogger", str);
        }
    }
    
}