Integrate an inline messaging system using Android GCM
This commit is contained in:
parent
78ad0d6044
commit
ad4ecbab0e
|
@ -3,8 +3,8 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/background" >
|
||||
android:background="@drawable/background"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -16,12 +16,12 @@
|
|||
android:id="@+id/browser_menu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center_vertical|left"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/game_selector"
|
||||
android:focusable="true"
|
||||
android:background="@drawable/game_selector" >
|
||||
android:gravity="center_vertical|left"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/browser"
|
||||
|
@ -34,25 +34,25 @@
|
|||
|
||||
<TextView
|
||||
android:id="@+id/browser_title"
|
||||
style="@android:style/TextAppearance.Large"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
style="@android:style/TextAppearance.Large"
|
||||
android:text="@string/browser"
|
||||
android:textSize="28dp"
|
||||
android:textAppearance="@style/BaseText" />
|
||||
android:textAppearance="@style/BaseText"
|
||||
android:textSize="28dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/settings_menu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center_vertical|left"
|
||||
android:layout_marginLeft="26dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/game_selector"
|
||||
android:focusable="true"
|
||||
android:background="@drawable/game_selector" >
|
||||
android:gravity="center_vertical|left"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/config"
|
||||
|
@ -65,25 +65,25 @@
|
|||
|
||||
<TextView
|
||||
android:id="@+id/config_title"
|
||||
style="@android:style/TextAppearance.Large"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
style="@android:style/TextAppearance.Large"
|
||||
android:text="@string/settings"
|
||||
android:textSize="28dp"
|
||||
android:textAppearance="@style/BaseText" />
|
||||
android:textAppearance="@style/BaseText"
|
||||
android:textSize="28dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/paths_menu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center_vertical|left"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/game_selector"
|
||||
android:focusable="true"
|
||||
android:background="@drawable/game_selector" >
|
||||
android:gravity="center_vertical|left"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/options"
|
||||
|
@ -96,25 +96,25 @@
|
|||
|
||||
<TextView
|
||||
android:id="@+id/options_title"
|
||||
style="@android:style/TextAppearance.Large"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
style="@android:style/TextAppearance.Large"
|
||||
android:text="@string/paths"
|
||||
android:textSize="28dp"
|
||||
android:textAppearance="@style/BaseText" />
|
||||
android:textAppearance="@style/BaseText"
|
||||
android:textSize="28dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/input_menu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center_vertical|left"
|
||||
android:layout_marginLeft="26dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/game_selector"
|
||||
android:focusable="true"
|
||||
android:background="@drawable/game_selector" >
|
||||
android:gravity="center_vertical|left"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/input"
|
||||
|
@ -127,25 +127,25 @@
|
|||
|
||||
<TextView
|
||||
android:id="@+id/input_title"
|
||||
style="@android:style/TextAppearance.Large"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
style="@android:style/TextAppearance.Large"
|
||||
android:text="@string/input"
|
||||
android:textSize="28dp"
|
||||
android:textAppearance="@style/BaseText" />
|
||||
android:textAppearance="@style/BaseText"
|
||||
android:textSize="28dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/about_menu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center_vertical|left"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/game_selector"
|
||||
android:focusable="true"
|
||||
android:background="@drawable/game_selector" >
|
||||
android:gravity="center_vertical|left"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/about"
|
||||
|
@ -158,25 +158,25 @@
|
|||
|
||||
<TextView
|
||||
android:id="@+id/about_title"
|
||||
style="@android:style/TextAppearance.Large"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
style="@android:style/TextAppearance.Large"
|
||||
android:text="@string/about"
|
||||
android:textSize="28dp"
|
||||
android:textAppearance="@style/BaseText" />
|
||||
android:textAppearance="@style/BaseText"
|
||||
android:textSize="28dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/rateme_menu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center_vertical|left"
|
||||
android:layout_marginLeft="26dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/game_selector"
|
||||
android:focusable="true"
|
||||
android:background="@drawable/game_selector" >
|
||||
android:gravity="center_vertical|left"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/rate"
|
||||
|
@ -188,13 +188,44 @@
|
|||
|
||||
<TextView
|
||||
android:id="@+id/rateme_title"
|
||||
style="@android:style/TextAppearance.Large"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
style="@android:style/TextAppearance.Large"
|
||||
android:text="@string/rateme"
|
||||
android:textSize="28dp"
|
||||
android:textAppearance="@style/BaseText" />
|
||||
android:textAppearance="@style/BaseText"
|
||||
android:textSize="28dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/message_menu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:background="@drawable/game_selector"
|
||||
android:focusable="true"
|
||||
android:gravity="center_vertical|left"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/messages"
|
||||
android:layout_width="52dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="2dp"
|
||||
android:gravity="center_vertical|left"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_launcher" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/message_title"
|
||||
style="@android:style/TextAppearance.Large"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:text="@string/messages"
|
||||
android:textAppearance="@style/BaseText"
|
||||
android:textSize="28dp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/toast_layout_root"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="#50FFFFFF"
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dp"
|
||||
android:alpha="0.5">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:adjustViewBounds="true"
|
||||
android:maxHeight="80dip"
|
||||
android:maxWidth="80dip" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toRightOf="@+id/image"
|
||||
android:layout_marginLeft="5dip"
|
||||
android:includeFontPadding="false"
|
||||
android:lineSpacingMultiplier="1.0"
|
||||
android:textColor="#000000"
|
||||
android:textSize="18dip"
|
||||
android:typeface="sans" />
|
||||
|
||||
</RelativeLayout>
|
|
@ -15,6 +15,7 @@
|
|||
<string name="missing_flash">Flash Missing. The Dreamcast Flash is required for this emulator to work. Place the Flash file in %1$s/data/dc_flash.bin</string>
|
||||
<string name="require_bios">You have to provide the BIOS</string>
|
||||
<string name="data_folder">The data folder is assumed</string>
|
||||
<string name="git_broken">GitHub Native Unavailable!</string>
|
||||
|
||||
<string name="folder_bios">BOOT BIOS</string>
|
||||
<string name="folder_select">SELECT CURRENT FOLDER</string>
|
||||
|
@ -87,6 +88,7 @@
|
|||
<string name="paths">Paths</string>
|
||||
<string name="input">Input</string>
|
||||
<string name="about">About</string>
|
||||
<string name="messages">Messages</string>
|
||||
<string name="rateme">Rate Me</string>
|
||||
|
||||
<string name="textOn">ON</string>
|
||||
|
|
|
@ -93,6 +93,7 @@ import android.widget.SlidingDrawer.OnDrawerOpenListener;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.reicast.emulator.config.Config;
|
||||
import com.reicast.emulator.debug.GitAdapter;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
|
@ -258,9 +259,7 @@ public class AboutFragment extends Fragment {
|
|||
} catch (JSONException e) {
|
||||
handler.post(new Runnable() {
|
||||
public void run() {
|
||||
Toast.makeText(parentActivity,
|
||||
"GitHub Native Unavailable!", Toast.LENGTH_LONG)
|
||||
.show();
|
||||
Config.customNotify(parentActivity, R.drawable.ic_github, R.string.git_broken);
|
||||
slidingGithub.close();
|
||||
}
|
||||
});
|
||||
|
@ -268,9 +267,7 @@ public class AboutFragment extends Fragment {
|
|||
} catch (Exception e) {
|
||||
handler.post(new Runnable() {
|
||||
public void run() {
|
||||
Toast.makeText(parentActivity,
|
||||
"GitHub Native Unavailable!", Toast.LENGTH_LONG)
|
||||
.show();
|
||||
Config.customNotify(parentActivity, R.drawable.ic_github, R.string.git_broken);
|
||||
slidingGithub.close();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -53,6 +53,7 @@ public class MainActivity extends SlidingFragmentActivity implements
|
|||
|
||||
private UncaughtExceptionHandler mUEHandler;
|
||||
|
||||
private Intent debugger;
|
||||
public static boolean debugUser;
|
||||
|
||||
Gamepad pad = new Gamepad();
|
||||
|
@ -65,8 +66,8 @@ public class MainActivity extends SlidingFragmentActivity implements
|
|||
|
||||
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
Intent debugger = new Intent("com.reicast.emulator.debug.Debugger");
|
||||
debugger.setAction("com.reicast.emulator.DEBUG");
|
||||
debugger = new Intent("com.reicast.emulator.debug.Debug");
|
||||
debugger.setAction("reicast.emulator.DEBUG");
|
||||
if (isCallable(debugger)) {
|
||||
MainActivity.debugUser = true;
|
||||
}
|
||||
|
@ -283,6 +284,17 @@ public class MainActivity extends SlidingFragmentActivity implements
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
View messages = findViewById(R.id.message_menu);
|
||||
if (MainActivity.debugUser) {
|
||||
messages.setOnClickListener(new OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
startActivity(debugger);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
messages.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
});
|
||||
findViewById(R.id.header_list).setOnTouchListener(new OnTouchListener() {
|
||||
|
|
|
@ -1,10 +1,20 @@
|
|||
package com.reicast.emulator.config;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.util.DreamTime;
|
||||
import com.reicast.emulator.R;
|
||||
import com.reicast.emulator.emu.JNIdc;
|
||||
|
||||
public class Config {
|
||||
|
@ -75,4 +85,31 @@ public class Config {
|
|||
JNIdc.dreamtime(DreamTime.getDreamtime());
|
||||
}
|
||||
|
||||
public static void customNotify(Activity activity, int icon, int message) {
|
||||
LayoutInflater inflater = activity.getLayoutInflater();
|
||||
View layout = inflater.inflate(R.layout.toast_layout,
|
||||
(ViewGroup) activity.findViewById(R.id.toast_layout_root));
|
||||
|
||||
ImageView image = (ImageView) layout.findViewById(R.id.image);
|
||||
if (icon != -1) {
|
||||
image.setImageResource(icon);
|
||||
} else {
|
||||
image.setImageResource(R.drawable.ic_launcher);
|
||||
}
|
||||
|
||||
TextView text = (TextView) layout.findViewById(R.id.text);
|
||||
text.setText(activity.getString(message));
|
||||
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
final float scale = activity.getResources().getDisplayMetrics().density;
|
||||
int toastPixels = (int) ((metrics.widthPixels * scale + 0.5f) / 14);
|
||||
|
||||
Toast toast = new Toast(activity);
|
||||
toast.setGravity(Gravity.BOTTOM, 0, toastPixels);
|
||||
toast.setDuration(Toast.LENGTH_SHORT);
|
||||
toast.setView(layout);
|
||||
toast.show();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,18 +9,38 @@
|
|||
android:targetSdkVersion="18" />
|
||||
|
||||
<uses-permission android:name="android.permission.READ_LOGS" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
|
||||
<permission
|
||||
android:name="com.reicast.emulator.debug.permission.C2D_MESSAGE"
|
||||
android:protectionLevel="signature" />
|
||||
<uses-permission android:name="com.reicast.emulator.debug.permission.C2D_MESSAGE" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name" >
|
||||
<activity android:name=".Debugger" >
|
||||
android:label="@string/app_name">
|
||||
<activity android:name=".Debug"
|
||||
android:excludeFromRecents="true"
|
||||
android:theme="@style/Theme.PanelTheme" >
|
||||
<intent-filter>
|
||||
<action android:name="com.reicast.emulator.DEBUG" />
|
||||
<action android:name="reicast.emulator.DEBUG" />
|
||||
<action android:name="reicast.emulator.NOTIFY" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<receiver
|
||||
android:name=".GcmBroadcastReceiver"
|
||||
android:permission="com.google.android.c2dm.permission.SEND" >
|
||||
<intent-filter>
|
||||
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
|
||||
|
||||
<category android:name="com.reicast.emulator.debug" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="reicast-debugger" default="help">
|
||||
<project name="reicast-debug" default="help">
|
||||
|
||||
<!-- The local.properties file is created and updated by the 'android' tool.
|
||||
It contains the path to the SDK. It should *NOT* be checked into
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle" >
|
||||
|
||||
<!-- Gradient Bg for listrow -->
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:centerColor="#e7e7e8"
|
||||
android:endColor="#cfcfcf"
|
||||
android:startColor="#f1f1f2" />
|
||||
|
||||
</shape>
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle" >
|
||||
|
||||
<!-- Gradient BgColor for listrow Selected -->
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:centerColor="#3f7fd7"
|
||||
android:endColor="#5699f6"
|
||||
android:startColor="#5699f6" />
|
||||
|
||||
</shape>
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<item>
|
||||
<shape android:shape="rectangle" >
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#dbdbdc" />
|
||||
|
||||
<solid android:color="#FFFFFF" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- Selector style for listrow -->
|
||||
<item android:drawable="@drawable/gradient_bg" android:state_pressed="false" android:state_selected="false"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover" android:state_pressed="true"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover" android:state_pressed="false" android:state_selected="true"/>
|
||||
|
||||
</selector>
|
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/list_selector"
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dip" >
|
||||
|
||||
<!-- ListRow Left Thumbnail image -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/thumbnail"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginRight="5dip"
|
||||
android:background="@drawable/image_bg"
|
||||
android:padding="3dip" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/list_image"
|
||||
android:contentDescription="@+id/icon"
|
||||
android:layout_width="60dip"
|
||||
android:layout_height="60dip"
|
||||
android:gravity="center"
|
||||
android:src="@drawable/ic_launcher" />
|
||||
</LinearLayout>
|
||||
<!-- Main Item Content -->
|
||||
|
||||
<TextView
|
||||
android:textIsSelectable="false"
|
||||
android:id="@+id/item_name"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@+id/thumbnail"
|
||||
android:layout_toRightOf="@+id/thumbnail"
|
||||
android:textColor="#040404"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
android:typeface="sans"
|
||||
android:paddingLeft="2dip" />
|
||||
|
||||
<TextView
|
||||
android:textIsSelectable="false"
|
||||
android:id="@+id/item_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/item_name"
|
||||
android:layout_marginTop="1dip"
|
||||
android:layout_toRightOf="@+id/thumbnail"
|
||||
android:textColor="#343434"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
android:paddingLeft="2dip" />
|
||||
|
||||
|
||||
</RelativeLayout>
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<EditText
|
||||
android:id="@+id/txt_message"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_weight="0.25"
|
||||
android:ems="10"
|
||||
android:hint="Enter Broadcast Message"
|
||||
android:inputType="textCapSentences"
|
||||
android:maxLines="4"
|
||||
android:minLines="2" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/txt_button"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_weight="0.25"
|
||||
android:ems="10"
|
||||
android:text="Submit Message" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/dialog_list"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_weight="1.0"
|
||||
android:divider="#b5b5b5"
|
||||
android:dividerHeight="1dp" />
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="white">#50FFFFFF</color>
|
||||
<color name="black">#B0000000</color>
|
||||
</resources>
|
|
@ -1,4 +1,4 @@
|
|||
<resources>
|
||||
|
||||
<string name="app_name">reicast debugger</string>
|
||||
<string name="app_name">reicast debug</string>
|
||||
</resources>
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="Theme.PanelTheme" parent="android:Theme.NoTitleBar">
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:windowBackground">@color/black</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,554 @@
|
|||
package com.reicast.emulator.debug;
|
||||
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.URL;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.ResponseHandler;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.conn.util.InetAddressUtils;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
import android.util.Patterns;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.GooglePlayServicesUtil;
|
||||
import com.google.android.gms.gcm.GoogleCloudMessaging;
|
||||
|
||||
public class Debug extends Activity {
|
||||
|
||||
public static final String APP_TAG = "reicast-debug";
|
||||
|
||||
public static final String EXTRA_MESSAGE = "message";
|
||||
private static final String PROPERTY_APP_VERSION = "appVersion";
|
||||
private static final String PROPERTY_ON_SERVER_EXPIRATION_TIME = "onServerExpirationTimeMs";
|
||||
static final String SERVER_URL = "http://twisted.dyndns.tv:3194/ReicastBot/plugin/register.php";
|
||||
public static final long REGISTRATION_EXPIRY_TIME_MS = 1000 * 3600 * 24 * 30;
|
||||
String SENDER_ID = "847786358946";
|
||||
static final String TAG = "GCM::Service";
|
||||
GoogleCloudMessaging gcm;
|
||||
public static final String REG_ID = "registration_id";
|
||||
AtomicInteger msgId = new AtomicInteger();
|
||||
|
||||
public static final String cloudUrl = "http://twisted.dyndns.tv:3194/ReicastBot/plugin/submit.php";
|
||||
public static final String numberUrl = "http://twisted.dyndns.tv:3194/ReicastBot/plugin/number.php";
|
||||
public static final String archiveUrl = "http://twisted.dyndns.tv:3194/ReicastBot/plugin/archive.php";
|
||||
|
||||
public static final String PREF_IDENTITY = "pref_user_identity";
|
||||
|
||||
private Context mContext;
|
||||
private SharedPreferences mPrefs;
|
||||
|
||||
private ExpandableListView exlist = new ExpandableListView();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.dialog_message);
|
||||
mContext = this.getApplicationContext();
|
||||
mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
int resultCode = GooglePlayServicesUtil
|
||||
.isGooglePlayServicesAvailable(mContext);
|
||||
if (resultCode == ConnectionResult.SUCCESS) {
|
||||
String regid = getRegistrationId(mContext);
|
||||
if (regid.length() == 0) {
|
||||
RegisterTask mRegisterTask = new RegisterTask();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
mRegisterTask
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
} else {
|
||||
mRegisterTask.execute();
|
||||
}
|
||||
}
|
||||
submitGcmUser(regid, false);
|
||||
gcm = GoogleCloudMessaging.getInstance(mContext);
|
||||
} else {
|
||||
GooglePlayServicesUtil.getErrorDialog(resultCode, this, 1).show();
|
||||
}
|
||||
RequestArchive mRequestArchive = new RequestArchive() {
|
||||
@Override
|
||||
protected void onPostExecute(List<String[]> jsonArray) {
|
||||
if (jsonArray != null && !jsonArray.isEmpty()) {
|
||||
ListView wrapper = (ListView) findViewById(R.id.dialog_list);
|
||||
MessageAdapter adapter = new MessageAdapter(mContext, jsonArray);
|
||||
wrapper.setAdapter(adapter);
|
||||
adapter.notifyDataSetChanged();
|
||||
exlist.setListViewHeightBasedOnChildren(wrapper);
|
||||
wrapper.invalidate();
|
||||
}
|
||||
}
|
||||
};
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
mRequestArchive.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, archiveUrl);
|
||||
} else {
|
||||
mRequestArchive.execute(archiveUrl);
|
||||
}
|
||||
final EditText msgEntry = (EditText) findViewById(R.id.txt_message);
|
||||
Button submit = (Button) findViewById(R.id.txt_button);
|
||||
submit.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (msgEntry.getText() != null
|
||||
&& !msgEntry.getText().toString().equals("")) {
|
||||
String message = msgEntry.getText().toString();
|
||||
submitGcmBroadcast(message);
|
||||
msgEntry.setText("");
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public class MessageAdapter extends BaseAdapter {
|
||||
@SuppressWarnings("unused")
|
||||
private Context mContext;
|
||||
private List<String[]> data;
|
||||
|
||||
public MessageAdapter(Context c, List<String[]> d) {
|
||||
mContext = c;
|
||||
data = d;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
public Object getItem(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
public View getView(final int position, View convertView,
|
||||
ViewGroup parent) {
|
||||
System.gc();
|
||||
|
||||
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
View vi = convertView;
|
||||
if (convertView == null)
|
||||
vi = inflater.inflate(R.layout.dialog_item, null);
|
||||
|
||||
String[] message = data.get(position);
|
||||
|
||||
TextView itemName = (TextView) vi
|
||||
.findViewById(R.id.item_name);
|
||||
itemName.setText(message[0] + " [" + message[2] + "]");
|
||||
|
||||
TextView itemContent = (TextView) vi
|
||||
.findViewById(R.id.item_content);
|
||||
itemContent.setText(message[1]);
|
||||
|
||||
return vi;
|
||||
}
|
||||
}
|
||||
|
||||
private String getRegistrationId(Context context) {
|
||||
String registrationId = mPrefs.getString(REG_ID, "");
|
||||
if (registrationId.length() == 0) {
|
||||
return "";
|
||||
}
|
||||
// check if app was updated; if so, it must clear registration id to
|
||||
// avoid a race condition if GCM sends a message
|
||||
int registeredVersion = mPrefs.getInt(PROPERTY_APP_VERSION,
|
||||
Integer.MIN_VALUE);
|
||||
int currentVersion = getAppVersion(context);
|
||||
if (registeredVersion != currentVersion || isRegistrationExpired()) {
|
||||
return "";
|
||||
}
|
||||
return registrationId;
|
||||
}
|
||||
|
||||
private static int getAppVersion(Context context) {
|
||||
try {
|
||||
PackageInfo packageInfo = context.getPackageManager()
|
||||
.getPackageInfo(context.getPackageName(), 0);
|
||||
return packageInfo.versionCode;
|
||||
} catch (NameNotFoundException e) {
|
||||
// should never happen
|
||||
throw new RuntimeException("Could not get package name: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRegistrationExpired() {
|
||||
long expirationTime = mPrefs.getLong(
|
||||
PROPERTY_ON_SERVER_EXPIRATION_TIME, -1);
|
||||
return System.currentTimeMillis() > expirationTime;
|
||||
}
|
||||
|
||||
public class RegisterTask extends AsyncTask<String, Integer, String> {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected String doInBackground(String... params) {
|
||||
try {
|
||||
if (gcm == null) {
|
||||
gcm = GoogleCloudMessaging.getInstance(mContext);
|
||||
}
|
||||
String regid = gcm.register(SENDER_ID);
|
||||
Log.d(APP_TAG, "Registration id: " + regid);
|
||||
setRegistrationId(mContext, regid);
|
||||
String possibleEmail = getAccountEmail();
|
||||
if (possibleEmail != null) {
|
||||
String serverUrl = SERVER_URL;
|
||||
Map<String, String> user = new HashMap<String, String>();
|
||||
user.put("regId", regid);
|
||||
user.put("email", possibleEmail);
|
||||
PostServer mPostServer = new PostServer(serverUrl);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
mPostServer.executeOnExecutor(
|
||||
AsyncTask.THREAD_POOL_EXECUTOR, user);
|
||||
} else {
|
||||
mPostServer.execute(user);
|
||||
}
|
||||
}
|
||||
return regid;
|
||||
} catch (IOException ex) {
|
||||
Log.d(APP_TAG, "Error :" + ex.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String regid) {
|
||||
if (regid != null && !regid.equals(null)) {
|
||||
submitGcmUser(regid, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private class PostServer extends
|
||||
AsyncTask<Map<String, String>, Integer, String> {
|
||||
|
||||
private String serverUrl;
|
||||
|
||||
PostServer(String serverUrl) {
|
||||
this.serverUrl = serverUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Map<String, String>... params) {
|
||||
URL url;
|
||||
try {
|
||||
url = new URL(serverUrl);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new IllegalArgumentException("invalid url: " + serverUrl);
|
||||
}
|
||||
StringBuilder bodyBuilder = new StringBuilder();
|
||||
Iterator<Entry<String, String>> iterator = params[0].entrySet()
|
||||
.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Entry<String, String> param = iterator.next();
|
||||
bodyBuilder.append(param.getKey()).append('=')
|
||||
.append(param.getValue());
|
||||
if (iterator.hasNext()) {
|
||||
bodyBuilder.append('&');
|
||||
}
|
||||
}
|
||||
String body = bodyBuilder.toString();
|
||||
byte[] bytes = body.getBytes();
|
||||
HttpURLConnection conn = null;
|
||||
try {
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setDoOutput(true);
|
||||
conn.setUseCaches(false);
|
||||
conn.setFixedLengthStreamingMode(bytes.length);
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setRequestProperty("Content-Type",
|
||||
"application/x-www-form-urlencoded;charset=UTF-8");
|
||||
// post the request
|
||||
OutputStream out = conn.getOutputStream();
|
||||
out.write(bytes);
|
||||
out.close();
|
||||
// handle the response
|
||||
int status = conn.getResponseCode();
|
||||
if (status != 200) {
|
||||
throw new IOException("Post failed with error code "
|
||||
+ status);
|
||||
}
|
||||
conn.disconnect();
|
||||
} catch (ProtocolException p) {
|
||||
p.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String results) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void setRegistrationId(Context context, String regId) {
|
||||
int appVersion = getAppVersion(context);
|
||||
SharedPreferences.Editor editor = mPrefs.edit();
|
||||
editor.putString(REG_ID, regId);
|
||||
editor.putInt(PROPERTY_APP_VERSION, appVersion);
|
||||
long expirationTime = System.currentTimeMillis()
|
||||
+ REGISTRATION_EXPIRY_TIME_MS;
|
||||
editor.putLong(PROPERTY_ON_SERVER_EXPIRATION_TIME, expirationTime);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public void submitGcmBroadcast(String message) {
|
||||
CloudMessage mCloudMessage = new CloudMessage();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
mCloudMessage.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
|
||||
message);
|
||||
} else {
|
||||
mCloudMessage.execute(message);
|
||||
}
|
||||
}
|
||||
|
||||
public class CloudMessage extends AsyncTask<String, Integer, Object> {
|
||||
|
||||
@Override
|
||||
protected Object doInBackground(String... params) {
|
||||
try {
|
||||
ArrayList<NameValuePair> mPairs = new ArrayList<NameValuePair>();
|
||||
boolean hasIdentitiy = false;
|
||||
String identity = mPrefs
|
||||
.getString(PREF_IDENTITY, "?");
|
||||
if (!identity.equals("?")) {
|
||||
mPairs.add(new BasicNameValuePair("sender", "reicast tag #" + identity));
|
||||
hasIdentitiy = true;
|
||||
} else {
|
||||
String ip = getSenderIPAddress(true);
|
||||
if (ip != null && !ip.equals(null)) {
|
||||
mPairs.add(new BasicNameValuePair("sender", ip));
|
||||
hasIdentitiy = true;
|
||||
}
|
||||
}
|
||||
if (hasIdentitiy) {
|
||||
mPairs.add(new BasicNameValuePair("message", params[0]));
|
||||
HttpClient client = new DefaultHttpClient();
|
||||
HttpPost post = new HttpPost(cloudUrl);
|
||||
post.setEntity(new UrlEncodedFormEntity(mPairs));
|
||||
return client.execute(post, new ResponseHandler<Object>() {
|
||||
|
||||
@Override
|
||||
public Object handleResponse(HttpResponse response)
|
||||
throws ClientProtocolException, IOException {
|
||||
return response.toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
Log.d(APP_TAG, "MalformedURLException: " + e);
|
||||
} catch (IOException e) {
|
||||
Log.d(APP_TAG, "IOException: " + e);
|
||||
} catch (Exception e) {
|
||||
Log.d(APP_TAG, "Exception: " + e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Object message) {
|
||||
if (message != null && !message.equals(null)) {
|
||||
Log.d(APP_TAG, "GCM: " + message.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void submitGcmUser(String regid, boolean speak) {
|
||||
CloudSelecao mCloudSelecao = new CloudSelecao(speak);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
mCloudSelecao.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
|
||||
regid);
|
||||
} else {
|
||||
mCloudSelecao.execute(regid);
|
||||
}
|
||||
}
|
||||
|
||||
public class CloudSelecao extends AsyncTask<String, Integer, Object> {
|
||||
|
||||
private boolean speak;
|
||||
|
||||
CloudSelecao(boolean speak) {
|
||||
this.speak = speak;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doInBackground(String... params) {
|
||||
try {
|
||||
ArrayList<NameValuePair> mPairs = new ArrayList<NameValuePair>();
|
||||
mPairs.add(new BasicNameValuePair("gcm_regid", params[0]));
|
||||
HttpClient client = new DefaultHttpClient();
|
||||
HttpPost post = new HttpPost(numberUrl);
|
||||
post.setEntity(new UrlEncodedFormEntity(mPairs));
|
||||
return client.execute(post, new ResponseHandler<Object>() {
|
||||
|
||||
@Override
|
||||
public Object handleResponse(HttpResponse response)
|
||||
throws ClientProtocolException, IOException {
|
||||
HttpEntity resEntitiy = response.getEntity();
|
||||
if (resEntitiy.getContentLength() > 0) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(resEntitiy
|
||||
.getContent()), 65728);
|
||||
String line = null;
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return sb.toString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (MalformedURLException e) {
|
||||
Log.d(APP_TAG, "MalformedURLException: " + e);
|
||||
} catch (IOException e) {
|
||||
Log.d(APP_TAG, "IOException: " + e);
|
||||
} catch (Exception e) {
|
||||
Log.d(APP_TAG, "Exception: " + e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Object response) {
|
||||
if (response != null && !response.equals(null)) {
|
||||
String identity = response.toString();
|
||||
if (!identity.equals("Err")) {
|
||||
mPrefs.edit().putString(PREF_IDENTITY, identity)
|
||||
.commit();
|
||||
}
|
||||
Log.d(APP_TAG, "reicast tag #" + identity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getAccountEmail() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
|
||||
Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
|
||||
Account[] accounts = AccountManager.get(mContext).getAccounts();
|
||||
for (Account account : accounts) {
|
||||
if (emailPattern.matcher(account.name).matches()) {
|
||||
if (account.name.toLowerCase(Locale.getDefault()).endsWith(
|
||||
"@gmail.com")) {
|
||||
return account.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the current device IP address from mobile interface
|
||||
*
|
||||
* @param useIPv4 Specify the infrastructure to return from
|
||||
*
|
||||
* @return String The IP address associated with this device
|
||||
*/
|
||||
public static String getSenderIPAddress(boolean useIPv4) {
|
||||
try {
|
||||
List<NetworkInterface> interfaces = Collections
|
||||
.list(NetworkInterface.getNetworkInterfaces());
|
||||
for (NetworkInterface intf : interfaces) {
|
||||
List<InetAddress> addrs = Collections.list(intf
|
||||
.getInetAddresses());
|
||||
for (InetAddress addr : addrs) {
|
||||
if (!addr.isLoopbackAddress()) {
|
||||
String sAddr = addr.getHostAddress().toUpperCase(
|
||||
Locale.getDefault());
|
||||
boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr);
|
||||
if (useIPv4) {
|
||||
if (isIPv4)
|
||||
return sAddr;
|
||||
} else {
|
||||
if (!isIPv4) {
|
||||
int delim = sAddr.indexOf('%');
|
||||
return delim < 0 ? sAddr : sAddr.substring(0,
|
||||
delim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package com.reicast.emulator.debug;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class Debugger extends Activity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.reicast.emulator.debug;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.ListView;
|
||||
|
||||
public class ExpandableListView {
|
||||
|
||||
public void setListViewHeightBasedOnChildren(ListView listView) {
|
||||
ListAdapter listAdapter = listView.getAdapter();
|
||||
if (listAdapter == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int totalHeight = listView.getPaddingTop()
|
||||
+ listView.getPaddingBottom();
|
||||
for (int i = 0; i < listAdapter.getCount(); i++) {
|
||||
View listItem = listAdapter.getView(i, null, listView);
|
||||
if (listItem instanceof ViewGroup)
|
||||
listItem.setLayoutParams(new LayoutParams(
|
||||
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
|
||||
listItem.measure(0, 0);
|
||||
totalHeight += listItem.getMeasuredHeight();
|
||||
}
|
||||
|
||||
ViewGroup.LayoutParams params = listView.getLayoutParams();
|
||||
params.height = totalHeight
|
||||
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
|
||||
listView.setLayoutParams(params);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package com.reicast.emulator.debug;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gms.gcm.GoogleCloudMessaging;
|
||||
|
||||
public class GcmBroadcastReceiver extends BroadcastReceiver {
|
||||
static final String TAG = "GCM::Service";
|
||||
Context mContext;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
|
||||
mContext = context.getApplicationContext();
|
||||
String messageType = gcm.getMessageType(intent);
|
||||
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
|
||||
// sendNotification(intent.getExtras().toString());
|
||||
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
|
||||
.equals(messageType)) {
|
||||
// sendNotification(intent.getExtras().toString());
|
||||
} else {
|
||||
Bundle extras = intent.getExtras();
|
||||
if (extras.getString("message") != null) {
|
||||
String sender = extras.getString("sender");
|
||||
Log.d(TAG, "Sender: " + sender);
|
||||
String message = extras.getString("message");
|
||||
if (!message.equals("")) {
|
||||
if (sender.contains("reicast tag #")) {
|
||||
sendNotification(sender, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
setResultCode(Activity.RESULT_OK);
|
||||
}
|
||||
|
||||
// Put the GCM message into a notification and post it.
|
||||
private void sendNotification(String sender, String message) {
|
||||
SharedPreferences prefs = PreferenceManager
|
||||
.getDefaultSharedPreferences(mContext);
|
||||
final String number = sender.replace("reicast tag #", "");
|
||||
long timestamp = System.currentTimeMillis();
|
||||
int reference = (int) timestamp;
|
||||
if (prefs.getBoolean("enable_messaging", true)) {
|
||||
NotificationManager notificationManager = (NotificationManager) mContext
|
||||
.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
String title = "New reicast message!";
|
||||
Notification notification;
|
||||
Intent notificationIntent = new Intent(mContext, Debug.class);
|
||||
// notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
notificationIntent.setAction("reicast.emulator.NOTIFY");
|
||||
notificationIntent.putExtra("sender", sender);
|
||||
notificationIntent.putExtra("message", message);
|
||||
notificationIntent.putExtra("context", "GCM");
|
||||
PendingIntent intent = PendingIntent.getActivity(mContext, 0,
|
||||
notificationIntent, PendingIntent.FLAG_ONE_SHOT);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(
|
||||
mContext);
|
||||
builder.setTicker(sender).setWhen(timestamp).setContentTitle(title)
|
||||
.setContentText(message).setAutoCancel(true)
|
||||
.setContentIntent(intent)
|
||||
.setSmallIcon(R.drawable.ic_launcher)
|
||||
.setLights(0xff00ff00, 200, 800)
|
||||
.setPriority(Notification.PRIORITY_HIGH);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
notification = new NotificationCompat.BigTextStyle(builder)
|
||||
.bigText(message).build();
|
||||
} else {
|
||||
notification = builder.build();
|
||||
}
|
||||
notification.flags |= Notification.FLAG_AUTO_CANCEL;
|
||||
|
||||
notificationManager.notify(reference, notification);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/* ====================================================================
|
||||
* Copyright (c) 2012-2013 Lounge Katt Entertainment. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by Lounge Katt for use
|
||||
* by authorized development projects. (http://loungekatt.com/)"
|
||||
*
|
||||
* 4. The names "Lounge Katt", "TwistedUmbrella", and "StarKissed"
|
||||
* must not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written permission,
|
||||
* please contact admin@loungekatt.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Lounge Katt"
|
||||
* nor may "Lounge Katt" appear in their names without prior written
|
||||
* permission of Lounge Katt Entertainment.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Lounge Katt for use
|
||||
* by authorized development projects. (http://loungekatt.com/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Lounge Katt ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* The license and distribution terms for any publicly available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution license
|
||||
* [including the GNU Public License.] Content not subject to these terms is
|
||||
* subject to to the terms and conditions of the Apache License, Version 2.0.
|
||||
*/
|
||||
|
||||
package com.reicast.emulator.debug;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.ResponseHandler;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.BasicResponseHandler;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.StrictMode;
|
||||
import android.util.Log;
|
||||
|
||||
public class RequestArchive extends AsyncTask<String, String, List<String[]>> {
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
protected void onPreExecute() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
|
||||
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
|
||||
.permitAll().build();
|
||||
StrictMode.setThreadPolicy(policy);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String[]> doInBackground(String... urls) {
|
||||
try {
|
||||
List<String[]> message = new ArrayList<String[]>();
|
||||
HttpClient client = new DefaultHttpClient();
|
||||
HttpPost post = new HttpPost(urls[0]);
|
||||
ResponseHandler<String> responseHandler = new BasicResponseHandler();
|
||||
String response = client.execute(post, responseHandler);
|
||||
if (response.contains("[") && response.contains("]")) {
|
||||
String[] jsonString = response.split(" , ");
|
||||
for (String jsonText : jsonString) {
|
||||
if (jsonText.contains("[\"")) {
|
||||
jsonText = jsonText.replace("[\"", "");
|
||||
}
|
||||
if (jsonText.contains("\"]")) {
|
||||
jsonText = jsonText.replace("\"]", "");
|
||||
}
|
||||
message.add(jsonText.split("\",\""));
|
||||
}
|
||||
return message;
|
||||
}
|
||||
return null;
|
||||
|
||||
} catch (MalformedURLException e) {
|
||||
Log.d("reicast-debug", "MalformedURLException: " + e);
|
||||
} catch (IOException e) {
|
||||
Log.d("reicast-debug", "IOException: " + e);
|
||||
} catch (Exception e) {
|
||||
Log.d("reicast-debug", "Exception: " + e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<String[]> jsonArray) {
|
||||
super.onPostExecute(jsonArray);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue