漫画雑誌の付録の組み立てできなかったけどガラスバキバキのスマホはなおせた。

バキバキNexus5

バキバキNexus5


今年の7月にNexus5を落としてバキバキに割ってしまったのですが、後継機が出る、という情報があったので直さないで騙し騙し使っていました。いざNexus5xが発表されてみるとおま国価格だし、実機触ってみても大きすぎて片手で操作できないので、諦めて自分で直すことにしました。ちなみにLGに正規で修理に出すと2万超えるし、どこの馬の骨かもよくわかんない業者さんに依頼しても2万超えるそうです。部品代と技術料で妥当なお値段かと思います。
ちなみに私のNexus5の場合、バキバキなのはガラスだけで液晶はノーダメージだったのですが、調べてみると、ガラスと液晶は強力接着されてて、ガラスだけ交換するのはほんとに上手じゃないと無理だそうです。ソースは下記リンク。
SKILIWAH® LG Google Nexus 5修理用 液晶LCD タッチパネル+フルLCD ブラックベゼルフレーム付き (フロントガラスデジタイザ)D820 D821 修理用キット
Apple Store表参道の前で粉々に割れたNexus 5の液晶を格安で修理する方法 – 週刊アスキー

ということで液晶+フレーム付きの修理キットを購入することにしました。

漫画雑誌についてた、すごい好きなキャラクターの「飛び出すトランプカードケース(もちろん紙)」を組み立てられなくて破壊してしまった思い出が蘇ります。レビューでは「慣れてる人なら30分」とありますが、手先の不器用さが半端ではないので、そもそも組み立てられるか不安です。

ジョーカーさん

ジョーカーさん

ジョーカーさんありがとう。私頑張ってみるよ。

週刊アスキーの記事とifixitを見ながら頑張ってバラしました。
Nexus 5 Teardown – iFixit
途中で下記の問題がありました。

  • 裏蓋で強力に接着してる箇所があって外すのにめっちゃ苦労した。(あまりに外れなくて業者に頼まなかったことを後悔しだした)ちなみに、硬すぎてこの段階で修理キットについてた青いヘラみたいな道具を早々に破壊した。
  • みんな言ってるけどバッテリーの接着が強力すぎて全然剥がれない。ドライヤー必須。ドライヤー無かったら死んでた。
  • カメラモジュールがすごく外れにくい(バッテリーほどではない)
  • イヤースピーカーモジュールの爪をうっかり引っ掛けて破壊。あれめっちゃ脆い。仕方ないのでイヤースピーカーは買い直すことにして放置。

無事バラして組み立て終わったあと下記の問題がありました。

  • バイブレータが動かない。
  • バイブを直すのに組み立てなおしたら電源が入らなくなった。

紆余曲折ありましたが、問題が起こるたびに組み立て直して、最終的に無事修理出来ました(イヤースピーカー以外)。やったー!ちなみに所要時間は1時間とちょっと程度でした。

なおった。

なおった。


若干というかかなり尿液晶っぽいんですが、おそらく正規品じゃない(イヤースピーカーの穴が正規のものより細かい)ので仕方ないでしょう。

リスクがあるのでオススメできませんが、手先が器用な方なら十分自前で修理できるレベルだと思いました。
あと、おっかなびっくりやってると一生作業終わんないから、時には思い切り良くバリバリやるのも大事だ、ということも学べました。
電源入らなくなった時にGoogle PlayのNexus5xのページ見てたのは内緒です。

jsoupでAndroidからWebスクレーピングしてTwitterに投稿する。

はてなブログやってたときにTagSoupでAndroidからWebスクレーピングする方法を書いて結構参照されたのですが、今はjsoupというjQueryライクなライブラリがあるそうなので、これを使ってスクレーピングしてみました。ついでにスクレーピングした内容をListViewに突っ込んで、クリックすると内容をTwitterに投稿するようにしました。通信とスクレーピング処理はAsyncTaskクラスを使って別スレッドで実行するようにしています。

サンプルではretrorocket.bizのaタグのテキストとhref属性の値を取り出しました。
あと、注意点としてAndroidで使う外部jarは全部libsディレクトリに入れないと動きません。これに気づかず2時間無駄にしました。

メインアクティビティのクラス

public class JsoupAndTestActivity extends Activity {
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		DownloadTask task = new DownloadTask(JsoupAndTestActivity.this);
		task.execute("start");
	}
}

DownloadTaskはAsyncTaskの拡張です。ここからスクレーピング用の処理を呼び出します。本来ならActivityではなくListViewを渡すべきなんだろうなーと思うのですが、いつもActivityを渡してしまいます。やっぱりだめなのかな…。

DownloadTaskクラス

//<入力値、プログレス用の値、処理完了後の値>
public class DownloadTask extends AsyncTask<String, Integer, Elements> {
	private JsoupAndTestActivity mActivity = null;
	private ProgressDialog dlg;
	private ArrayAdapter<String> adapter;// リスト用のアダプタ
	private ListView list;

	public DownloadTask(JsoupAndTestActivity activity) {
		this.mActivity = activity;
		this.dlg = new ProgressDialog(mActivity);
		this.list = (ListView) mActivity.findViewById(R.id.listView1);
		this.adapter = new ArrayAdapter<String>(
				mActivity.getApplicationContext(),
				android.R.layout.simple_list_item_1);
	}

	/** 前処理(プログレスバー等の用意) **/
	@Override
	protected void onPreExecute() {
		dlg.setTitle("処理中");
		dlg.setMessage("しばらくお待ちください");
		dlg.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		dlg.setCancelable(true);
		dlg.setCancelable(true);
		dlg.setMax(100);
		dlg.setProgress(0);
		dlg.show();
	}

	/** バックグラウンドのメイン処理 **/
	@Override
	protected Elements doInBackground(String... params) {
		//params[0]:start
		Elements aTags = null;
		publishProgress(30);
		try {
			String url = "https://retrorocket.biz/";
			Document doc = Jsoup.connect(url).get();
			aTags = doc.getElementsByTag("a");
		} catch (IOException e) {
			e.printStackTrace();
		}
		publishProgress(70);
		return aTags;
	}

	/** プログレスバーの更新 **/
	@Override
	protected void onProgressUpdate(Integer... values) {
		dlg.setProgress(values[0]);
	}

	/** doInBackground完了後の処理 **/
	@Override
	protected void onPostExecute(Elements result) {
		publishProgress(90);
		if (result == null) {
			Toast.makeText(mActivity, "結果を取得できませんでした", Toast.LENGTH_LONG)
					.show();
		} else {
			//本来ならdoInBackground側で実行すべきかもしれない
			for (Element elem : result) {
				String text = elem.text();
				String href = elem.attr("href");
				adapter.add(text + " " + href);
			}
		}
		
		//リストにセット
		list.setAdapter(adapter);
		//クリックイベントを設定
                list.setOnItemClickListener(new ClickEvent());
		dlg.dismiss();
	}

	@Override
	protected void onCancelled() {
		Toast.makeText(mActivity, "キャンセルされました", Toast.LENGTH_LONG).show();
		dlg.dismiss();
	}

}

タスクに渡すのはString(デバッグするのにString渡しただけなので、別にVoidでもいいです)で、処理中の進行度はInteger、処理完了後の値の型はElementsです。doInBackgroundでスクレーピングを実行しています。progressDialogに渡す値は適当に設定しました。
次はリストをクリックした時にTwitterに投稿するためのクラスです。

ClickEventクラス

public class ClickEvent implements OnItemClickListener {

	//Twitterクラスのインスタンスを作成
	private Twitter twitter = TwitterFactory.getSingleton();

	//adapter:AdapterView・view:選択したView・
	//position:選択された位置・id:IDを示すlong値
	@Override
	public void onItemClick(AdapterView<?> adapter, View view, int position,
			long id) {
		
		//* viewから取得するパターン */
		TextView textview = (TextView) view;
		String text = (String) textview.getText();
		
		//*adapterから取得するパターン*/
		//ListView listView = (ListView) adapter;
		//String text = (String) listView.getItemAtPosition(position);
		
		try {
			twitter4j.Status status = twitter.updateStatus(text);
			//以下statusを使った処理等
			
		} catch (TwitterException e) {
			e.printStackTrace();
		}

	}

}

twitter4j.propertiesはsrcに配置しないと動きませんでした。

実行結果

実行結果

実行結果


リストをタップするとTwitterに投稿されます。